Agent 长会话设计实战:从对话上下文到持久状态,把记忆写进检查清单

摘要: GPT-6 官方明确说 persistent agent 能连续干几小时的活,提示缓存命中还能省最多九成的输入 token 成本------成本被官方补贴了,工程问题没人替你解决。长会话里 Agent 的"记忆"分三层:会话状态、工作上下文、跨会话记忆。本文按会话中、会话变长、会话结束三个阶段,把每一层该放哪、该留什么、该丢什么讲清楚,文末附一张可直接勾选的长会话设计检查清单。

文章目录

开头:Agent 能跑一整天的活了,然后呢?

9 月 22 号 OpenAI 发了篇东西,讲 GPT-6 的提示缓存优化(Better prompt caching for GPT-6),我盯着里面一句话看了半天:persistent agent 现在可以连续工作几个小时 ,做代码库重构、做长文档调研那种活。缓存命中率上去了,输入 token 最多能省九成。翻译一下:官方把长会话的成本问题补贴了,让你敢让 Agent 跑久一点。但成本只是第一道坎。我第一次让 Agent 跑长任务是在沙箱里搭的一堆假订单------原计划是让它一口气处理完,别中间停下来问我。结果跑到后半程,它开始用自己默认的习惯做事,开头交代的规矩全当没听见。我当时第一反应是"模型又犯蠢了",排查到后面才发现,问题出在我没替它管好记忆。

这篇把我在那轮演练里踩出来的三个决策点讲清楚:状态放哪、上下文怎么压缩、记忆怎么留。每个都给边界,别照着抄完就以为万事大吉。

会话、上下文、记忆,先把概念对齐

长会话翻车,多半是这三个词混着用导致的。先把定义对齐,后面全部按这个口径说,不然容易绕晕。

  • 会话状态:Agent 当前这一步在干什么、手里有什么数据。比如处理到第几条、当前订单的 id 是什么。
  • 上下文窗口:每次请求发给模型的全部内容,指令、工具定义、历史对话都塞在里面。窗口是有限的,GPT-6 给了更大的窗口,但再大也有头。
  • 记忆:我理解是跨会话还能用上的东西,比如"金额一律按分返回"这种约定、用户偏好、业务规则。

三个东西的寿命不一样。会话状态跟着这次会话走,上下文窗口每次请求都会重建(历史还在,只是越来越挤),记忆是要跨越会话留下去的。

维度 会话状态 上下文窗口 跨会话记忆
生命周期 单次会话内 每次请求,随窗口滚动 跨会话/跨天
典型内容 处理到第几条、当前数据 指令、工具、历史对话 约定、偏好、规则
存放位置 内存/外部存储 随请求发送给模型 外部存储/数据库
丢了会怎样 任务中断,可重试 细节丢失,Agent 按默认习惯办事 每次会话从头学

表 1 会话状态、上下文窗口、跨会话记忆的对比

判断标准就一句话:凡是丢了会让 Agent 办错事的信息,都不该只活在上下文窗口里。 这条后面反复用到。

阶段一:会话进行中,状态放哪

先说最容易踩的坑:单轮能完的事,别上状态。这条看着像废话,但很多人一上来就把 Agent 做成"带状态"的,结果单轮问答也背着全套历史,白白增加出错的面积。

我之前给 Agent 配过一个问答工具,让它根据用户问题查资料回答,一次一问,问完就完。那种场景给 Agent 塞一套状态管理,纯属给自己找事------每次请求都带全量上下文,答完就丢,干净利落。

真正需要管状态的是长链路任务:批量处理几百条数据、分步骤生成内容、跟外部系统打多轮交道。这种任务里 Agent 自己记不住"处理到第几条",它的工作记忆每次请求都在重置。

我的做法比较土:用一个 JSON 文件当状态层,Agent 每处理一条,就把进度和当前结果写回去。

javascript 复制代码
// state.js ------ 一个极简的会话状态层(Node 25.8.2 实测)
// 为什么看这段:长任务里 Agent 的"进行到哪了"不该靠它自己记,
// 而是外部持久化,重启不丢、可对账。
const fs = require('fs');

const STATE_FILE = './agent-session.json';

function loadState() {
  if (!fs.existsSync(STATE_FILE)) {
    return { processed: 0, agreements: null, results: [] };
  }
  return JSON.parse(fs.readFileSync(STATE_FILE, 'utf8'));
}

function saveState(state) {
  fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
}
text 复制代码
// 运行结果(Node 25.8.2 实测):第一条处理完后的状态文件
{
  "processed": 1,
  "agreements": "金额按分返回;库存字段禁止修改",
  "results": [
    { "id": "O-1001", "amountInCents": 12990, "status": "ok" }
  ]
}

