有勇气的牛排博客

大模型 Agent 深度拆解:System|工具|记忆|RAG|会话历史如何分配上下文预算


核心目标:让智能体能输出更多有效内容,同时不超限上下文、不幻觉、不重复、调用开销可控。这几个模块本质都是向大模型输入上下文素材,最大约束是 LLM 上下文窗口,所有取舍都围绕「上下文预算分配」展开。

各模块职责边界

表格

模块 核心作用 输入来源 典型问题
System Prompt 角色、规则、输出格式、约束、能力边界 硬编码配置 写太长挤占业务上下文;写太短 Agent 乱行为
工具调用 (Tool Call) 外部能力:查数据库、联网、计算、API、文件解析 函数集合 + 工具返回结果 工具返回内容爆炸;频繁循环调用;工具结果污染 prompt
记忆检索 (Memory) 长期个性化记忆,用户偏好、历史事实、用户习惯,跨会话持久存储 向量库 / 数据库,用户历史摘要 记忆太多噪音;记忆和知识库混淆;混入无关旧记忆
知识库检索 (RAG) 静态业务知识、文档、手册、业务规则,通用业务资料 业务文档切片向量库 召回冗余片段;召回无关内容;文档太长占满窗口
历史会话 (Chat History) 当前对话轮次上下文,本轮对话的问答流 本次会话内存 轮次越多上下文膨胀;旧消息无用但占 token

关键区分:

  • 历史会话:只管当前这一轮对话,临时上下文;
  • 记忆 Memory:跨会话,提炼后的用户事实、偏好;
  • 知识库 RAG:业务资料,不是用户对话,是外部文档;
  • 工具调用:实时外部获取动态数据;
  • System:全局行为规则,不存放业务数据。

整体执行流程(标准流水线)

用户query
1. 预处理:query向量化 + 简单意图判断
2. 并行/串行检索:
   ├─ 记忆检索Memory:取出和当前query相关的长期记忆
   └─ 知识库RAG检索:取出相关业务文档片段
3. 组装上下文素材,做**压缩过滤**(非常关键,保证能回复更多内容)
4. 拼接System Prompt + 过滤后的历史会话 + 检索出来的记忆+知识库 + 用户query
5. LLM判断:是否需要调用工具
   ├─ 需要:执行tool,拿到工具返回,把工具结果加入上下文,回到4重新推理
   └─ 不需要:直接生成回答输出

重点:不要把所有记忆、全部知识库、全部历史无脑塞进去,这是大部分 Agent 效果差的根源。

逐个模块设计策略 & 取舍权衡

1. System Prompt 系统提示词

定位:行为控制器,不要塞业务数据、不要塞大量案例 ✅推荐设计

  1. 分为多段:角色定义、能力说明、工具调用规则、输出格式、边界约束;
  2. 尽量精简,控制在500‑1200token,大模型不要把 System 当知识库用;
  3. 在 System 里写明:如何使用记忆、如何使用知识库、如何使用工具。

示例片段:

你拥有知识库检索结果、用户长期记忆、工具能力。 知识库内容优先参考;记忆记录用户过往偏好;工具用来获取实时数据。 如果检索到的资料冲突,优先工具最新结果 > 知识库 > 记忆 > 历史对话。

❌坏做法:把业务文档、大量示例、用户历史全部写进 System。

取舍点

  • System 越长,留给记忆 / 知识库 / 历史会话的 token 就越少;
  • System 只写规则,业务资料全部交给 RAG 知识库;用户偏好交给 Memory 记忆。

2. 历史会话 Chat History(当前对话)

作用:保持本轮对话连贯性,理解上下文指代。 两种方案:

  1. 完整历史模式

    :直接把对话全量放入 prompt

    • 优点:信息最全;缺点:轮数一多 token 爆炸,后面检索、知识库根本塞不下,大模型就没空间输出长回复。
  2. 滑动窗口 + 会话摘要模式(生产首选)

    • 保留最近 N 轮原始对话(例如最近 3‑6 轮完整);
    • 更早的历史做 LLM 摘要压缩,只保留关键结论,丢弃细节;
    • 超过阈值直接丢弃极早期会话。

✅取舍策略

想要 Agent 回复更多内容,必须控制历史会话占用 token。 总上下文 = System + 历史会话 + Memory + RAG + Query + 输出预留。 输出要预留 20%‑30% 窗口,如果你把输入占满,模型就只能输出很短的回答。

例子:8k 窗口模型 System:1k;历史会话:2k;记忆 + 知识库:2k;Query:0.5k;预留输出 2.5k。 如果历史占掉 4k,输出就没有空间。

取舍:牺牲遥远历史的细节,换取更大输出 token。


3. 记忆检索 Memory(长期记忆,跨会话)

记忆≠历史会话,记忆是提炼后的事实,不是原始聊天记录。 不要把完整聊天记录全部存记忆库,只存关键事实:用户偏好、用户说过的事实、重要结论。

两种记忆实现:

  1. 向量记忆:向量化检索,query 相似度召回相关记忆;
  2. 结构化记忆:KV 存储,用户属性、偏好表,直接读取。

