长期记忆
长期记忆的目标不是让 Agent 搜到更多旧话,而是让它在新证据到来后,更新自己对世界和工作的理解。
假设你两年前说过“我喜欢吃烤肉”,上个月又说“我开始吃素了”。普通向量检索可能同时找回两句话,却不知道后一句已经改变了前一句的含义。
Ankole 不把这两段话当成永远平等的两个结果,而是整理出带时间线的当前认知。
Ankole 的长期记忆模块代号为 Brain。它把原始证据、整理后的当前知识、后台 Dreaming、外部资料学习和 Skill 经验连成一套系统。
记忆不是聊天记录仓库
只增不减的聊天日志解决的是“以前说过什么”,不能独立回答“现在应该相信什么”。一个长期运行的 Agent 还需要完成三类工作:
- 记忆压缩:把分散在多次对话中的相关信息并入同一个主题,而不是留下许多互不相干的碎片。
- 记忆演化:新事实出现后更新旧认知,同时保留必要的生效时间和历史出处。
- 冲突处理:区分明确纠正、不同来源的分歧、尚未证实的传闻和 Agent 自己的推断。
Brain 同时维护两种知识。一种是由人物、组织、项目、政策等词条及其关系构成的世界模型;另一种是从多次工作中归纳或演绎出的判断、经验和工作方法。
一份长期记忆由什么组成
| 组成部分 | 回答的问题 | 是否可以直接当作事实 |
|---|---|---|
| 聊天消息 | 谁在什么时候说过什么 | 只证明“说过这句话” |
| 外部资料 | Agent 读过哪些文本、网页或文件 | 是证据来源,不等于资料中的每句话都正确 |
| 情景摘要 | 一段聊天主要在讨论什么 | 不可以,只用于找到原始消息 |
| 知识词条 | 当前对一个主题知道什么 | 是带出处、可纠正的当前认知 |
| 常驻备忘 | 哪些规则必须在每轮都提醒 Agent | 是从知识中压缩出的工作上下文 |
| Skill Overlay | 使用某个 Skill 时应注意什么 | 是单个 Agent 的程序性经验 |
一条知识词条对应一个稳定主题。它可以包含名称、类型、别名、简介、属性、分块正文和与其他词条的关系。
这些词条和关系组成轻量的世界模型。例如,一个人物可以属于某个组织,一个项目可以受某项政策影响。
Brain 只把证据明确表达的关系写入关系图,不会把模型猜出的关系伪装成事实。
知识词条也不是不可质疑的“最终真相”。它表示 Agent 目前根据可见证据形成的最佳理解,并保留来源、作者、时间和审计记录。
Dreaming:把信息整理成认知
Dreaming 是 Brain 的后台整理机制。它不会在每条消息到达时立刻调用模型,而会等对话暂时安静,或待处理材料积累到一定数量后再批量处理。
这样既能看见跨消息的完整脉络,也避免为每一句话重复支付同一份提示词和模型开销。
Stage A:为聊天建立情景索引
Stage A 按聊天渠道处理较早的消息,把一段连续聊天划分成一个或多个情景。支线话题可以成为独立情景,噪声可以跳过,仍在进行的话题可以留到下一批。
每个情景摘要包含主题、摘要、未来可能的问法、已经形成的结论、涉及的系统,以及结论对应的原始消息。
情景摘要只负责导航。Stage A 不会改写或删除原始消息;Agent 真正需要引用或核实时,Brain 会展开摘要背后的聊天原文。
模型输出通过校验后,摘要和处理进度才会在同一个事务中保存。失败不会推进进度;即使某段最终被跳过,原始消息仍可通过关键词检索找到。
Stage B:把证据整理成当前知识
Stage B 按 Agent 处理材料。它先浏览情景摘要和材料索引,找出值得长期保存的主题,再展开相关原文、当前知识和已启用的 Skills。
Stage B 会新建词条,也会修改或删除旧正文,更新简介、别名、属性和关系。它还会压缩常驻备忘,并把可复用的工作教训写入 Skill Overlay。
聊天消息可以作为人物、团队、决定和外部世界的证据。任务结果只能说明 Agent 如何完成了一项工作,不能反过来证明 Agent 最后的回答一定正确。
因此,普通的成功不会自动变成经验。只有明确的人类纠正、故障恢复过程,或不容易凭空想到的多步骤成功,才适合沉淀为工作方法。
Stage B 的变更立即生效,并同时写入审计流水。它采用事后监督:人可以检查、纠正或恢复,而不是在每次自动整理前逐条审批。
高级:Dreaming 的默认触发条件
Stage A 默认在频道安静 30 分钟,或积压达到 200 条消息时运行。单次最多处理 200 条、约 8,000 token,并保护最近 20 条及最近 360 分钟的消息。
Stage B 默认在材料安静 30 分钟,或积压达到 50 条时运行。单次最多读取 240 条材料。Stage A 和 Stage B 都使用 light 模型档案。
这些数值是实例级或 Agent 级的高级设置。扫描任务可以频繁检查,但只有满足条件时才会真正调用模型。
演绎记忆与归纳记忆
Brain 不只摘录原话。它也允许 Agent 在证据约束下形成新的判断,但演绎和归纳承担的任务不同。
演绎记忆:从已有事实推出当前含义
演绎从已有事实和明确关系出发,回答“这些事实对当前问题意味着什么”。Agent 会在任务中重新读取相关词条和出处,再结合当前上下文推理。
值得长期保存的推断必须写成有条件的判断,标明 Dreaming、日期和依据。推断出的关系不会直接进入关系图;只有来源明确表达的关系才能成为结构化关系。
归纳记忆:从多次观察中总结模式
归纳把跨消息、跨时间的多次观察合在一起,形成趋势、偏好、规则或工作经验。一次偶然事件不能被包装成长期模式;当前规则要求至少有两条不同证据。
归纳结果会并入拥有该主题的词条,而不是每次观察都新建一条记忆。下一批新证据可以修正、收窄或推翻原来的判断。
Dreaming 的产出不会因为“更综合”就比原始证据更权威。新的 Dreaming 运行由新的原始材料触发,结论必须保留回到来源的路径。
记忆如何压缩和演化
Stage B 整理一批材料时,大致按下面的顺序工作:
- 区分原始消息、任务结果和不值得长期保留的临时状态。
- 找出每份材料涉及的稳定主题,并打开已有词条。
- 比较新证据与当前正文,优先修改已有内容,而不是另建日期词条。
- 重写已经失效或过时的段落,并保留必要的时间范围和出处。
- 更新简介、别名、显式关系、常驻备忘和相关 Skill 经验。
- 在一个事务中提交知识变更、Skill Overlay 更新、审计记录和处理进度。
在前面的饮食例子中,当前词条不应同时写着“喜欢烤肉”和“吃素”,却不给任何解释。
它应表达为“过去喜欢烤肉;自某时起开始吃素”,或者在用户明确纠正后,只保留仍会影响未来建议的现状。
Brain 不用“最后一条消息自动覆盖一切”处理冲突:
| 新情况 | 处理方式 |
|---|---|
| 明确纠正或新的生效日期 | 改写旧内容,写清时间边界 |
| 两个可靠来源相互矛盾 | 并列保留,标为未裁决 |
| 未经证实的说法 | 明确标为未证实 |
| Agent 根据证据形成的判断 | 使用条件式表述,并保留 Dreaming 署名和日期 |
| 人工纠正 | 保留人的新版本;恢复旧审计记录时也不能覆盖后来修改 |
当前版本不会用一个简单的数值置信度替人做决定。时间、出处、说话人、是否明确纠正以及是否仍有争议,会直接写进知识内容和审计记录。
学习外部知识,而不只整理对话
在 Console 打开知识库 → 资料 → 让 Agent 学习资料,选择 Agent 和记忆范围后,可以提供三类资料:
| 资料类型 | Brain 如何处理 |
|---|---|
| 粘贴文本 | 直接建立一条可编辑的外部资料词条 |
| 网页 URL | 抓取网页正文,并建立一条可编辑的外部资料词条 |
| PDF 或其他文件 | 先保存不可变原文件,再让 Agent 在后台完整阅读并整合知识 |
文件会在学习任务开始前保存。因此即使 Worker 暂时不可用,或学习任务失败,原文件也不会丢失,可以直接重试。
资料是证据,不是最终知识。Agent 应把不同主题整理进各自词条,给结论保留资料引用;原文更新后,应重新学习或纠正受影响的知识。
外部系统的事件也可以通过信号源进入 Agent。对于价格、库存等高频变化的数据,更可靠的做法是在任务发生时查询其权威系统。
Brain 适合保存稳定结论、变化原因、适用时间和数据来源,而不是复制一个很快过期的当前值。
如果实例安装了资料 Connector,Brain 还可以按来源版本同步外部文档。同步文档在知识库中是只读镜像;来源更新时整体更新,来源被删除或失去访问权限时撤下。
高级:三种资料的生命周期差异
粘贴文本和网页正文进入普通词条,之后可以由人或 Agent 继续修改。文件保留原始字节,学习得到的正文块必须引用该文件。
Connector 镜像由外部来源负责,不能在 Ankole 中直接修改。需要改原文时,应回到来源系统;本地判断应另建词条,并引用镜像。
删除一份资料不会盲目删除所有派生知识。Brain 会根据精确引用和后续修改判断能否撤回;已经被人改过的内容不会被旧的自动操作覆盖。
Skill Overlay:让工作方法持续改进
知识词条回答“世界现在是什么样”,Skill 回答“这类工作应该怎样做”。把工作教训全塞进知识库,会让事实和操作方法混在一起。
Ankole 因此为每个 Agent 和 Skill 保存一份 Skill Overlay,Console 中称为技能经验。它叠加在内置 Skill 之上,不会修改基础 Skill 文件,也不会影响其他 Agent。
Agent 可以在工作中主动补充经验,Dreaming 也会从明确纠正、故障恢复或可复用的复杂做法中提炼经验。下次加载该 Skill 时,基础说明和 Overlay 会一起交给 Agent。
Dreaming 只能更新已经启用的 Skill,不能凭空创建新 Skill。没有新信息时可以不写;内容重复时应改写已有经验,而不是持续追加近义条目。
你可以在知识库 → 技能经验查看 Dreaming 写入了什么,再到 Agent Library 修改或删除。Skill 被停用时,已有 Overlay 会保留,但不会进入 Agent 的工作上下文。
高级:Skill Overlay 的写入约束
新经验先写适用情境,再写需要遵守的注意事项。Dreaming 会给经验附上日期;一条情境默认不超过 50 token,整份 Overlay 不超过 2,000 token。
与现有经验高度重合时,Dreaming 必须整体改写,而不是在末尾追加。并发修改使用内容版本检查;人在编辑期间若 Dreaming 已经改过,旧编辑不会覆盖新内容。
私聊或保密频道中的材料不能修改全局 Skill Overlay,避免私密内容改变 Agent 在其他场景中的工作方法。
Agent 如何找回需要的记忆
每轮对话都会带上一份很短的常驻备忘。它只放那些不经搜索也必须遵守的规则,并受固定 token 预算限制;其余知识在需要时检索。
一次 memory_search 会在当前会话有权读取的范围内并行查找:
- 知识词条和正文的关键词结果;
- 知识正文的向量结果;
- 聊天原文的关键词结果;
- 情景摘要的向量结果。
Brain 将四路排名融合为一个总排名,再应用时间衰减和可选的 Rerank。聊天消息随时间完整衰减;知识词条只做有限降权,不会仅因长期未修改就彻底消失。
排名完成后,Brain 才展开入选结果。情景摘要展开其原始消息;有 thread 的消息展开整条 thread;没有 thread 的消息补充前后相邻内容。
最后,Brain 在总 token 预算内保留最相关的若干项。某个候选过长时会被截短,Agent 仍可通过 memory_browse 打开完整 thread 或资料。
Embedding 不是使用长期记忆的前提。未配置向量模型时,关键词检索、知识词条、审计和 Dreaming 仍可工作;缺少的是同义表达和语义相近内容的召回。
记忆范围决定谁能看到什么
每份知识都有归属 Agent 和知识库范围:
| 范围 | 适合保存什么 |
|---|---|
| 共享 | 多个会话都需要使用的公司知识、公共约定和团队事实 |
| Agent 自身 | 这个 Agent 的常驻备忘、长期职责和工作方法 |
| 私聊 | 某个人与 Agent 之间的长期上下文 |
| 频道专属 | 只允许一个保密群聊或频道读取的内容 |
共享频道可以读取共享知识和 Agent 自身知识,默认写入共享范围。私聊还可以读取对应的私聊记忆,默认写回该私聊范围。
聊天渠道使用共享还是频道专属记忆,由信号路由规则中的记忆范围决定。不要为了方便把客户资料或隔离项目写入共享范围。
一个会话的记忆范围在会话期间保持不变。修改信号路由规则后,下一次对话会使用新范围;系统不会把旧会话内容跨过新的可见性边界。
Console 中的长期记忆功能
Console 的知识库有六个标签页。它们共享同一个归属 Principal 选择器,但各自负责一类任务:
| 标签页 | 可以做什么 |
|---|---|
| 词条 | 搜索、新建和编辑当前知识,并维护整理指南 |
| 资料 | 查看保留的文件和 Connector 来源,检查学习或同步状态 |
| 技能经验 | 查看 Dreaming 和 Agent 写入的 Skill Overlay |
| 状态 | 检查 Dreaming、Embedding、常驻备忘、任务和知识质量 |
| 审计 | 筛选、预览和恢复知识变更 |
| Dreaming | 为所选 Agent 手动运行一次 Stage B,并查看整理存活率 |
词条与整理指南
- 打开知识库 → 词条。
- 选择归属 Principal。
- 按名称、别名、简介或正文搜索。
- 需要时展开筛选器,按类型、知识库、作者或更新时间缩小范围。
- 打开词条,检查正文块、出处和关系。
词条编辑器分为编辑、投影和审计。编辑页可以修改元数据、正文块和关系;投影页显示 Agent 实际读取的 Markdown,并列出正文引用的出处。
纠正正文块时填写原因。每个正文块独立记录最后修改者和版本;修改不会抹去历史。
整理指南位于词条列表上方。每个 Principal 在自身知识库中只能有一份,并且只能由人维护。它用来告诉 Dreaming 应采用哪些领域类型、建页门槛、分类和更新规则。
不要把临时进度、一次性的报错或未经核实的猜测写成长期知识。
资料与技能经验
资料页只列出保留的二进制文件和 Connector 管理的来源。粘贴文本和网页正文会直接变成知识词条,因此保存后会进入对应词条,不会留在资料列表中。
打开一份文件可以查看学习状态、下载不可变原文、重试失败的学习任务,并进入引用了该资料的知识词条。
技能经验页是只读汇总。需要修改或删除 Skill Overlay 时,使用卡片上的在 Agent Library 中编辑。
Dreaming 与整理存活率
在知识库 → Dreaming选择 Agent,然后点击立即运行整理。这个按钮只运行所选 Agent 的 Stage B,不会手动触发频道级 Stage A。
运行结束后,页面显示处理材料数、知识操作数和技能经验更新数。
页面还显示 Dreaming 存活率:达到观察周期的 Dreaming 正文中,有多少没有被人修改或删除。它只是发现整理质量变化的监督信号,不是知识正确率,也不是模型评分。
审计与恢复
在知识库 → 审计中,可以按知识库、操作、执行者、Dreaming Run 和日期筛选。
恢复前先预览修改前后的内容。你可以恢复一条记录,也可以选择多条记录后一次恢复。批量恢复按从新到旧执行;只要有一项当前值已经变化,整批就不会写入。
恢复本身也会留下新的审计记录。已经删除的词条仍保留审计流水,可以从删除记录恢复整份词条。
复核时重点检查:
- 暂时状态被误写成长期事实;
- 已经失效但仍会影响判断的规则;
- 重复或互相矛盾的词条;
- 没有来源却表述过度肯定的结论;
- 不再适用或重复堆叠的 Skill 经验。
状态
知识库 → 状态是长期记忆唯一的健康面。它显示当前告警、情景摘要和知识正文的向量状态、全局 Embedding 配置、Stage A 频道、Stage B、常驻备忘预算、卡住的任务和知识 Lint。
知识 Lint 会统计日期式名称、近重名、超长词条和零正文词条。状态页只报告问题,不会替你自动改写知识。
高级:系统配置中的 Brain 设置
展开五组 Brain 配置
打开系统配置,进入 Brain 分组。Console 当前提供五组配置:
| 配置 | 作用范围 | 控制什么 |
|---|---|---|
brain.knowledge |
全局 | 常驻备忘预算和单次召回条数 |
brain.dreaming |
全局默认,可按 Agent 覆盖 | Stage A 和 Stage B 的触发条件与单次预算 |
brain.embedding |
全局 | 实例唯一的向量模型和输出维度 |
brain.search |
全局 | 时间衰减和可选 Rerank |
brain.sources |
全局 | Connector 来源的轮询和切块 |
brain.knowledge
| 字段 | 默认值 | 含义 |
|---|---|---|
pinned_memo_max_tokens |
1500 |
每轮常驻备忘最多占用的 token |
result_limit |
10 |
一次记忆检索最多返回多少个候选 |
brain.dreaming
Console 为这组配置提供专用表单,并把字段分为阶段 A · 频道情景和阶段 B · Agent 知识。
阶段 A 读取全局值:
| Console 字段 | 默认值 |
|---|---|
| 频道静默时间 | 30 分钟 |
| 频道积压条数 | 200 |
| 首次回看 | 5 天 |
| 单窗口消息数 | 200 |
| 单窗口 token | 8,000 |
| 保护尾部条数 | 20 |
| 保护尾部时间 | 360 分钟 |
阶段 B 读取所选 Agent 的有效值:
| Console 字段 | 默认值 |
|---|---|
| Dreaming | 跟随默认;Agent 默认启用 |
| 整理静默时间 | 30 分钟 |
| 整理积压条数 | 50 |
| 材料上限 | 240 |
| Token 上限 | 0,表示不限 |
| 知识操作上限 | 0,表示不限 |
“首次回看”选择读取全部历史时保存为 null;填写 0 表示从当前消息开始。Stage A 的字段对整个实例生效,不按临时选中的处理方 Agent 生效。
brain.embedding
Console 为这组配置提供开关、Embedding 模型 Agent和输出维度三个字段。下拉框只显示 active 且已配置 embedding ModelProfile 的 Agent。
启用时必须选择 Agent,并填写模型真实返回的向量维度,范围为 1 到 4096。知识正文、情景摘要和召回查询共用这一个实例级向量空间。
一个私有化部署实例只使用一套全局向量空间。更换模型或维度后,旧向量会被标记为待更新,并由后台逐步重建。
brain.search
| 字段 | 默认值 | 含义 |
|---|---|---|
half_life_days |
30 |
聊天消息的时间衰减半衰期 |
knowledge_decay_floor |
0.5 |
知识词条时间降权的最低比例 |
rerank_enabled |
false |
是否启用全局 Rerank |
rerank_model_agent_uid |
null |
提供 rerank ModelProfile 的 Agent |
先让关键词和 Embedding 搜索稳定运行,再决定是否增加 Rerank。它会为每次召回增加一次模型调用。
brain.sources
| 字段 | 默认值 | 含义 |
|---|---|---|
enabled |
true |
是否轮询 Connector 管理的外部来源 |
sync_interval_minutes |
15 |
默认同步间隔 |
block_max_tokens |
1500 |
同步文档每个正文块的 token 上限 |
这组配置只控制 Connector 同步,不会关闭手工粘贴文本、抓取网页或上传文件。
检查记忆是否正常
打开知识库 → 状态,先看当前告警,再按页面顺序检查对应管线。
- 搜索不到刚写入的词条:先用准确关键词搜索;若只有语义搜索失败,检查 Embedding 配置和索引积压。
- Agent 记住了错误内容:找到词条并纠正;需要撤销整批改动时,到审计流水恢复。
- 资料一直处于学习中:打开资料查看状态,再检查后台 Agent 任务和 Worker。
- 同一事实出现多份:合并重复正文,并给保留词条补充常用别名。
- Dreaming 长时间没有新结果:检查对应 Agent 的
light模型档案,以及状态页中的不可用原因和失败任务。 - 群聊内容出现在错误范围:检查该聊天渠道的信号路由规则和记忆范围。