注意看 agreements 这个字段,它是这个方案的核心:把开头跟 Agent 约定好的规矩,直接写进状态文件,而不是只存在于对话开头那几轮里。后面阶段二会讲为什么这条救了我的命。

这里有个明显的边界:状态全塞一个 JSON 文件,扛不住并发和多 Agent 同时写。真上线我会换数据库或 Redis,演练阶段图省事用文件够了。你要是做高并发长任务,别学这个,但思路是一样的。

阶段二:上下文满了,怎么压缩

长任务跑起来,上下文窗口会被中间输出快速灌满。历史对话不能全删------Agent 后面要用前面的结论。这时候只有两条路:压缩,或者换会话。

先说换会话这条路,很多人容易忽略:如果任务能拆成独立小步骤,步骤之间只共享少量数据,那就别硬撑一个长会话。 每个步骤新开会话、只把必要数据传过去,上下文干净,翻车面也小。我后来复盘才发现,当初那个订单任务本来可以拆,是我图省事硬让一个会话从头跑到尾。

拆不动的时候才谈压缩。压缩常见三种,各有各的坑:

压缩策略 怎么做 保留什么 最容易丢什么 适合场景
直接截断 最早的对话滚出窗口 最近的内容 早期指令、开头的约定 早期内容真没用了
摘要压缩 把历史对话喂给模型,产出摘要 事件主干 数字、单位、禁止项这类细节 叙事型任务
结构化压缩 把关键信息抽成结构化字段 状态、结果、约定 推理过程和中间讨论 有明确数据边界的任务

表 2 三种压缩策略对比

我的经验是,摘要压缩是最大的坑 :AI 摘要是会丢细节的,而且丢的恰恰是"金额按分返回"这种看起来不起眼、丢了就要命的信息。OpenAI 自己的缓存指南也印证了这一点------他们专门提醒开发者用 append-only 的方式维护上下文,新指令追加在末尾覆盖旧的,而不是去修改中间内容,就是为了保持上下文稳定、别把前面的东西弄丢。

所以压缩之前,先做一件事:把不可丢的信息钉死在状态里 。就是阶段一那个 agreements 字段。上下文随便压,只要 Agent 每步都能从状态文件里读到关键约定,摘要丢多少都不怕。这个效果我在演练里实测过:没钉约定之前,跑到后半程金额单位错了九十多条;把约定写进状态文件重跑,从头到尾零漂移------完整对账脚本和数字在另一篇演练复盘里有,这篇不重复贴。

这个策略的边界也讲清楚:钉死约定只解决"约定丢失",解决不了"模型对约定的理解漂移"。Agent 读到了约定但执行时打折,那是另一层问题,需要靠验证环节兜。

阶段三:会话结束,记忆怎么留

长任务跑完,会话就结束了,但 Agent 干活的规矩不能跟着会话一起结束。这时候要决定哪些东西值得留到下次会话。

我的取舍标准很简单:留规则,不留过程。 业务约定、输出格式、禁止操作,这些是规则,留;中间某一步具体怎么算出来的,那是过程,下次基本用不上,删。收尾这段用一个归档脚本搞定:

javascript 复制代码
// archiveRules.js ------ 会话结束后:规则入库,过程丢弃
// 为什么看这段:收尾不是把整个会话原样存下来,而是只提取规则层,
// 下次会话载入的也是这份规则,不是几 MB 的历史对话。
const fs = require('fs');

const session = JSON.parse(fs.readFileSync('./agent-session.json', 'utf8'));
const rulesArchive = {
  savedAt: '2026-09-28',
  agreements: session.agreements,      // 规则,留
  resultCount: session.results.length, // 只留数量,过程结果丢弃
  lastId: session.results.at(-1)?.id   // 断点续跑用,留个锚
};

fs.writeFileSync('./rules.json', JSON.stringify(rulesArchive, null, 2));
text 复制代码
// 运行结果(Node 25.8.2 实测):archiveRules.js 产出的 rules.json
{
  "savedAt": "2026-09-28",
  "agreements": "金额按分返回;库存字段禁止修改",
  "resultCount": 428,
  "lastId": "O-1428"
}

留多久、放哪,看信息敏感度:

  • 纯业务规则(金额单位、字段命名):放项目配置或状态文件,长期留。
  • 带用户数据的(用户偏好、历史操作):放数据库,按业务合规要求定保留期。
  • 敏感的(token、密钥、用户 PII):别留在任何 Agent 可读的上下文里,交给专门的密钥管理。