✅设计要点

  1. 记忆要做过滤打分,设置召回数量上限,例如最多取 3‑5 条相关记忆;无关记忆直接丢弃;
  2. 记忆要有时间衰减,很久远低重要度记忆降低权重;
  3. 记忆在 prompt 中排版简短,每条记忆尽量压缩为短句;
  4. System 明确告诉模型:记忆只是参考,记忆可能过时,以工具 / 知识库为准。

取舍矛盾

  • 记忆放越多,越懂用户,但抢占 token,挤占知识库、输出空间;
  • 记忆只保留「对当前 query 有用的」,不要全量灌入。

经验:记忆总 token 控制在 300‑800 以内。

区分:

  • 当前对话上下文 → Chat History
  • 跨会话用户事实 → Memory 记忆
  • 业务文档 → RAG 知识库

4. 知识库检索 RAG

作用:外部业务文档,解决大模型知识截止、业务资料。 ✅设计要点

  1. 检索后做重排序 Rerank,过滤无关片段;设置最大片段 token,例如总知识库片段控制 1500‑3000token;
  2. 文档切片不要过大;
  3. 当知识库和工具返回冲突,工具实时结果优先级 > 知识库静态文档
  4. System 告诉模型:没有资料不要编造,不要强行输出。

取舍:

  • 召回片段越多,信息越全,但挤占上下文,导致输出变短,甚至触发截断;
  • 想要输出更长回复,必须限制 RAG 总输入 token,宁可少召回高质量片段,不要一堆低质量碎片。

误区:很多人把几十 k 文档塞进去,模型输入直接占满,输出只有一两句话。


5. 工具调用 Tool Call

工具包含:联网搜索、数据库查询、文件解析、代码执行。 工具返回结果经常会很大,是最容易爆上下文的模块。

✅设计策略

  1. 工具返回结果做截断 / 摘要

    • 如果接口返回几千行数据,不要直接全部塞回 prompt;交给 LLM 做摘要,只保留关键信息;
  2. 控制循环调用轮次,最大循环次数(例如最多 3 轮工具调用,防止死循环);

  3. 工具结果优先级最高:实时最新数据,优先级高于知识库、记忆;

  4. 工具结果也要计入总 token 预算。

取舍:

  • 工具拿的数据越完整,回答越准,但 token 消耗暴涨;
  • 大返回工具,必须做摘要压缩,否则后续没有 token 给知识库、记忆,输出很短。

优先级规则(写进 System,解决素材冲突)

数据冲突时参考优先级: 工具实时返回结果 > 当前对话最新历史 > 知识库文档 > 用户长期记忆 Memory > 久远历史会话

记忆是用户过去说的,可能已经过时;知识库是静态文档,可能不如工具实时数据。

上下文预算分配方案(两套可直接落地)

假设模型上下文窗口 8k tokens,输出预留 25%(2000token,保证可以输出更多内容)

方案 A:偏向业务知识库(企业问答 Agent)

  • System Prompt:1000
  • 当前会话历史:1500(最近 4‑6 轮完整,更早摘要)
  • 记忆 Memory:500
  • RAG 知识库片段:2000
  • 用户 Query:500
  • 输出预留:2000

总和:7500,留有安全余量。

方案 B:偏向用户记忆(私人助手 Agent)

  • System Prompt:1000
  • 当前会话历史:1200
  • 记忆 Memory:1000
  • RAG 知识库:1200
  • Query:500
  • 输出预留:2000

如果是 32k 大窗口,可以按比例放大,但依然要预留 20‑30% 窗口给输出。 核心关键点:想要回复更多内容,必须给输出预留足够 token,不能把输入占满

常见坑与取舍总结

  1. ❌把全部历史会话、全部记忆、大量知识库一股脑丢进 prompt

后果:输入占满窗口,模型只能输出很短内容,频繁截断。 ✅取舍:做检索召回,只拿和当前 query 相关的素材,做数量 /token 限制。

  1. ❌System 写几万字,把知识库、示例全部塞 System

✅取舍:System 只做规则,业务知识交给 RAG。

  1. ❌记忆存完整聊天记录

✅取舍:记忆是提炼后的事实,原始对话留在会话历史。

  1. ❌工具返回大原始数据直接丢回 LLM

✅取舍:工具返回做摘要压缩。

  1. ❌不给输出预留 token,全部给输入

✅取舍:输入总 token 必须小于窗口的 70‑80%,剩下留给模型生成回复。

架构层面可选优化方案

  1. 双层检索:第一层粗召回,第二层 rerank 过滤,保证进 prompt 的都是高相关片段;
  2. 动态 token 预算:简单 query 少占知识库记忆,复杂 query 动态分配;
  3. 离线摘要:长历史、长工具返回,使用廉价小模型先摘要,再送入主模型;
  4. 区分内存记忆(本次会话)和持久记忆(跨会话),不要混淆;
  5. 多级 Agent:如果素材太多,拆成前置 Agent 做素材整理,再交给主 Agent 生成回答,规避单轮上下文限制。

评论区

×
×