Agent 进阶概念补全
一、结构化输出(Structured Output)
Agent 最终要给下游用,输出必须稳定可解析。
三种强制方式
| 方式 | 说明 | 示例 |
|---|---|---|
| JSON Mode | 模型只返回 JSON,不废话 | {"status": "success", "data": [...]} |
| Function Calling | 模型调用一个"伪工具"来返回结构 | 定义 final_answer 工具 |
| Output Parser | 先让模型自由回答,再用代码正则/LLM 提取 | 兜底方案 |
Function Calling 作为结构化输出
json
{
"name": "final_answer",
"description": "任务完成时调用,返回答案",
"parameters": {
"type": "object",
"properties": {
"summary": {"type": "string"},
"items": {"type": "array", "items": {"type": "string"}}
},
"required": ["summary", "items"]
}
}解析失败怎么办
- 先让模型重试,提示"请严格返回 JSON"
- 用代码清洗(去掉 ```json 标记、截断尾部)
- 仍失败 → 降级为自然语言回答 + 记录日志
二、工具 Schema 设计
工具描述 = 模型判断"该不该用这个"的唯一依据。
反例
json
{
"name": "search",
"description": "搜索",
"parameters": {"type": "object"}
}模型不知道搜什么、什么时候搜。
正例
json
{
"name": "search_laws",
"description": "当用户询问中国法律、法规、司法解释时调用,返回相关法条",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "要搜索的法律关键词,例如'劳动合同解除赔偿'"
}
},
"required": ["query"]
}
}设计原则
- 名称即意图:
send_email比tool_3好 - 描述写触发条件:"当…时调用"
- 参数描述给例子:不要只说"查询词",给一个示例
- 枚举优于自由文本:状态字段用
enum: ["pending", "done"] - 一个工具只做一件事:别造万能工具
三、错误处理与重试策略
Agent 跑的是循环,任何一步都可能出错。
常见错误
| 类型 | 例子 | 处理 |
|---|---|---|
| 工具执行失败 | API 超时、文件不存在 | 重试 3 次,换备用工具 |
| 模型返回格式错误 | JSON 缺字段、调用不存在的工具 | 提示重试,不行就降级 |
| 模型陷入循环 | 反复调用同一工具 | 检测重复 → 强制结束 |
| 结果质量差 | 回答偏题、有幻觉 | 自我反思后重生成 |
简单重试模式
python
for attempt in range(3):
try:
result = tool.call(args)
break
except Exception as e:
if attempt == 2:
result = f"工具调用失败:{e}"循环保护
python
if history.count_same_tool_call(tool, args) >= 2:
return "检测到重复调用,请直接给出最终回答。"四、状态管理(State / Checkpoint)
Agent 不是无状态的函数,中途可能崩、可能被人打断。
状态里存什么
{
"conversation_id": "abc123",
"messages": [...],
"tool_results": [...],
"plan": [...],
"variables": {"user_name": "张三"},
"step_count": 5
}Checkpoint 模式
每完成一步就存盘:
用户输入 → 思考 → 调工具 → 存 checkpoint → 调工具 → 存 checkpoint → 输出崩了从最近 checkpoint 恢复,不用从头跑。
状态图(State Graph)
LangGraph 的核心思想:把 Agent 看成"状态机",每个节点读取全局状态、修改全局状态、决定下一个节点。
┌─────────┐
│ 开始 │
└────┬────┘
▼
┌─────────┐
│ 思考 │
└────┬────┘
┌─────┴─────┐
▼ ▼
┌────────┐ ┌────────┐
│ 调工具 │ │ 直接答 │
└───┬────┘ └───┬────┘
│ ▼
└──────► 结束五、Human-in-the-loop
不是每个动作都让 Agent 自己决定,关键节点必须等人。
三种模式
| 模式 | 触发时机 | 例子 |
|---|---|---|
| 预执行审批 | Agent 计划做某操作前 | "我要发邮件给 CEO,确认吗?" |
| 事中干预 | 执行过程中需要信息 | "请提供你的身份证号以继续" |
| 事后修正 | 输出完成后 | "这个回答不对,应改为…" |
实现方式
python
if tool_name in DANGEROUS_TOOLS:
ask_user_for_approval(tool_name, args)
if not approved:
return "用户未批准该操作"六、进阶推理模式
| 模式 | 核心思想 | 适用 |
|---|---|---|
| Tree of Thoughts | 同时想多条路径,评估哪条最好 | 数学、策略、复杂决策 |
| Self-Reflection | 生成后自检"对吗?" | 高精度代码、法律审查 |
| Plan-and-Solve | 先写详细计划,再按步骤执行 | 写报告、长流程 |
| DSPy | 把提示词当成可优化的模块,自动调优 | 需要稳定高产出的场景 |
Self-Reflection 示例
第一步:生成回答
第二步:问自己"这个回答有没有遗漏?有没有事实错误?"
第三步:如果有 → 修正;没有 → 输出七、向量检索进阶
RAG 不是"塞进向量库就完事"。
Embedding 模型选择
| 场景 | 推荐 |
|---|---|
| 通用中文 | BGE-M3、text-embedding-3 |
| 法律/医疗 | 领域微调模型 |
| 多语言 | BGE-M3、E5-mistral |
相似度算法
| 算法 | 特点 |
|---|---|
| Cosine | 方向一致即可,适合文本语义 |
| Dot Product | 对向量长度敏感,适合归一化后 |
| Euclidean | 距离越近越相似 |
重排序(Rerank)
先向量检索召回 20 个候选,再用一个专门的 cross-encoder 模型给它们重新打分,取 Top 5。
混合检索
向量检索:找语义相关的
关键词检索(BM25):找字面匹配的
融合两者结果 → 重排序 → 取 Top-K八、Agent Evals(评估)
评估维度
| 维度 | 问什么 |
|---|---|
| 准确性 | 答案对吗? |
| 完整性 | 有没有漏要点? |
| 幻觉率 | 有没有编造? |
| 工具使用 | 该调的工具调了吗? |
| 效率 | 用了几步?花了多少 Token? |
| 安全性 | 有没有越权/泄露? |
评估方法
| 方法 | 说明 |
|---|---|
| 规则匹配 | 答案里必须出现某些关键词 |
| LLM-as-a-Judge | 用另一个模型打分 |
| RAGAS | RAG 专用评估库 |
| 人工标注 | 最准但最贵 |
回归测试
改提示词后必须跑一批老用例,确认没把以前对的改错。
九、多 Agent 通信模式
| 模式 | 说明 | 例子 |
|---|---|---|
| 主从式 | 一个主控分配任务 | 项目经理 + 程序员 |
| 广播式 | 所有 Agent 都能收到消息 | 群聊讨论 |
| 消息总线 | 通过统一队列通信 | 微服务架构 |
| Handoff | A 把任务交接给 B | 客服转技术专家 |
| 共享记忆 | 所有 Agent 读同一份状态 | 协作写报告 |
关键问题
- 谁有权决定任务结束?
- Agent 之间怎么避免重复工作?
- 冲突结果怎么仲裁?
十、成本与延迟优化
常见手段
| 手段 | 做法 |
|---|---|
| 缓存 | 相同查询直接返缓存结果 |
| 模型路由 | 简单问题用小模型,复杂问题才用大模型 |
| 流式输出 | 边生成边展示,降低等待感 |
| Prompt 压缩 | 去掉冗余上下文 |
| 限制循环步数 | max_steps 设上限 |
Token 监控
每次调用记录:
input_tokens / output_tokens / total_cost成本超预算时自动降级。
十一、Agent 安全与风险
| 风险 | 防御 |
|---|---|
| Prompt Injection | 输入过滤、权限隔离、不要直接把用户输入塞进系统提示词 |
| 工具滥用 | 敏感工具必须审批,设白名单 |
| 数据泄露 | PII 脱敏、最小权限原则 |
| 无限循环 | max_steps + 重复检测 |
| 幻觉 | 要求引用来源、 grounding 校验 |
| 沙箱执行 | 代码类工具必须在隔离环境运行 |
最小权限原则
Agent 只能访问它必须访问的东西。不要让一个查天气的 Agent 也能删数据库。
十二、Agent vs Workflow
| Agent | Workflow | |
|---|---|---|
| 决策权 | LLM 自己决定下一步 | 人把步骤写死 |
| 灵活度 | 高 | 低 |
| 可控性 | 低 | 高 |
| 成本 | 高(多次 LLM 调用) | 低 |
| 适用 | 探索性、开放式任务 | 固定流程、高确定性任务 |
选型原则
流程固定 → Workflow
需要推理和自适应 → Agent
两者混合 → Agent 决定大方向,Workflow 执行固定子步骤十三、MCP(Model Context Protocol)
Anthropic 推出的开放标准,让 LLM 统一连接外部工具和数据源。
核心思想
以前:每个框架各自定义一套工具接口
MCP:所有工具都按同一协议暴露,Agent 像插 USB 一样即插即用组成
| 组件 | 作用 |
|---|---|
| MCP Server | 提供工具/资源/提示词的服务端 |
| MCP Client | Agent 里连接 Server 的客户端 |
| Protocol | 统一的通信格式 |
为什么值得关注
- 工具可以跨框架复用
- 降低接入新数据源的成本
- 生态逐渐形成标准
十四、部署形态
| 形态 | 场景 |
|---|---|
| 聊天界面 | 客服、助手 |
| API 服务 | 被其他系统调用 |
| 后台异步任务 | 批量处理、定时任务 |
| Webhook | 接收外部事件触发 |
生产 checklist
- [ ] 日志完整记录每次循环
- [ ] 监控成本、延迟、错误率
- [ ] 有降级方案(LLM 不可用时返回默认提示)
- [ ] 敏感操作需审批
- [ ] Prompt 版本管理
- [ ] 回归测试集