这段说得直白点:记忆不是越多越好。我之前见过有人给 Agent 配了个"无限记忆",把几年对话全存进去,结果每次请求都背着几 MB 的历史,贵不说,Agent 反而被无关老对话带偏。

ASCII 图是长会话生命周期的完整样子:

复制代码
会话开始 → 阶段一:状态初始化(约定写入 agreements)
                ↓
         任务循环:读状态 → 干活 → 写状态
                ↓
         上下文窗口滚满 → 阶段二:先钉死约定 → 再压缩
                ↓
         任务完成 → 阶段三:规则入库,过程丢弃
                ↓
         下次会话 → 载入 agreements,不用从头教

图 1 长会话生命周期:约定从开头写进状态,压缩不丢,结束入库

产出物:长会话设计检查清单

把上面的决策整理成一张能勾选的表,我演练完之后就一直按这个检查:

检查项 具体动作 勾选
1 单轮够用? 任务能一次问答解决就别上状态 ☐
2 需要外部状态吗 长链路任务才需要,先确认拆不掉 ☐
3 约定有没有钉死 关键约定写进状态文件,不只活在对话里 ☐
4 压缩策略选对了吗 数据型任务用结构化,别用摘要 ☐
5 压缩前先固化 先钉不可丢信息,再让上下文滚 ☐
6 留规则不留过程 会话结束只入库规则,过程丢弃 ☐
7 敏感信息隔离 token/PII 不进 Agent 可读上下文 ☐
8 能拆就拆 步骤独立就拆会话,别硬撑长会话 ☐

表 3 长会话设计检查清单

这套清单只覆盖"记忆与上下文"这个维度。长会话还有别的坑------成本监控、任务取消与恢复、超时重试------这篇不展开,真要上线得单独过一遍。

清单落地之后怎么验收?我自己验证的方式是三遍对账:跑一遍长任务,用对账脚本盯漂移点;把约定钉进状态文件重跑,看漂移是否消失;再删掉状态文件重跑,看漂移是否回来。这三步和同一轮演练的复盘文里用的脚本是一套,读者可以照搬------比"我觉得没问题"可靠得多。

边界:有些场景根本不需要长会话

写到最后必须泼一盆冷水。

长会话不是越久越好。多数日常任务根本用不到长会话:问答、单次生成、独立小任务,短会话干净利落,反而省事。硬把简单任务拉成长会话,等于给自己引入状态管理、压缩策略、记忆持久化一整套复杂度,收益为零。

适合长会话的,是那种必须在一个上下文里连续推理、中间结果互相依赖的任务------批量处理共享约定的数据、多步骤长文档、跨系统协调。判断标准就一条:拆开会话后,要不要频繁地把前面的结论手动搬过来?要,就别拆。

我见过不少团队一上来就追求"Agent 跑一整天",其实他们那个场景,拆成几十个短任务反而更稳。先想清楚你的任务配不配长会话,再谈长会话怎么设计。

总结

回头看那轮演练,翻车的不是我让 Agent 跑得久,是我让它的记忆全活在上下文窗口里,而窗口是会滚、会压、会丢的。

三个决策点再压一遍:状态放外部,约定先钉死,记忆留规则不留过程。做到这三点,Agent 跑几小时还是跑一天,差别就没那么大了。

相关推荐
u1301301 小时前
GitHub 热榜项目:周榜(2026-09-27)
人工智能·github
AI搅拌机1 小时前
MiniMax H3导演台Bug修复指南:二采、首尾帧生视频和图生视频优化!全能工作流分享~
人工智能
老纪的技术唠嗑局1 小时前
Tibo 谈 Codex:harness 总比模型快一步
数据库·人工智能
程序员于老七1 小时前
漫话大模型:7 家中国公司被点名「蒸馏」,他们到底偷走了什么?
人工智能
YOLO数据集集合1 小时前
风机叶片表面损伤检测数据集 | 风机叶片 表面损伤 污渍检测 无人机巡检 风电运维9119期
运维·人工智能·计算机视觉·目标跟踪·无人机·智慧城市·电力巡检
程序员于老七1 小时前
漫话大模型:反 LLM 新物种:0.1 秒出结果、零幻觉的 Jev 是什么
人工智能
tellmewhoisi1 小时前
机器学习:集成学习4(XGBoost前置知识泰勒展开式4)
人工智能·机器学习·集成学习
youdexiang2 小时前
会议录音APP实时转文字有哪些关键技术
人工智能
hqyjzsb2 小时前
法律 Prompt 干货:搭建合同审查提示词要包含哪些要素
开发语言·人工智能·python·职场和发展·数据分析·prompt·业界资讯