捕获:工具暴露与对话回写 本节摘要:SDK 四步的第二步「捕获」做两件事:一是把 Wiki/CodeGraph 等知识作为工具暴露给模型,让它按需调用(对应代理层 toolize);二是把对话回写给记忆系统沉淀(对应代理层 extract)。本节讲清这两个动作的时机、对象与实现要点。捕获是「记忆持续生长」的保证——没有它,系统只消耗不产出,越用越空。 一、捕获的两个动作 「捕获」实际包含两个不同动作,对应代理层的两个机制: 动作 | 对应代理层 | 时机 工具暴露 | injection 的 toolize | 推理前(告知模型有哪些工具) 对话回写 | extract | 推理后(答复产生后)
本节摘要:SDK 四步的第二步「捕获」做两件事:一是把 Wiki/CodeGraph 等知识作为工具暴露给模型,让它按需调用(对应代理层 toolize);二是把对话回写给记忆系统沉淀(对应代理层 extract)。本节讲清这两个动作的时机、对象与实现要点。捕获是「记忆持续生长」的保证——没有它,系统只消耗不产出,越用越空。
「捕获」实际包含两个不同动作,对应代理层的两个机制:
捕获的两个动作 动作一:工具暴露(toolize 对应) 把知识(Wiki/CodeGraph)作为工具告知模型 模型按需调用 → 拿到知识片段 动作二:对话回写(extract 对应) 把本次对话(用户问+Agent答+工具调用)回写 触发抽取 Pipeline → 沉淀成 L0/L1
| 动作 | 对应代理层 | 时机 |
|---|---|---|
| 工具暴露 | injection 的 toolize | 推理前(告知模型有哪些工具) |
| 对话回写 | extract | 推理后(答复产生后) |
这两个动作时机不同——工具暴露在推理前(让模型知道能用什么),对话回写在推理后(有了对话才回写)。但它们都属于「捕获」范畴:前者捕获「知识能力」,后者捕获「对话内容」。
工具暴露的实现,是把知识引擎的能力(Wiki/CodeGraph)以工具形式告知模型:
# 概念性:工具暴露 # 推理前,获取可用工具并告知模型 tools = await client.list_tools(team_id=..., agent_id=...) # tools 可能含:wiki_search, wiki_read, code_search, code_callers, code_impact # 把 tools 作为「模型可调用的工具」传入推理 reply = await llm.complete( prompt, tools=tools, # 模型看到这些工具,按需调用 tool_handler=handle_tool_call # 你实现的调用处理器 ) async def handle_tool_call(tool_name, params): # 模型决定调用某工具时,你用 SDK 执行 return await client.call_tool(tool_name, params)
工具暴露的关键是「模型自主决定何时调用」——你不主动把知识塞进上下文,而是告诉模型「有这些工具」,模型根据问题判断是否需要、调哪个。这就是第 7 章讲的「按需调用」机制。
关键概念:工具暴露让你不必预判「模型需要什么知识」——你把工具清单给它,它自己决定。这比「人工挑选知识注入」更灵活,尤其当代码库大、无法预知模型会问什么时。
对话回写在推理后执行,把这次对话交给记忆系统沉淀:
# 概念性:对话回写 # 推理完成,有答复后 reply = await llm.complete(...) # 回写(降级包裹,失败不影响已返回的答复) try: await client.capture( conversation={ "user": user_message, "agent": reply, "tool_calls": [...] # 本次发生的工具调用 }, team_id=..., agent_id=..., session_id=..., ) # capture 触发: L0 录制 + 异步抽取 Pipeline except Exception: pass # 降级:回写失败不拖垮对话
回写的内容包括:用户消息、Agent 答复、本次工具调用。这些交给核心服务后,L0 即时录制,异步 Pipeline 抽取 L1/L2/L3。这就是「记忆生长」的 SDK 入口。
| 回写对象 | 去向 |
|---|---|
| 用户消息 + Agent 答复 | L0 录制 |
| 可复用做法 | skill 候选归档 |
| 触发 | 异步抽取(L0→L1→L2/L3) |
捕获的两个动作都在「不阻塞用户」的时机执行:
捕获时机 推理前:工具暴露(同步,需要告知模型才能推理) 推理后:对话回写(异步/降级,不阻塞用户) → 工具暴露必须同步(否则模型不知道能用什么) → 对话回写可异步/降级(用户已拿到答复)
⚠️ 注意:工具暴露与对话回写的降级策略不同。工具暴露失败,可以让推理继续(模型没工具也能答,只是没知识辅助);对话回写失败,绝不能影响答复(用户该拿到的答复不能因回写失败而丢)。这就是为什么对话回写要用 try/except 包裹且失败即 pass——回写是「锦上添花」,不是「必需」。
捕获(回写)与召回(取记忆)合起来,构成记忆的「闭环」:
记忆闭环 召回:从记忆系统取 → 注入 → Agent 用记忆工作 ↓ (产生新对话) 捕获:回写新对话 → 抽取 → 成为新记忆 ↓ (下次召回能取到) 召回:取到更新的记忆 → ... → 召回与捕获循环 = 记忆持续生长 = 复利
这个闭环是第 11 章「Loop 复利」的工程基础——每一轮对话既消耗记忆(召回)又产生记忆(捕获),让系统越用越丰富。SDK 接入必须同时实现召回与捕获,缺任何一个都会打破闭环:只召回不捕获,记忆不生长;只捕获不召回,记忆不发挥作用。
下一节看 SDK 接入最容易踩的三个工程坑——召回污染还原、写入位置切片、sanitize 清洗。