持续学习协调_continual-learning:用 AGENTS.md 与 agents-memory-updater 搭建子智能体记忆更新闭环

发布时间:2026/10/2 17:06:36
持续学习协调_continual-learning:用 AGENTS.md 与 agents-memory-updater 搭建子智能体记忆更新闭环 1. 多子智能体协作下记忆为什么会丢先说清楚 continual-learning 是什么、能做什么、适合谁。它是一套「持续学习协调」机制父技能只做编排把对话记录挖掘和 AGENTS.md 更新这两件重活委托给一个叫 agents-memory-updater 的子智能体去干。适合谁适合那些跑长周期任务的团队——比如一个主智能体带三四个子智能体连续几天甚至几周处理同一批需求中间还要不断吸收新信息。如果你遇到过「昨天刚对齐的约定今天子智能体又忘了」这种问题那这套东西就是冲着你来的。我先把问题摊开。多子智能体协作时上下文丢失通常不是模型笨而是记忆没有落点。每个子智能体有自己的上下文窗口任务一结束窗口一清经验就蒸发了。父智能体想记住但它又不该亲自去翻聊天记录、改文件——那样职责就糊了。于是需要一个外部记忆文件也就是 AGENTS.md作为所有子智能体共享的「记忆契约」。谁读它、谁写它、什么时候写、冲突了听谁的这些规则定不清楚持续学习就是一句空话。excerpt 里提到的设计哲学很关键纯协调。父技能不挖转录、不编辑文件、不绕过子智能体。这三条护栏看着简单实际是防止记忆系统退化成「谁都能改、改完没人认」的烂摊子。单一职责原则在这里不是洁癖是刚需——因为一旦父流程也去写 AGENTS.md就会出现两个写入源冲突消解逻辑直接失效。我试过让父智能体顺手更新记忆结果两天后 AGENTS.md 里同一件事有三条互相矛盾的记录子智能体读的时候随机挑一条行为完全不可预测。踩过的坑告诉我记忆更新必须收口到一个子智能体。那 agents-memory-updater 具体负责什么两件事。第一增量写入——只把新出现的、值得长期保留的信息追加进去而不是每次重写整个文件。第二冲突消解——当新信息和旧记录打架时按规则决定是覆盖、保留还是标记待定。这两件事都需要判断力所以交给专门的子智能体父技能只负责「触发」和「返回结果」。这里有个容易被忽略的点持续学习不等于把所有对话都存下来。存太多AGENTS.md 会膨胀到子智能体读不完存太少关键约定又丢了。所以触发规则要设计得克制——只在特定条件下才唤起 agents-memory-updater。下面几节我会给出可复制的模板、触发规则、注册配置以及一轮任务后记忆落盘和回读的完整验证步骤。目标很明确让 continual-learning 在长周期任务里不丢上下文。2. TaoToken 前置把模型调用和记忆闭环接起来要让上面这套记忆闭环真正跑起来你得先有一个稳定的模型调用入口。子智能体 agents-memory-updater 在挖掘转录、判断冲突时都要调模型父技能编排时也要调模型。如果每个子智能体各自配一套 Key、各自指向不同地址那记忆契约还没建立调用层先乱了。所以前置工作就一件事统一 Base URL、统一 Key、统一 Model ID让所有子智能体走同一个入口。我用的是 TaoToken 作为统一入口。它的官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。注意 API 地址后面不加任何 UTM 参数配置里就写这个干净的地址。为什么强调统一因为 agents-memory-updater 在写入记忆时需要和父技能、其他子智能体看到完全一致的模型行为。如果 A 子智能体走一个入口、B 子智能体走另一个同一个冲突判断可能得出不同结论记忆就分裂了。具体要准备三样东西也就是常说的三件套Base URL、Key、Model ID。Base URL 填 https://taotoken.net/api Key 在控制台的 API Keys 页面生成Model ID 按你实际要用的模型填。这三样在后面的 AGENTS.md 模板、子智能体注册配置里都会反复出现先备好。生成 Key 的入口在这里https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。进去之后新建一个 Key复制出来存好。注意 Key 只显示一次丢了就得重建。如果你还没想好具体用哪个模型可以先到模型对话页面看看有哪些可选https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。在对话页里试几个模型确认哪个在「判断两条记忆是否冲突」这类任务上表现稳再把它写进配置。这里要提醒一句不要把 Key 硬编码进 AGENTS.md。AGENTS.md 是共享记忆契约会被多个子智能体读取甚至可能进版本库。Key 应该放在环境变量或独立的密钥文件里AGENTS.md 里只写「从环境变量 TAOTOKEN_API_KEY 读取」这样的引用。这是安全底线别图省事。如果你打算长期跑编码类或 Agent 类任务可以考虑 Coding Plan它更适合这种持续调用的场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 配置细节以文档为准。前置工作做到这里就够了一个入口、一个 Key、一个确定的 Model ID加上一份不泄露密钥的约定。接下来进入可复制配置环节。3. 可复制配置AGENTS.md 模板与子智能体注册这一节是全文的核心给你能直接抄的配置。分三块AGENTS.md 模板、记忆更新触发规则、子智能体注册配置。三块配合起来才构成完整的记忆更新闭环。先看 AGENTS.md 模板。它的作用是当共享记忆契约所以结构要固定让所有子智能体读的时候有章可循。下面这份可以直接复制路径放在项目根目录的 AGENTS.md# AGENTS.md — 共享记忆契约 ## 元信息 - 契约版本: 1.0 - 最后更新: 由 agents-memory-updater 自动填写 - 更新者: agents-memory-updater ## 模型调用约定 - Base URL: https://taotoken.net/api - API Key: 从环境变量 TAOTOKEN_API_KEY 读取禁止硬编码 - Model ID: 填入你确认的模型 ID ## 长期记忆条目 !-- 每条记忆使用固定格式便于冲突消解 -- !-- 格式: [ID] [类别] [置信度] [更新时间] 内容 -- [M001] [约定] [高] [待填] 所有子智能体输出前必须校验字段命名风格为 snake_case [M002] [偏好] [中] [待填] 用户倾向简洁回复避免冗长解释 ## 冲突消解规则 1. 同类别同主题的新条目与旧条目冲突时置信度高者胜 2. 置信度相同时更新时间晚者胜 3. 无法判断时保留两条并标记 [待人工确认] 4. 任何情况下不删除历史条目只做覆盖标记 ## 写入护栏 - 仅 agents-memory-updater 可写入本文件 - 父技能与其他子智能体只读 - 每次写入必须追加禁止整体重写这份模板里模型调用约定那一段就是三件套的落点Base URL、Key 引用方式、Model ID。注意 Key 写的是环境变量引用不是明文。冲突消解规则是给 agents-memory-updater 用的判断依据写清楚它才不会乱覆盖。接着是记忆更新触发规则。不是每轮对话都要更新记忆那样太吵。触发规则建议放在父技能的配置里用一份 JSON 描述{ memory_update_triggers: { on_task_complete: true, on_user_correction: true, on_new_convention: true, min_new_facts: 1, cooldown_seconds: 300, delegate_to: agents-memory-updater } }解释一下这几个字段。on_task_complete 表示一轮任务结束时触发on_user_correction 表示用户纠正了某个行为时触发这类信息最值得记on_new_convention 表示出现了新的约定时触发。min_new_facts 设成 1意思是至少有一条新事实才唤起子智能体避免空跑。cooldown_seconds 是冷却时间防止短时间内反复触发。delegate_to 明确指向 agents-memory-updater这就是「纯协调」的体现——父技能只负责按规则触发不自己动手。最后是子智能体注册配置。这份配置告诉父技能agents-memory-updater 这个子智能体怎么调、用什么模型、能碰哪些文件。用 TOML 写[[subagents]] name agents-memory-updater description 挖掘转录并增量更新 AGENTS.md负责冲突消解 model_id 填入你确认的模型 ID base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY writable_files [AGENTS.md] readable_files [AGENTS.md, transcripts/*.jsonl] guardrails [ 只追加不整体重写, 冲突时按 AGENTS.md 中的消解规则处理, 不删除历史条目 ]这份注册配置里base_url 和 api_key_env 再次出现和 AGENTS.md 里的约定保持一致。writable_files 只给了 AGENTS.md意味着这个子智能体只能写记忆文件不能碰别的。readable_files 里加了 transcripts 目录它要挖转录就得能读。guardrails 把三条护栏写死防止子智能体越界。三块配置放好后目录结构大概是这样项目根目录下有 AGENTS.md、subagents.toml、triggers.json外加一个 transcripts 目录存对话记录。父技能启动时读 subagents.toml 注册子智能体读 triggers.json 决定何时触发子智能体被唤起后读 AGENTS.md 拿规则、写 AGENTS.md 落记忆。闭环就成型了。4. 验证请求一轮任务后记忆落盘与回读配置写完不代表能用得验证。这一节演示一轮完整任务后记忆怎么落盘、怎么回读。验证分四步跑一轮任务、检查触发、确认落盘、回读校验。第一步跑一轮会产生新约定的任务。假设你让主智能体带两个子智能体处理一个数据清洗需求过程中用户说了一句「以后所有时间字段都用 UTC不要用本地时间」。这句话就是一条值得长期保留的新约定。任务结束时on_task_complete 和 on_new_convention 两个触发条件都满足父技能按 triggers.json 唤起 agents-memory-updater。第二步检查触发是否发生。父技能的日志里应该出现类似这样的记录[orchestrator] task complete, checking triggers... [orchestrator] new convention detected: UTC time fields [orchestrator] delegating to agents-memory-updater [agents-memory-updater] reading AGENTS.md... [agents-memory-updater] mining transcripts/2024-xx-xx.jsonl... [agents-memory-updater] new fact: [M003] [约定] [高] UTC time fields [agents-memory-updater] conflict check: no conflict with M001/M002 [agents-memory-updater] appending to AGENTS.md [agents-memory-updater] done, returned result to orchestrator这段日志能证明「纯协调」在起作用父技能只做了检测和委托挖掘转录、判断冲突、写文件全是子智能体干的。如果日志里出现父技能直接编辑 AGENTS.md 的记录说明护栏被绕过了得回去检查配置。第三步确认落盘。打开 AGENTS.md长期记忆条目区应该多了一条[M003] [约定] [高] [2024-xx-xx] 所有时间字段使用 UTC禁止本地时间注意它是追加的M001 和 M002 还在没有被重写。这就是增量写入。如果发现整个文件被重写了说明子智能体没遵守「只追加」护栏。第四步回读校验。这一步最关键因为记忆写进去不等于用得上。新起一个子智能体让它读 AGENTS.md 后回答「时间字段用什么时区」。它应该能答出 UTC。如果答不出可能是两个原因要么 AGENTS.md 没被正确读取要么子智能体的注册配置里 readable_files 没包含 AGENTS.md。回读校验可以用一次简单的模型请求完成请求走统一的 Base URLcurl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: 你的 Model ID, messages: [ {role: system, content: 你是子智能体请先阅读 AGENTS.md 的内容粘贴 AGENTS.md 全文}, {role: user, content: 时间字段用什么时区} ] }返回里如果出现 UTC说明记忆回读通了。这一步别省很多「记忆丢了」的问题其实不是没写进去而是没读出来。验证通过后建议再跑一轮冲突场景。比如用户改口说「时间字段改用本地时间」。这时 agents-memory-updater 应该按消解规则处理新条目和 M003 冲突置信度如果都是高就看更新时间新的胜但旧条目不删除只标记覆盖。检查 AGENTS.md 里 M003 是否被标记、新条目是否追加就能确认冲突消解逻辑真的在工作。5. 本篇常见错排查401、local proxy failed 与 OAuth配置和验证跑下来最容易卡在几个具体报错上。这一节按真实报错逐个排查每个都给定位思路和修法。第一个401 Unauthorized。这个最常见基本是 Key 的问题。先确认环境变量 TAOTOKEN_API_KEY 真的被设上了用echo $TAOTOKEN_API_KEY看一眼别是空的。如果环境变量没问题检查 AGENTS.md 和 subagents.toml 里引用的变量名是否一致——一个写 TAOTOKEN_API_KEY另一个写 TAOTOKEN_KEY就会读不到。还有一种情况是 Key 复制时带了空格或换行粘进去就废了重新生成一个干净的。401 的本质是认证没过和记忆逻辑无关先把调用层修好再谈闭环。第二个local proxy failed。这个报错通常出现在你本地配了某种转发但转发目标不可达。排查顺序先确认 Base URL 写的是 https://taotoken.net/api 没有多余路径、没有多余参数。然后确认本地没有残留的转发配置指向一个已经关掉的端口。如果你之前配过别的入口记得清掉只留一个。local proxy failed 往往不是服务端问题是本地配置打架。把 subagents.toml 里的 base_url 和 AGENTS.md 里的 Base URL 对齐两边都指向同一个干净地址问题一般就消了。第三个reading choices 相关报错。这类报错说明请求发出去了、也返回了但返回结构和你代码里解析的字段对不上。常见原因是 Model ID 填错或者返回体里 choices 字段的路径变了。先确认 Model ID 和你在模型对话页面里验证过的一致。然后打印完整返回体看一眼别只看 choices[0]有时候错误信息藏在顶层。如果是流式返回注意分块解析别把半截 JSON 当完整对象解析。这个错和记忆更新没直接关系但会卡住 agents-memory-updater 的判断流程因为它拿不到模型输出就没法挖转录。第四个OAuth 相关报错。如果你在配置里用了某种 OAuth 流程报错通常出在回调地址或 token 过期。先确认回调地址和你在控制台登记的一致差一个斜杠都可能失败。token 过期就重新走一遍授权。这里要提醒记忆更新子智能体用的是 API Key 方式不是 OAuth别把两套认证混在一起。如果你在 subagents.toml 里同时写了 api_key_env 和 OAuth 配置子智能体可能不知道该用哪个直接报错。二选一用 Key 就只写 Key。除了这四个还有一个隐蔽的坑AGENTS.md 写入成功但回读失败。这通常不是报错是静默失效。排查方法是手动把 AGENTS.md 全文粘进一次模型请求看模型能不能基于它回答。如果手动能答、自动不能答问题在子智能体的 readable_files 配置没把 AGENTS.md 加进去。如果手动也不能答说明 AGENTS.md 内容本身有问题比如格式乱了、条目被截断。排查时记住一个原则先分层再定位。调用层的问题401、local proxy failed先修认证和地址对了再谈记忆解析层的问题reading choices看返回结构记忆层的问题回读失败看文件读写权限。分层排查比一股脑改配置快得多。修完每个错都回到第 4 节的验证步骤重跑一遍确认闭环真的通了。6. 把记忆闭环用起来从验证到长期运行走到这里你已经有了 AGENTS.md 模板、触发规则、子智能体注册配置也跑通了落盘和回读验证还知道几个常见错怎么修。接下来就是让它长期跑。长期运行和一次性验证的区别在于记忆会越积越多冲突会越来越频繁子智能体的判断负担会变重。所以有几件事要提前想。第一定期清理低置信度条目。AGENTS.md 里的 [待人工确认] 标记不能一直堆着攒到一定数量就人工过一遍该合并的合并、该降级的降级。第二控制条目总量。如果长期记忆超过几百条子智能体读起来会吃力可以考虑按类别拆分文件但拆分后要在 AGENTS.md 里维护索引别让子智能体找不到。第三给冲突消解规则留升级空间。规则不是一成不变的跑一段时间后你会发现某些类别的冲突特别多那就针对那个类别加更细的规则。如果你要把这套东西接到编码类或 Agent 类工作流里Coding Plan 会更顺手https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。接入细节看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。需要新建 Key 就去 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。想先试模型行为就去模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。最后说一个我自己的经验持续学习系统最怕的不是记不住是记错了还一直用。所以每次调整触发规则或消解规则后都拿一轮真实任务重跑验证别只看配置文件写对了就放心。记忆这东西写进去容易用对难。把回读校验做成常规动作比事后排查省事得多。