Agent 工程实践:从 RAG、工具调用到可控自动化
Agent 工程实践:从 RAG、工具调用到可控自动化
Agent 是 AI 原生应用里最容易让人兴奋,也最容易失控的概念。
一个普通聊天机器人只会回答问题。一个 Agent 可以根据目标拆解步骤、选择工具、调用外部系统、观察结果,再决定下一步。
但生产系统里,Agent 不能只追求“自主”。更重要的是可控、可审计、可回滚、可评估。
Agent 的基本循环
一个 Agent 通常包含以下循环:
用户目标
-> 规划下一步
-> 选择工具
-> 调用工具
-> 观察结果
-> 更新状态
-> 判断是否完成
-> 输出结果例子:
帮我查一下订单 1001 为什么还没发货。Agent 可能会:
- 调用订单查询工具。
- 发现订单已付款但库存不足。
- 调用库存查询工具。
- 调用物流规则知识库。
- 生成解释和建议处理动作。
如果用户继续说:
那帮我创建一个人工处理工单。Agent 可以调用工单系统,但在创建前最好要求用户确认。
Agent、RAG、Workflow 的关系
RAG 是一种知识增强模式。
Workflow 是预先定义的流程。
Agent 是允许模型动态选择步骤的执行模式。
三者可以组合:
Agent
-> RAG 工具:查询政策知识
-> 数据库工具:查询订单状态
-> 工单工具:创建处理单
-> 通知工具:发送消息不要把 Agent 理解成 RAG 的替代品。Agent 可以把 RAG 当成一个工具使用。
什么时候需要 Agent
适合 Agent 的场景:
- 用户目标开放,步骤不固定。
- 需要多工具组合。
- 需要根据中间结果调整路径。
- 任务包含查询、判断、生成、执行多个阶段。
不适合 Agent 的场景:
- 流程固定,直接写 Workflow 更稳。
- 涉及资金、权限、删除、审批等高风险操作。
- 结果必须完全确定。
- 缺少工具权限和审计能力。
例如“根据知识库回答问题”通常用 RAG Workflow 即可。“调查订单异常并给出处理建议”更适合 Agent。
工具是 Agent 的手
Agent 的能力来自工具。没有工具,Agent 只是会聊天。
工具可以是:
- 查询数据库
- 调用 HTTP API
- 检索知识库
- 搜索网页
- 读取文件
- 执行代码
- 创建工单
- 发送邮件
- 生成图表
一个工具至少要定义:
名称
说明
参数 schema
返回格式
权限规则
错误处理
是否高风险示例:
{
"name": "get_order_status",
"description": "根据订单号查询订单支付、库存、发货和物流状态。",
"parameters": {
"order_id": "string"
},
"risk": "read-only"
}工具说明要让模型知道何时调用,也要让后端知道如何校验。
工具返回要简洁
工具返回不是越多越好。返回内容太长,会浪费上下文,也会干扰模型判断。
不推荐:
{
"order": {
"all_fields": "... 上百个字段 ..."
}
}推荐:
{
"order_id": "1001",
"paid": true,
"stock_status": "out_of_stock",
"shipping_status": "not_shipped",
"suggested_reason": "库存不足,暂未发货"
}工具输出应该面向模型决策,而不是直接暴露数据库原始结构。
只读工具和写入工具
工具要按风险分级。
只读工具:
- 查询订单
- 查询库存
- 查询知识库
- 查询用户资料
写入工具:
- 创建工单
- 修改订单
- 发优惠券
- 发送邮件
- 删除文件
- 执行命令
只读工具可以相对宽松。写入工具必须加权限、确认和审计。
高风险操作不要只靠 Prompt 限制。后端必须强制执行:
用户权限校验
参数合法性校验
二次确认
操作审计
幂等控制
回滚策略Agent 的记忆
记忆不是把所有聊天记录都塞进上下文。
常见记忆类型:
- 短期记忆:当前对话上下文。
- 长期记忆:用户偏好、历史任务。
- 工作记忆:当前任务状态、已调用工具、待完成步骤。
- 外部记忆:数据库、向量库、知识库。
生产中要谨慎保存长期记忆,尤其涉及隐私和权限。
更推荐把任务状态结构化保存:
{
"task_id": "task-001",
"goal": "分析订单下降原因",
"steps": [
{"name": "query_orders", "status": "done"},
{"name": "query_traffic", "status": "done"},
{"name": "generate_report", "status": "pending"}
]
}结构化状态比长对话历史更可控。
规划能力
Agent 常见做法是先计划再执行。
例如:
用户目标:分析最近 7 天订单下降原因。
计划:
1. 查询最近 7 天订单量。
2. 查询前 7 天订单量作为对比。
3. 查询渠道流量。
4. 查询支付失败率。
5. 汇总结论。计划可以由模型生成,但执行时应该受约束:
- 最大步骤数。
- 最大工具调用次数。
- 超时时间。
- 禁止调用的工具。
- 用户确认点。
否则 Agent 可能陷入循环或执行不必要操作。
受控 Agent 架构
推荐架构:
用户请求
-> 权限校验
-> 任务分类
-> 是否允许 Agent
-> Agent Planner
-> Tool Router
-> Tool Executor
-> Observation Store
-> Safety Checker
-> Final Answer其中 Tool Executor 必须由后端控制,不要让模型直接访问真实系统。
模型只能提出工具调用意图:
{
"tool": "get_order_status",
"arguments": {
"order_id": "1001"
}
}后端负责:
- 检查工具是否存在。
- 检查用户是否有权限。
- 检查参数是否合法。
- 执行工具。
- 记录日志。
- 把结果返回给模型。
Human-in-the-loop
高风险任务需要人类确认。
例如:
- 退款
- 删除数据
- 发送外部邮件
- 修改生产配置
- 执行服务器命令
- 创建采购订单
流程:
Agent 提出操作建议
-> 展示给用户确认
-> 用户确认
-> 后端执行
-> Agent 汇报结果确认信息要具体:
即将给订单 1001 创建退款申请,金额 199 元,原因:库存不足无法发货。是否确认?不要让用户确认模糊操作。
Agent 评估
Agent 比普通 RAG 更难评估,因为它包含多步工具调用。
评估维度:
- 是否正确理解目标。
- 是否选择正确工具。
- 工具参数是否正确。
- 是否遵守权限。
- 是否在资料不足时停止。
- 是否避免无意义循环。
- 是否在高风险操作前请求确认。
- 最终结果是否有用。
可以记录轨迹:
{
"goal": "查询订单未发货原因",
"steps": [
{"tool": "get_order_status", "args": {"order_id": "1001"}},
{"tool": "get_inventory", "args": {"sku": "SKU-8"}}
],
"final_answer": "订单未发货原因是库存不足。"
}评估 Agent 时,不只看最终回答,也要看中间步骤是否合理。
Agent 常见失败模式
第一,工具选择错误。模型调用了不相关工具。
第二,参数编造。模型没有订单号,却编了一个。
第三,循环调用。模型重复查同一个工具。
第四,权限越界。用户无权查询的数据被工具返回。
第五,高风险操作无确认。模型直接执行写入操作。
第六,工具返回太长。模型被噪声干扰。
第七,没有降级策略。工具失败后模型胡乱回答。
这些都要用工程手段处理。
一个最小 Agent 项目
可以从“订单助手”开始。
工具:
get_order_status(order_id)
get_refund_policy(order_status)
create_support_ticket(order_id, reason)能力:
- 用户提供订单号。
- Agent 查询订单状态。
- 如果未发货,查询原因。
- 根据政策说明用户可选方案。
- 如果需要人工处理,创建工单前请求确认。
这个项目能覆盖 Agent 的核心:
- 工具调用
- 多步推理
- RAG 政策查询
- 写入工具确认
- 轨迹日志
- 最终回答
参考资料
- LangChain Agents 教程
- LangChain Tool Calling 概念
- OpenAI 文档:Function calling
- OWASP Top 10 for LLM Applications
总结
Agent 的本质是“模型驱动的工具调用循环”。它能处理开放任务,但也带来权限、安全、成本和可控性问题。
生产中不要追求完全自治。更好的路线是:先做好 RAG,再增加只读工具调用,再加入受控写入工具,最后为复杂任务引入 Agent。每一步都要配套权限校验、审计日志、评估集、超时限制和人工确认。
