深浅色
Agent 与工具调用(背诵版)
1. Function Calling 完整链路
- 定义工具 schema(name、description、参数的 JSON Schema),随请求发给模型。
- 模型返回 tool_calls(函数名 + 参数 JSON),注意它并没有真的执行。
- 你的代码解析、校验参数、执行真实函数、把结果以 tool 角色消息回填。
- 模型再决定继续调用还是给最终答案。
- 追问:模型会保证参数合法吗?-> 不会,必须服务端校验,还要防注入。
2. ReAct / Plan-and-Execute / Reflexion
- ReAct:思考 -> 行动 -> 观察 循环,边想边做,适合探索型任务。
- Plan-and-Execute:先出完整计划再执行,省 token,但计划错了会连锁失败。
- Reflexion:执行后自我反思并重试,适合可验证的任务(代码、数学)。
- 追问:什么时候不该用 Agent?-> 流程固定的场景直接用工作流(DAG)更稳更便宜。
3. 状态管理与上下文裁剪
- 每轮工具调用都会加消息,上下文很快爆掉。
- 策略:只保留最近 N 轮 + 系统提示、对历史做摘要、截断工具结果、大结果存外部只给引用。
- 追问:直接截断有什么风险?-> 可能丢掉关键约束,系统提示和任务目标必须永不裁剪。
4. MCP
- MCP(Model Context Protocol):统一模型与外部工具 / 数据源的接口,避免每个应用重复写集成。
- 结构:Host(应用)-> Client -> Server(暴露 tools / resources / prompts)。
- 好处:工具实现一次,多个客户端复用。
- 追问:MCP 和 Function Calling 什么关系?-> MCP 是工具的提供方式,底层调用仍走 Function Calling。
5. 多 Agent 编排
- 常见拓扑:主管(supervisor)+ 专家、流水线、辩论 / 评审。
- 关键是有明确的状态机:谁在什么时候把控制权交给谁,避免无限循环。
- 工程建议:先从单 Agent + 多工具起步,确实需要再拆。
- 追问:多 Agent 的主要成本?-> token 翻倍、延迟增加、调试困难。
6. 流式输出与中断
- 流式用 SSE 逐 token 推给前端;工具调用阶段也要推「正在调用 XX 工具」的状态。
- 中断:前端发取消信号 -> 服务端 cancel context -> 停止生成并终止工具执行。
- 追问:用户打断后上下文怎么处理?-> 保留已生成内容并标记中断,让用户能接着追问。
7. 重试与幂等
- 区分可重试(网络抖动、限流)和不可重试(参数错误、权限不足)。
- 重试要退避 + 设上限,避免雪上加霜。
- 有副作用的工具(下单、发消息)必须幂等,用幂等键去重。
- 追问:模型重试同一个工具会重复下单吗?-> 会,所以副作用工具必须带幂等键。
8. 幻觉工具的兜底
- 模型可能返回不存在的工具名或错误参数。
- 兜底:白名单校验(不在列表就返回错误让模型重试)、参数 schema 校验、连续失败 N 次就终止并降级回答。
- 追问:为什么不能把错误直接吞掉?-> 模型看不到错误就无法纠正,会一直错下去。
9. 安全边界
- 代码执行必须在沙箱里(容器 / 微虚拟机),限制网络、文件、CPU 内存和超时。
- 外网访问走白名单代理,文件操作限定目录。
- 追问:最大的风险是什么?-> Prompt Injection:网页或文件里的恶意指令诱导 Agent 调用危险工具。
10. Prompt Injection 防护
- 来源:工具返回内容、用户上传的文档、抓取的网页。
- 防护:把不可信内容明确标注为数据而非指令、最小权限、敏感操作要人工确认、输出侧过滤。
- 追问:能完全防住吗?-> 目前不能,只能降低概率并用权限边界兜底。
11. 长任务的前端交互
- 不要用同步 HTTP 干等 30 秒,容易超时。
- 方案:异步任务 + SSE / WebSocket 推进度,或先返回任务 id 再轮询。
- 前端要展示:当前步骤、已用时、可取消、失败可重试。
- 追问:为什么不用 WebSocket?-> SSE 单向够用且更简单,需要双向指令才用 WS。