【Agent Harness实战】我让 Agent 的上下文“瘦身”成功,Token 省了,记忆反而更好了

我让 Agent 的上下文"瘦身"成功,Token 省了,记忆反而更好了

前几篇聊了 Agent 怎么编排调度、怎么用 5W2H 和 PDCA 做认知框架、四层记忆系统、感知引擎。

但在记忆系统那篇里,有个最关键的设计我只是一笔带过------上下文到底是怎么"瘦身"的? 为什么聊了 50 轮,Token 几乎不涨?为什么 Agent 永远不会忘记第 3 轮说过什么?

今天把这套"上下文管理"的压箱底设计拆开揉碎讲清楚。这里面藏着整个 Agent OS 最精妙的工程细节。


一、历史上下文:只拼摘要,不拼全文

传统 Agent 怎么处理多轮对话?把每轮的完整回复全塞进上下文。聊 50 轮,上下文就塞满 50 轮完整回复------Token 爆炸,LLM 还容易迷失重点。

我的做法:每轮 LLM 回复后,强制它输出一个 summary(摘要)。历史上下文只拼接这些摘要,不拼原始内容。

makefile 复制代码
历史上下文示例:

第1轮摘要: 用户需要分析Q2销售数据,目的是为库存计划提供依据
第2轮摘要: 确认数据源为sales_q2.csv,数据包含区域、产品、销售额三个维度
第3轮摘要: 决定使用Python分析,拆分为数据清洗、分组分析、预测建模三步
第4轮摘要: 数据清洗完成,发现华东区有12条异常值,已标记待确认
...

但是,光有摘要不够。 万一 LLM 突然想确认某个细节呢?比如"第 3 轮里那个 JWT 密钥到底是多少位的?"

所以,系统在注入摘要的同时,会自动附带对应的 IRI(数据地址)。

bash 复制代码
第3轮摘要: 决定使用JWT认证,采用256位密钥
  ↳ 详细内容: memory:session-042/block-003

LLM 拿到这个 IRI 后,如果觉得摘要信息够了,就不用管。如果需要确认细节------比如"256 位密钥的配置代码具体怎么写?"------它就调用内置的图查询工具,沿着 IRI 去 Oxigraph 里查。

sparql 复制代码
SELECT ?content WHERE {
  <memory:session-042/block-003> mem:content ?content .
}

图数据库瞬间返回那轮的完整记录,Token 不花,细节不丢。

这套"摘要 + IRI 引用"的组合拳,是 JSON-LD 作为数据地址总线和 Oxigraph 作为高速查询引擎结合后的核心威力。 单轮对话 Token 会略多一点(因为多了 summary 和 IRI 字段),但对于需要几十轮才能完成的复杂任务,Token 消耗从 O(n) 变成了接近 O(1)。


二、提示词分区顺序:固定在前,动态在中,历史在后

很多人写 Prompt 就是一坨全塞进去,完全不考虑顺序。

LLM 对提示词不同位置的注意力是不一样的------最前面和最后面的内容记得最牢,中间容易"走神"。

所以我把系统提示词分成了严格的分区顺序:

graph TB subgraph 提示词分区 direction TB FIXED[&#34;固定系统提示词<br/>(最前面)<br/>角色定义 + 输出格式&#34;] DYNAMIC[&#34;动态系统提示词<br/>(中间)<br/>5W2H约束 + 重要强调<br/>+ 工具列表 + 经验注入&#34;] HISTORY[&#34;历史会话 summary<br/>(动态之后)<br/>只拼摘要 + IRI 引用&#34;] CURRENT[&#34;本轮用户输入<br/>(最后面)&#34;] end FIXED --> DYNAMIC --> HISTORY --> CURRENT

为什么这样排序?

  • 固定提示词最前面:角色定义、输出格式是"铁律",必须让 LLM 最先看到、印象深刻。"你是谁"、"必须输出什么格式"------这些一旦被放在后面,LLM 就可能"忘了自己的身份"。
  • 动态提示词中间:5W2H 约束、工具列表、经验注入------这些随任务变化,放中间不影响角色认知。
  • 历史摘要接在后面:让 LLM 了解"之前聊了什么",但不抢占最核心的注意力位。
  • 本轮用户输入最后面:利用"近因效应",LLM 对最后看到的内容印象最深,优先处理当前问题。

三、后台 Batch 提取:用户输入不浪费,自动生成"重点笔记"

前面讲的都是 LLM 回复后的处理。但用户说的话同样宝贵------里面藏着需求、约束、决策。

我设计了一个后台批处理机制:用滑动窗口收集最近几轮用户输入,攒够一批就调用 LLM 做结构化总结。

flowchart LR U1[&#34;第1轮用户输入&#34;] U2[&#34;第2轮用户输入&#34;] U3[&#34;第3轮用户输入&#34;] WINDOW[&#34;滑动窗口<br/>(默认 5 轮)&#34;] BATCH[&#34;后台 Batch Agent<br/>调用 LLM 总结&#34;] L0[(L0 知识图谱)] L2[(L2 黑板)] U1 --> WINDOW U2 --> WINDOW U3 --> WINDOW WINDOW -->|&#34;窗口满 5 轮&#34;| BATCH BATCH -->|&#34;重点内容摘要&#34;| L2 BATCH -->|&#34;实体 + 关系 IR I&#34;| L0

抽取出的重点内容分两条路处理:

  1. 存入 L2 黑板:当前任务的活跃重点,直接注入后续 Agent 的上下文
  2. 存入 L0 知识图谱:实体、关系、决策全部建 IRI 节点,永久保存

效果:下次 SA 调度时,从 L2 直接拿到"前几轮讨论提炼出的重点",而不是重新翻聊天记录。


四、大结果不是简单压缩,而是生成知识图谱

很多 Agent 系统对工具调用的大结果(比如几千行的日志、几百条的搜索结果)是直接截断或做文本摘要。

这样做的问题是:摘要丢了结构,LLM 无法确认细节。

我的做法:大结果自动生成局部知识图谱,上下文里注入让 LLM 用工具查询的提示。

flowchart TB TOOL_RESULT[&#34;工具返回大结果<br/>(日志/搜索结果/代码)&#34;] KG_GEN[&#34;自动生成局部知识图谱<br/>(存入 L0)&#34;] SUMMARY[&#34;生成结构摘要<br/>(注入上下文)&#34;] TOOL_HINT[&#34;注入工具提示:<br/>'可通过 query_graph<br/>查询细节'&#34;] LLM[&#34;LLM 看到摘要<br/>+ 工具提示&#34;] QUERY[&#34;需要细节时<br/>调用 query_graph<br/>查 IR I&#34;] TOOL_RESULT --> KG_GEN TOOL_RESULT --> SUMMARY SUMMARY --> TOOL_HINT TOOL_HINT --> LLM KG_GEN --> QUERY QUERY --> LLM

举个例子:

DA 执行了一个 SQL 查询,返回了 2000 行数据。直接扔进上下文烧 Token,截断了怕丢信息。

系统自动处理:

  1. 2000 行数据生成一个局部知识图谱,每行一个 IRI 节点
  2. 上下文里只注入:"查询返回 2000 条结果,摘要:华东区销售额增长 35%,华南区下降 12%。可通过 query_graph(IRI: result-042) 查询特定区域或产品的详细数据。"
  3. LLM 如果想确认"华南区下降的具体产品是什么",就调用 query_graph 工具沿 IRI 去查

兜底机制:如果结果太大导致知识图谱生成也耗时,就分 chunk 处理,每个 chunk 一个摘要 IRI,上下文里只记录 IRI 列表。


五、完整上下文构建流程

sequenceDiagram participant SA participant SPB as 提示词构建器 participant L2 as L2 黑板 participant L3 as L3 投影引擎 participant Agent as AgentRunner participant LLM SA->>SPB: 构建提示词(角色=PA, 任务=sales-q2) Note over SPB: 1. 固定提示词(最前面) SPB->>SPB: Region 1: 角色定义 + Region 4: 输出格式 Note over SPB: 2. 动态提示词(中间) SPB->>L3: 获取5W2H约束、工具列表、经验注入 L3-->>SPB: Region 2 + Region 5 + Region 6 SPB->>L2: 获取后台 Batch 提取的重点摘要 L2-->>SPB: Region 3: 强调内容 + 重点摘要 Note over SPB: 3. 历史会话 summary(动态之后) SPB->>L2: 获取历史 summary + IRI 引用列表 L2-->>SPB: 历史上下文 Note over SPB: 4. 本轮用户输入(最后面) SPB->>SPB: 拼接当前用户消息 SPB-->>SA: 完整系统提示词 SA->>Agent: 执行 Agent->>LLM: 发送完整提示词 LLM-->>Agent: thought/content/summary Agent->>Agent: summary 回写 L1<br/>content 存 L0

六、总结:上下文管理的四个核心设计

  1. 历史上下文只拼摘要 + IRI 引用:复杂任务 Token 从 O(n) 降到接近 O(1),细节通过图查询随时确认。这是 JSON-LD 作为数据地址总线和 Oxigraph 结合的巅峰应用。
  2. 固定提示词在最前,动态在中间,历史在动态之后,本轮在最后:利用首因和近因效应,让 LLM 记住最重要的东西。
  3. 后台 Batch 滑动窗口提取用户重点:用户输入不浪费,自动提炼成重点摘要注入上下文,同时沉淀为知识图谱节点。
  4. 大工具结果生成知识图谱,不压缩原文:上下文里只放结构摘要 + 查询提示,LLM 需要细节时通过 IRI 工具查询,兜底分 chunk 处理。

这套上下文管理的本质,是把 LLM 的"工作台"从堆满杂物的桌子变成只放索引卡片的干净桌面------想查什么,顺着索引去找,而不是把所有东西摊在桌上。


七、预告

下一篇聊 Skill Graph------技能不是 Markdown 文件,而是 JSON-LD 图节点。200 多个 Skill 怎么互相发现、怎么自动组合、怎么做到"渐进式披露"------SA 看只花 200 Token,DA 执行时才展开到 1500 Token。期待的话,下篇见。


我这套系统叫 Gliding Horse(流马) ,所有代码都在 GitHub 上:github.com/doiito/glid...

设计细节系列持续更新中。想催更或者点菜,去 Issue 区喊一声。

相关推荐
意图共鸣1 小时前
技术视角:意图共鸣科技《AI记忆链商业化白皮书3.0》中的第二大脑与AI参谋架构
人工智能
大模型最新论文速读1 小时前
06-10 · LLM 最新论文速览
论文阅读·人工智能·深度学习·机器学习·自然语言处理
梦想三三1 小时前
矿物智能识别项目实战(一):从零开始清洗工业矿物数据
大数据·人工智能·数据挖掘
雨水的早晨1 小时前
什么是SKill
人工智能·skill
gis分享者1 小时前
AI数字营销实测体验,产品推广创作体验
人工智能·csdn·产品推广·数字营销·体验
下班走回家1 小时前
RAG 技术的进化:从朴素检索到 Agentic RAG
开发语言·人工智能·python
Codebee1 小时前
做一款 AI-IDE 有多难 —— 从 OODER Studio 的现有实现谈起
人工智能
傅科摆 _ py1 小时前
AI Ping 平台使用教程
java·前端·人工智能
weixin_307779131 小时前
从“大海捞针”到“主动推理”:AI如何重塑云原生故障诊断的根因链
开发语言·人工智能·算法·自动化·原型模式