从一次模型调用到 Agent:Tools 和 RAG 分别解决什么问题
目录(12)
从一次模型调用到 Agent:Tools 和 RAG 分别解决什么问题
一个聊天框背后,可能同时存在模型、会话存储、工具、检索系统和业务代码。 用户只看到一句回答,很容易把这些能力都归到“AI”身上:
- 它为什么记得前面的对话?
- 它真的会自己查询数据库吗?
- Tool Calling 和 Agent 有什么区别?
- Tools 和 RAG 都能提供外部信息,为什么不能只选一个?
如果这些概念没有分清,产品设计很容易走向两个极端:要么把模型当成无所不能的黑盒, 要么把所有流程都写死,完全没有利用模型处理模糊语言的能力。
这篇文章从最小的模型调用开始,一层层拆到 Agent 和 RAG。
第一层:模型调用
对大多数自回归语言模型来说,生成过程可以粗略理解为:
输入上下文 → 计算下一个 Token 的概率分布 → 选出一个 Token → 继续生成
从应用层看,它很像“根据已有内容继续写”。但这里有三个容易被简化过头的地方。
Token 不是一个字
Token 是模型处理文本的单位,可能是一个词、词的一部分、一个汉字、标点或几个字符的组合。 切分结果由具体模型的 tokenizer 决定,同一段文字换一个模型,Token 数量也可能变化。
因此不要用“一个汉字等于一个 Token”估算成本,也不要把字符的 UTF-8 字节误认为 Token ID。 需要精确计算时,应使用目标模型对应的 tokenizer。
模型不是永远选择概率最高的词
模型先产生概率分布,再由解码策略决定如何选择下一项。Temperature、top-p 等参数可能影响 采样结果,但不同模型和服务商支持的参数、范围与实际行为并不完全一致。
所以“同一个问题每次都应得到完全相同的答案”并不是一个可靠假设。
输出只基于本次可见的上下文
模型不会自动知道你的数据库、内部文档或上一次独立请求的内容。它能依据的,是这次调用中 真正提供给它的输入,以及服务端工具在本次执行中补充的结果。
这不代表所有 AI API 都“不保存状态”。有些 API 或应用会保存 conversation、response 或 thread, 并在后续调用时恢复上下文。需要区分两件事:
- 模型层:一次生成只处理当前可见的上下文;
- 应用/API 层:可以负责保存、裁剪和重新提供历史状态。
聊天产品的“记忆”,通常是模型能力和应用层状态管理共同形成的体验。
第二层:Tool Calling
纯模型可以理解文字并生成内容,但它不能凭空读取你的订单、修改数据库或调用内部接口。 Tool Calling 为模型和外部系统约定了一种结构化协作方式。
一个工具通常包含:
- 名称:工具是做什么的;
- 描述:什么情况下应该使用;
- 输入 schema:允许哪些参数、类型和约束;
- 执行逻辑:真正查询或修改外部系统的代码。
典型流程如下:
这里最重要的边界是:
模型提出“想调用什么”,执行环境决定“是否允许以及如何执行”。
有些工具由应用自己的服务器执行,有些内置工具由模型服务商执行。无论是哪一种, 工具调用都不应该被理解为“模型可以绕过代码和权限直接做事”。
Tool Call 不是可信输入
模型生成的参数仍然属于外部输入,必须像处理普通 API 请求一样防御:
- 用 schema 校验类型、枚举和长度;
- 在服务端重新做身份认证与权限检查;
- 写操作使用幂等键,避免重试造成重复副作用;
- 高风险操作增加确认步骤;
- 限制工具集合,不要把内部所有能力一次性暴露给模型;
- 记录调用参数、结果、耗时和失败原因,便于审计。
让模型选择工具,不等于把安全边界交给模型。
第三层:Agent Loop
一次 Tool Calling 只能完成“模型提出调用请求”这一步。真实任务经常需要多个回合:
- 模型决定调用工具;
- 应用执行工具;
- 工具结果回到上下文;
- 模型判断下一步;
- 继续调用工具,或者生成最终回答。
这个“模型—工具—模型”的循环,就是 Agent 最核心的执行结构之一。
Agent 不只是“模型多调用几次工具”。一个可上线的 Agent 还需要:
- 最大步骤数和超时;
- 可取消机制;
- 权限与审批;
- 失败重试和降级策略;
- 上下文裁剪;
- 成本与用量限制;
- 完整的调用轨迹。
如果业务流程本来就确定,例如“先校验参数,再查库存,最后创建订单”,普通代码或显式工作流 通常更可靠。Agent 更适合路径无法预先枚举、需要模型根据中间结果继续判断的任务。
第四层:RAG
RAG 是 Retrieval-Augmented Generation,即检索增强生成。
它解决的不是“让模型执行动作”,而是“回答前给模型补充相关知识”。一个常见流程是:
用户问题
↓
关键词、向量或混合检索
↓
过滤、重排相关片段
↓
把片段和来源加入模型上下文
↓
生成回答并展示引用
向量数据库不是 RAG 的定义。数据量较小或关键词明确时,全文检索、数据库查询甚至人工规则 都可以成为检索器;大型系统也经常组合关键词、向量和结构化过滤。
RAG 适合处理:
- 企业内部规范和知识库;
- 会持续更新的产品文档;
- 需要引用依据的客服或研究问答;
- 模型训练数据中没有的私域内容。
但 RAG 也不是“消除幻觉”的开关。检索可能漏掉关键资料、召回错误版本,模型也可能误读片段。 生产系统至少要关注:
- 文档版本、权限和生命周期;
- 分块策略与检索召回率;
- 重排和上下文长度;
- 来源引用是否真的支持结论;
- 外部文档中的 Prompt Injection;
- 没有可靠证据时是否允许拒答。
Tools 和 RAG 到底有什么区别
| 维度 | Tools | RAG |
|---|---|---|
| 核心目标 | 执行动作、读取实时状态 | 提供回答所需的知识依据 |
| 常见数据 | 订单、库存、天气、计算结果、业务 API | 文档、规范、手册、研究资料 |
| 是否可写 | 可以包含创建、修改、发送等副作用 | 通常只读 |
| 触发方式 | 模型或工作流选择工具 | 调用模型前检索,也可以由检索工具触发 |
| 主要风险 | 越权、错误参数、重复执行、不可逆操作 | 召回错误、版本过期、证据不足 |
| 关键工程能力 | schema、鉴权、幂等、审批、审计 | 索引、权限过滤、重排、引用、评估 |
可以把它们简单理解为:
Tools 延伸的是行动能力,RAG 补充的是知识依据。
它们不是互斥关系。
一个同时使用 Tools 和 RAG 的例子
假设用户提出:
“这笔订单还能退款吗?如果可以,帮我申请。”
一个可靠的系统可能这样处理:
- RAG 检索当前有效的退款政策,并保留条款来源;
- Tool 查询订单状态、商品类型和支付时间;
- 模型根据政策和订单数据解释是否满足条件;
- 应用要求用户确认金额和退款方式;
- Tool 提交退款申请,并使用幂等键防止重复创建;
- 模型总结结果,同时展示政策引用和申请编号。
RAG 回答“规则是什么”,Tools 回答“这笔订单是什么状态”并完成实际操作, Agent Loop 负责根据中间结果决定下一步。
一套更稳定的职责划分
| 层次 | 适合负责的事情 |
|---|---|
| 模型 | 理解模糊表达、生成语言、在候选动作中做判断 |
| 检索系统 | 找到相关事实、版本和来源 |
| 工具代码 | 查询、计算和执行副作用 |
| 工作流 | 控制顺序、停止条件、审批、重试和失败恢复 |
| UI | 展示进度、数据、证据、确认状态和可操作入口 |
模型越强,也不意味着其他层可以消失。恰恰相反,模型负责的判断越多,系统越需要清晰的 权限边界、停止条件和可观察性。