核心目标:让智能体能输出更多有效内容,同时不超限上下文、不幻觉、不重复、调用开销可控。这几个模块本质都是向大模型输入上下文素材,最大约束是 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 系统提示词
定位:行为控制器,不要塞业务数据、不要塞大量案例 ✅推荐设计
- 分为多段:角色定义、能力说明、工具调用规则、输出格式、边界约束;
- 尽量精简,控制在500‑1200token,大模型不要把 System 当知识库用;
- 在 System 里写明:如何使用记忆、如何使用知识库、如何使用工具。
示例片段:
你拥有知识库检索结果、用户长期记忆、工具能力。 知识库内容优先参考;记忆记录用户过往偏好;工具用来获取实时数据。 如果检索到的资料冲突,优先工具最新结果 > 知识库 > 记忆 > 历史对话。
❌坏做法:把业务文档、大量示例、用户历史全部写进 System。
取舍点
- System 越长,留给记忆 / 知识库 / 历史会话的 token 就越少;
- System 只写规则,业务资料全部交给 RAG 知识库;用户偏好交给 Memory 记忆。
2. 历史会话 Chat History(当前对话)
作用:保持本轮对话连贯性,理解上下文指代。 两种方案:
-
完整历史模式
:直接把对话全量放入 prompt
- 优点:信息最全;缺点:轮数一多 token 爆炸,后面检索、知识库根本塞不下,大模型就没空间输出长回复。
-
滑动窗口 + 会话摘要模式(生产首选)
- 保留最近 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(长期记忆,跨会话)
记忆≠历史会话,记忆是提炼后的事实,不是原始聊天记录。 不要把完整聊天记录全部存记忆库,只存关键事实:用户偏好、用户说过的事实、重要结论。
两种记忆实现:
- 向量记忆:向量化检索,query 相似度召回相关记忆;
- 结构化记忆:KV 存储,用户属性、偏好表,直接读取。
✅设计要点
- 记忆要做过滤打分,设置召回数量上限,例如最多取 3‑5 条相关记忆;无关记忆直接丢弃;
- 记忆要有时间衰减,很久远低重要度记忆降低权重;
- 记忆在 prompt 中排版简短,每条记忆尽量压缩为短句;
- System 明确告诉模型:记忆只是参考,记忆可能过时,以工具 / 知识库为准。
取舍矛盾
- 记忆放越多,越懂用户,但抢占 token,挤占知识库、输出空间;
- 记忆只保留「对当前 query 有用的」,不要全量灌入。
经验:记忆总 token 控制在 300‑800 以内。
区分:
- 当前对话上下文 → Chat History
- 跨会话用户事实 → Memory 记忆
- 业务文档 → RAG 知识库
4. 知识库检索 RAG
作用:外部业务文档,解决大模型知识截止、业务资料。 ✅设计要点
- 检索后做重排序 Rerank,过滤无关片段;设置最大片段 token,例如总知识库片段控制 1500‑3000token;
- 文档切片不要过大;
- 当知识库和工具返回冲突,工具实时结果优先级 > 知识库静态文档;
- System 告诉模型:没有资料不要编造,不要强行输出。
取舍:
- 召回片段越多,信息越全,但挤占上下文,导致输出变短,甚至触发截断;
- 想要输出更长回复,必须限制 RAG 总输入 token,宁可少召回高质量片段,不要一堆低质量碎片。
误区:很多人把几十 k 文档塞进去,模型输入直接占满,输出只有一两句话。
5. 工具调用 Tool Call
工具包含:联网搜索、数据库查询、文件解析、代码执行。 工具返回结果经常会很大,是最容易爆上下文的模块。
✅设计策略
-
工具返回结果做截断 / 摘要
:
- 如果接口返回几千行数据,不要直接全部塞回 prompt;交给 LLM 做摘要,只保留关键信息;
-
控制循环调用轮次,最大循环次数(例如最多 3 轮工具调用,防止死循环);
-
工具结果优先级最高:实时最新数据,优先级高于知识库、记忆;
-
工具结果也要计入总 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,不能把输入占满。
常见坑与取舍总结
- ❌把全部历史会话、全部记忆、大量知识库一股脑丢进 prompt
后果:输入占满窗口,模型只能输出很短内容,频繁截断。 ✅取舍:做检索召回,只拿和当前 query 相关的素材,做数量 /token 限制。
- ❌System 写几万字,把知识库、示例全部塞 System
✅取舍:System 只做规则,业务知识交给 RAG。
- ❌记忆存完整聊天记录
✅取舍:记忆是提炼后的事实,原始对话留在会话历史。
- ❌工具返回大原始数据直接丢回 LLM
✅取舍:工具返回做摘要压缩。
- ❌不给输出预留 token,全部给输入
✅取舍:输入总 token 必须小于窗口的 70‑80%,剩下留给模型生成回复。
架构层面可选优化方案
- 双层检索:第一层粗召回,第二层 rerank 过滤,保证进 prompt 的都是高相关片段;
- 动态 token 预算:简单 query 少占知识库记忆,复杂 query 动态分配;
- 离线摘要:长历史、长工具返回,使用廉价小模型先摘要,再送入主模型;
- 区分内存记忆(本次会话)和持久记忆(跨会话),不要混淆;
- 多级 Agent:如果素材太多,拆成前置 Agent 做素材整理,再交给主 Agent 生成回答,规避单轮上下文限制。
<blockquote>
<p>核心目标:让智能体能输出更多有效内容,同时<strong>不超限上下文、不幻觉、不重复、调用开销可控</strong>。这几个模块本质都是<strong>向大模型输入上下文素材</strong>,最大约束是 LLM 上下文窗口,所有取舍都围绕「上下文预算分配」展开。</p>
</blockquote>
<h2><a id="_2"></a>各模块职责边界</h2>
<p>表格</p>
<table>
<thead>
<tr>
<th>模块</th>
<th>核心作用</th>
<th>输入来源</th>
<th>典型问题</th>
</tr>
</thead>
<tbody>
<tr>
<td>System Prompt</td>
<td>角色、规则、输出格式、约束、能力边界</td>
<td>硬编码配置</td>
<td>写太长挤占业务上下文;写太短 Agent 乱行为</td>
</tr>
<tr>
<td>工具调用 (Tool Call)</td>
<td>外部能力:查数据库、联网、计算、API、文件解析</td>
<td>函数集合 + 工具返回结果</td>
<td>工具返回内容爆炸;频繁循环调用;工具结果污染 prompt</td>
</tr>
<tr>
<td>记忆检索 (Memory)</td>
<td>长期个性化记忆,用户偏好、历史事实、用户习惯,跨会话持久存储</td>
<td>向量库 / 数据库,用户历史摘要</td>
<td>记忆太多噪音;记忆和知识库混淆;混入无关旧记忆</td>
</tr>
<tr>
<td>知识库检索 (RAG)</td>
<td>静态业务知识、文档、手册、业务规则,通用业务资料</td>
<td>业务文档切片向量库</td>
<td>召回冗余片段;召回无关内容;文档太长占满窗口</td>
</tr>
<tr>
<td>历史会话 (Chat History)</td>
<td>当前对话轮次上下文,本轮对话的问答流</td>
<td>本次会话内存</td>
<td>轮次越多上下文膨胀;旧消息无用但占 token</td>
</tr>
</tbody>
</table>
<blockquote>
<p>关键区分:</p>
<ul>
<li><strong>历史会话</strong>:只管<strong>当前这一轮对话</strong>,临时上下文;</li>
<li><strong>记忆 Memory</strong>:跨会话,提炼后的用户事实、偏好;</li>
<li><strong>知识库 RAG</strong>:业务资料,不是用户对话,是外部文档;</li>
<li><strong>工具调用</strong>:实时外部获取动态数据;</li>
<li><strong>System</strong>:全局行为规则,不存放业务数据。</li>
</ul>
</blockquote>
<h2><a id="_22"></a>整体执行流程(标准流水线)</h2>
<pre><code class="lang-">用户query
1. 预处理:query向量化 + 简单意图判断
2. 并行/串行检索:
├─ 记忆检索Memory:取出和当前query相关的长期记忆
└─ 知识库RAG检索:取出相关业务文档片段
3. 组装上下文素材,做**压缩过滤**(非常关键,保证能回复更多内容)
4. 拼接System Prompt + 过滤后的历史会话 + 检索出来的记忆+知识库 + 用户query
5. LLM判断:是否需要调用工具
├─ 需要:执行tool,拿到工具返回,把工具结果加入上下文,回到4重新推理
└─ 不需要:直接生成回答输出
</code></pre>
<blockquote>
<p>重点:<strong>不要把所有记忆、全部知识库、全部历史无脑塞进去</strong>,这是大部分 Agent 效果差的根源。</p>
</blockquote>
<h2><a id="___39"></a>逐个模块设计策略 & 取舍权衡</h2>
<h3><a id="1_System_Prompt__41"></a>1. System Prompt 系统提示词</h3>
<p><strong>定位:行为控制器,不要塞业务数据、不要塞大量案例</strong> ✅推荐设计</p>
<ol>
<li>分为多段:角色定义、能力说明、工具调用规则、输出格式、边界约束;</li>
<li>尽量精简,控制在<strong>500‑1200token</strong>,大模型不要把 System 当知识库用;</li>
<li>在 System 里写明:如何使用记忆、如何使用知识库、如何使用工具。</li>
</ol>
<blockquote>
<p>示例片段:</p>
<blockquote>
<p>你拥有知识库检索结果、用户长期记忆、工具能力。 知识库内容优先参考;记忆记录用户过往偏好;工具用来获取实时数据。 如果检索到的资料冲突,优先工具最新结果 > 知识库 > 记忆 > 历史对话。</p>
</blockquote>
</blockquote>
<p>❌坏做法:把业务文档、大量示例、用户历史全部写进 System。</p>
<p><strong>取舍点</strong></p>
<ul>
<li>System 越长,留给记忆 / 知识库 / 历史会话的 token 就越少;</li>
<li>System 只写规则,业务资料全部交给 RAG 知识库;用户偏好交给 Memory 记忆。</li>
</ul>
<hr />
<h3><a id="2__Chat_History_62"></a>2. 历史会话 Chat History(当前对话)</h3>
<p>作用:保持本轮对话连贯性,理解上下文指代。 两种方案:</p>
<ol>
<li>
<p>完整历史模式</p>
<p>:直接把对话全量放入 prompt</p>
<ul>
<li>优点:信息最全;缺点:轮数一多 token 爆炸,后面检索、知识库根本塞不下,大模型就没空间输出长回复。</li>
</ul>
</li>
<li>
<p>滑动窗口 + 会话摘要模式(生产首选)</p>
<ul>
<li>保留最近 N 轮原始对话(例如最近 3‑6 轮完整);</li>
<li>更早的历史做 LLM 摘要压缩,只保留关键结论,丢弃细节;</li>
<li>超过阈值直接丢弃极早期会话。</li>
</ul>
</li>
</ol>
<p>✅取舍策略</p>
<blockquote>
<p>想要 Agent 回复更多内容,<strong>必须控制历史会话占用 token</strong>。 总上下文 = System + 历史会话 + Memory + RAG + Query + 输出预留。 输出要预留 20%‑30% 窗口,如果你把输入占满,模型就只能输出很短的回答。</p>
</blockquote>
<blockquote>
<p>例子:8k 窗口模型 System:1k;历史会话:2k;记忆 + 知识库:2k;Query:0.5k;<strong>预留输出 2.5k</strong>。 如果历史占掉 4k,输出就没有空间。</p>
</blockquote>
<blockquote>
<p>取舍:牺牲遥远历史的细节,换取更大输出 token。</p>
</blockquote>
<hr />
<h3><a id="3__Memory_88"></a>3. 记忆检索 Memory(长期记忆,跨会话)</h3>
<blockquote>
<p>记忆≠历史会话,记忆是<strong>提炼后的事实</strong>,不是原始聊天记录。 不要把完整聊天记录全部存记忆库,只存关键事实:用户偏好、用户说过的事实、重要结论。</p>
</blockquote>
<p>两种记忆实现:</p>
<ol>
<li>向量记忆:向量化检索,query 相似度召回相关记忆;</li>
<li>结构化记忆:KV 存储,用户属性、偏好表,直接读取。</li>
</ol>
<p>✅设计要点</p>
<ol>
<li>记忆要做<strong>过滤打分</strong>,设置召回数量上限,例如最多取 3‑5 条相关记忆;无关记忆直接丢弃;</li>
<li>记忆要有时间衰减,很久远低重要度记忆降低权重;</li>
<li>记忆在 prompt 中排版简短,每条记忆尽量压缩为短句;</li>
<li>System 明确告诉模型:记忆只是参考,记忆可能过时,以工具 / 知识库为准。</li>
</ol>
<p><strong>取舍矛盾</strong></p>
<ul>
<li>记忆放越多,越懂用户,但抢占 token,挤占知识库、输出空间;</li>
<li>记忆只保留「对当前 query 有用的」,不要全量灌入。</li>
</ul>
<blockquote>
<p>经验:记忆总 token 控制在 300‑800 以内。</p>
</blockquote>
<blockquote>
<p>区分:</p>
<ul>
<li>当前对话上下文 → Chat History</li>
<li>跨会话用户事实 → Memory 记忆</li>
<li>业务文档 → RAG 知识库</li>
</ul>
</blockquote>
<hr />
<h3><a id="4__RAG_119"></a>4. 知识库检索 RAG</h3>
<p>作用:外部业务文档,解决大模型知识截止、业务资料。 ✅设计要点</p>
<ol>
<li>检索后做<strong>重排序 Rerank</strong>,过滤无关片段;设置最大片段 token,例如总知识库片段控制 1500‑3000token;</li>
<li>文档切片不要过大;</li>
<li>当知识库和工具返回冲突,<strong>工具实时结果优先级 > 知识库静态文档</strong>;</li>
<li>System 告诉模型:没有资料不要编造,不要强行输出。</li>
</ol>
<p>取舍:</p>
<ul>
<li>召回片段越多,信息越全,但挤占上下文,导致输出变短,甚至触发截断;</li>
<li>想要输出更长回复,必须限制 RAG 总输入 token,宁可少召回高质量片段,不要一堆低质量碎片。</li>
</ul>
<blockquote>
<p>误区:很多人把几十 k 文档塞进去,模型输入直接占满,输出只有一两句话。</p>
</blockquote>
<hr />
<h3><a id="5__Tool_Call_137"></a>5. 工具调用 Tool Call</h3>
<p>工具包含:联网搜索、数据库查询、文件解析、代码执行。 工具返回结果经常会很大,是最容易爆上下文的模块。</p>
<p>✅设计策略</p>
<ol>
<li>
<p>工具返回结果做截断 / 摘要</p>
<p>:</p>
<ul>
<li>如果接口返回几千行数据,不要直接全部塞回 prompt;交给 LLM 做摘要,只保留关键信息;</li>
</ul>
</li>
<li>
<p>控制循环调用轮次,最大循环次数(例如最多 3 轮工具调用,防止死循环);</p>
</li>
<li>
<p>工具结果优先级最高:实时最新数据,优先级高于知识库、记忆;</p>
</li>
<li>
<p>工具结果也要计入总 token 预算。</p>
</li>
</ol>
<p>取舍:</p>
<ul>
<li>工具拿的数据越完整,回答越准,但 token 消耗暴涨;</li>
<li>大返回工具,必须做摘要压缩,否则后续没有 token 给知识库、记忆,输出很短。</li>
</ul>
<h2><a id="_System_160"></a>优先级规则(写进 System,解决素材冲突)</h2>
<blockquote>
<p>数据冲突时参考优先级: <strong>工具实时返回结果 > 当前对话最新历史 > 知识库文档 > 用户长期记忆 Memory > 久远历史会话</strong></p>
</blockquote>
<blockquote>
<p>记忆是用户过去说的,可能已经过时;知识库是静态文档,可能不如工具实时数据。</p>
</blockquote>
<h2><a id="_166"></a>上下文预算分配方案(两套可直接落地)</h2>
<blockquote>
<p>假设模型上下文窗口 8k tokens,输出预留 25%(2000token,保证可以输出更多内容)</p>
</blockquote>
<h3><a id="_A_Agent_170"></a>方案 A:偏向业务知识库(企业问答 Agent)</h3>
<ul>
<li>System Prompt:1000</li>
<li>当前会话历史:1500(最近 4‑6 轮完整,更早摘要)</li>
<li>记忆 Memory:500</li>
<li>RAG 知识库片段:2000</li>
<li>用户 Query:500</li>
<li>输出预留:2000</li>
</ul>
<blockquote>
<p>总和:7500,留有安全余量。</p>
</blockquote>
<h3><a id="_B_Agent_181"></a>方案 B:偏向用户记忆(私人助手 Agent)</h3>
<ul>
<li>System Prompt:1000</li>
<li>当前会话历史:1200</li>
<li>记忆 Memory:1000</li>
<li>RAG 知识库:1200</li>
<li>Query:500</li>
<li>输出预留:2000</li>
</ul>
<blockquote>
<p>如果是 32k 大窗口,可以按比例放大,但依然要预留 20‑30% 窗口给输出。 核心关键点:<strong>想要回复更多内容,必须给输出预留足够 token,不能把输入占满</strong>。</p>
</blockquote>
<h2><a id="_192"></a>常见坑与取舍总结</h2>
<ol>
<li>❌把全部历史会话、全部记忆、大量知识库一股脑丢进 prompt</li>
</ol>
<blockquote>
<p>后果:输入占满窗口,模型只能输出很短内容,频繁截断。 ✅取舍:做检索召回,只拿和当前 query 相关的素材,做数量 /token 限制。</p>
</blockquote>
<ol>
<li>❌System 写几万字,把知识库、示例全部塞 System</li>
</ol>
<blockquote>
<p>✅取舍:System 只做规则,业务知识交给 RAG。</p>
</blockquote>
<ol>
<li>❌记忆存完整聊天记录</li>
</ol>
<blockquote>
<p>✅取舍:记忆是提炼后的事实,原始对话留在会话历史。</p>
</blockquote>
<ol>
<li>❌工具返回大原始数据直接丢回 LLM</li>
</ol>
<blockquote>
<p>✅取舍:工具返回做摘要压缩。</p>
</blockquote>
<ol>
<li>❌不给输出预留 token,全部给输入</li>
</ol>
<blockquote>
<p>✅取舍:输入总 token 必须小于窗口的 70‑80%,剩下留给模型生成回复。</p>
</blockquote>
<h2><a id="_214"></a>架构层面可选优化方案</h2>
<ol>
<li><strong>双层检索</strong>:第一层粗召回,第二层 rerank 过滤,保证进 prompt 的都是高相关片段;</li>
<li><strong>动态 token 预算</strong>:简单 query 少占知识库记忆,复杂 query 动态分配;</li>
<li><strong>离线摘要</strong>:长历史、长工具返回,使用廉价小模型先摘要,再送入主模型;</li>
<li><strong>区分内存记忆(本次会话)和持久记忆(跨会话)</strong>,不要混淆;</li>
<li>多级 Agent:如果素材太多,拆成前置 Agent 做素材整理,再交给主 Agent 生成回答,规避单轮上下文限制。</li>
</ol>
评论区