猪头少年 - 云南AI专家 - 云南独立开发者

Engineering note

记忆、会话与上下文窗口:哪些信息应该留下

这是「Agent 工程实战」的第 13 篇。专题从一个能聊天、能调工具的 .NET Agent 出发,逐步补齐可靠性、安全、测试与发布能力。

本篇要解决的问题: 从会话持久化、并发控制到上下文预算,建立可控的“记忆”。

返回专题路线


本章定位:本章讨论 Agent 的记忆从哪里来、什么时候该删、怎样摘要,以及为什么上下文窗口应该被当成预算。

建议阅读方式:先通读原理,再对照当前项目源码,最后完成本章实践。先把进程内消息列表管理好,再引入数据库和长期记忆。过早堆存储技术,往往掩盖不了上下文策略缺失。

本章导读

本章讨论 Agent 的记忆从哪里来、什么时候该删、怎样摘要,以及为什么上下文窗口应该被当成预算。

本章采用“源码观察 → 概念拆解 → 工程改造 → 实践验证”的顺序。示例中的接口和代码骨架用于说明设计方向,真正提交代码时应结合项目当前状态逐步落地。

13.1 当前的记忆是什么

当前 _messages 是进程内列表:程序退出即丢失,且所有消息都不断追加。这适合演示多轮对话,不适合长期使用。

13.2 会话对象

建议将消息列表放入会话:

public sealed class AgentSession
{
    public string Id { get; init; } = Guid.NewGuid().ToString("N");
    public DateTimeOffset CreatedAt { get; init; } = DateTimeOffset.UtcNow;
    public List<Message> Messages { get; } = [];
}

后续可以把会话持久化到 JSON、SQLite 或数据库。

13.3 上下文压缩

上下文窗口有限,不能无限追加。常见策略:

  • 保留 system 消息;
  • 保留最近若干轮;
  • 把旧消息摘要化;
  • 工具输出截断并保存原文引用;
  • 把稳定用户偏好写入单独的长期记忆。

摘要不是越多越好。必须记录摘要的来源、时间和可能的失真,关键事实应支持重新检索原文。

13.4 本章交付物

  • session ID;
  • 会话保存与恢复;
  • 消息长度统计;
  • 摘要策略;
  • 工具输出截断策略。

13.5 短期记忆与长期记忆

短期记忆是当前会话中的消息,回答“这轮对话发生了什么”;长期记忆是跨会话保存的用户偏好或事实,回答“以前知道什么”。两者不应混在同一个 _messages 列表里。

例如用户说“我偏好使用中文”,可以保存成一条带来源和时间的偏好记录;但不能把所有历史聊天原文都永久塞进 system message。

13.6 上下文预算

上下文窗口应该被当成一种预算:

system 指令预算
+ 用户问题预算
+ 工具 schema 预算
+ 历史消息预算
+ 工具结果预算
+ 输出预算
<= 模型上下文上限

工具 schema 也会占用上下文。工具数量增加后,不能无限把所有工具都发给模型,可以按任务类型筛选工具。

13.7 工具结果的引用化

读取大型文件时,不要把全部内容放进会话。可以把内容保存到临时 artifact,工具结果只返回摘要、路径、大小和片段:

{
  "success": true,
  "data": {
    "artifactId": "file-123",
    "path": "Agent/ModelHandle.cs",
    "preview": "前 2000 个字符"
  }
}

模型需要更多内容时,再调用带范围的读取工具。这种设计同时改善成本、速度和安全性。

13.8 会话并发

同一会话不能同时被两个请求无序修改。至少要有版本号或锁:

读取 session version = 7
执行一轮
只有 version 仍为 7 才能提交 version = 8

Web 化后,这个问题会从“偶尔显示错乱”变成真实的数据一致性问题。

13.9 练习:实现上下文预算报告

在发送模型请求前统计 system、历史、工具定义和待发送问题的字符数,打印一个脱敏报告。先观察哪部分增长最快,再决定摘要和截断策略。

13.10 本章产出

本章结束时,Agent 应该知道自己记住了什么、忘记了什么、为什么裁剪上下文,以及一次请求占用了多少预算。

单篇实战作业

实践:增加上下文预算报告,分别统计 system、历史、工具 schema 和工具结果占用的字符数。

建议把作业拆成一个独立提交,并在提交说明中写清楚:改动前的行为、改动后的行为、验证命令、尚未解决的风险。先把进程内消息列表管理好,再引入数据库和长期记忆。过早堆存储技术,往往掩盖不了上下文策略缺失。

章节复盘

复盘问题:上下文被裁剪后,模型是否知道自己不知道什么?关键事实能否重新检索原文?

本章的完成标准不是把所有设计一次性做完,而是能把它变成项目中的一个明确边界,并为下一章留下可验证的接口。


下一篇:第 14 篇《日志、指标与可观测性:看见 Agent 到底做了什么》

如果你正在把 Agent 放进真实工作流,建议完成本篇的实战作业后再继续:每一步都应留下可验证的代码、测试或运行记录。

Next step

不要停在单篇文章。

沿主专题继续阅读,查看同一问题从概念到实战的完整路径。

返回「Agent 工程实战」路线