Repository navigation
Agent Workflow v0.19.1
本版本是 v0.19.0 之后的修订版,累计 93 个提交。主线在长期记忆:补上了「执行结束」这条一直缺失的提炼信号源,并修掉了让记忆蒸馏静默失效一个多月的输出协议问题。
本版本有数据库迁移:SQLite 新增 0227–0229(端点 0226 → 0229);PostgreSQL 新增增量升级边 0003–0005,原地升级,不需要重做 cutover。
注意默认行为变化:新的「任务来源准入门」默认只让手工创建的任务产出候选记忆。定时 / webhook / 事件 / API 启动的任务,即使里面有人审、澄清或留言,默认也不再入队提炼。需要恢复旧行为请在设置页把对应来源勾上——详见文末「升级说明」。
主要更新
执行结束记忆提炼(RFC-366)
此前只有 clarify(澄清答复)、review(人审决定)、feedback(任务留言)三类信号会触发记忆提炼——全部是人类介入点。一个从头到尾没人审、没澄清、没人留言的任务(正是「跑得顺」的那种)在记忆库里等于没发生过,而平台绝大多数产出恰恰来自 agent 自己跑完的那一段。
- 新增两类信号源:
agent-run(每个 agent 节点达终态时各触发一次,loop 每轮、fanout 每分片、每次重试都算)与task-run(任务达终态时触发一次)。只有done/failed会提炼,canceled/interrupted/exhausted/skipped不提炼。 - 喂给蒸馏器的内容按源区分:
agent-run喂会话全文 transcript + 输出端口 + 本次运行已注入的记忆快照;task-run喂任务级摘要(名称 / 状态 / 耗时 / 失败节点 / 错误摘要 / 启动入参 / 各节点终态一览 / 最终输出),不重复搬运 transcript。两者都按字节预算裁剪并标注截断量。 - 任务来源准入门:按任务的启动来源(
launch_origin)白名单决定该任务的事件是否提炼,默认只放行manual。这条门统一管五类源——一个每小时跑一次的定时任务,此前只要中途有人审一次就会照常烧掉一次 LLM 调用,产出的同质候选会淹没人审队列。平台内部任务(数字员工 / 动作执行等用户在任务列表里看不到的执行)一律不提炼。 - 逐源开关:五类源各一个布尔,默认全开,与来源白名单正交——只想要人审沉淀、不想要 agent 过程沉淀时,关掉
agentRun/taskRun即可。 - 成本护栏:
agent-run用 60 秒去抖窗口(其余四类仍是 5 秒),一分钟内陆续结束的多个 agent 合并成一次蒸馏运行。 - 配置全部热读:改完即生效,不需要重启 daemon。设置页「记忆」卡片可配来源白名单、五个源开关与去抖窗口;
/memory的蒸馏任务列表可按agent-run/task-run筛选。 agent-run的候选 scope 收窄到本次结束的那个 agent(外加 workflow / repo / global),不会把一个 agent 的教训记到同任务的其他 agent 头上。
记忆蒸馏输出协议修复(RFC-367)
对本机 daemon 库的实测显示,记忆蒸馏已经静默失效一个多月:memory_distill_jobs 里 176 个 done 有 76 个零候选,有会话捕获的 10 个全部零候选——而这 10 个的捕获里全部含有完整、可用的候选 JSON。最后一条真正落库的候选停在 2026-07-17。
- 根因一:提示词从未给出完整字面语法。蒸馏器的系统提示词里一个尖括号都没有,
<port name="candidates">…</port>与</workflow-output>从未出现在任何提示词中。模型于是写出<wflow-output>/<wf-output>这类残标签,或把 JSON 裹进代码围栏。现在系统提示词内嵌 envelope → port → JSON 的三层嵌套字面示例,用户提示词尾部改用仓内公共协议块(worker 节点一直用的那一个)。 - 根因二:解析失败只 warn,任务照常完成。无 envelope / 无 candidates 端口 / JSON 非法三条失败路径全都是「记一条 warn 然后返回 0 条候选」,结果与「确实没有可蒸馏内容」完全同形:UI 绿、无错误、不退避、不重试。现在这些一律判协议失败——先在同一会话内补问(复用 worker 节点的补问文案与 runtime resume,最多 3 轮),补问预算用尽才让任务
failed并带上失败码与已试轮次,按既有指数退避重试。{"candidates": []}仍然是成功路径,与协议失败严格区分。 - 取数与会话记录同源:候选解析此前读的是子进程 stdout 的末尾 256KB(单行还受 1MiB 截断),而会话页读的是另一条事后走查路径——同一段模型输出有两个互不相同的 reader,历史上已经因此出过一次同型事故。现在蒸馏器迁到仓内的系统代理运行原语,候选解析与会话页渲染同源于一条规范化事件流:页面上能看到 envelope,就不可能解析不出候选。
- 附带收益:claude-code 运行时首次获得蒸馏会话捕获;stderr 行进入会话页。
- 历史数据不回收:此前 76 个零候选的 done 任务保持 done,不重跑、不回填。
记忆蒸馏超时默认值放宽
单次蒸馏的子进程超时默认值从 120 秒提到 1 小时,并在设置页明确标出可调(下限 30 秒、上限 6 小时)。原来的 120 秒对于喂了完整 transcript 的提炼任务经常不够用。
事件自动化目标拆分(RFC-365)
事件中心此前把规则归属、目标、投递 / 订阅和触发上下文一起交给一个启动端口,任务目标与数字员工目标的规则物化、启动和 receipt 归属混在同一个口子里。现在事件中心自己拥有规则选择、模板物化、持久化的来源 / 工作意图与投递结算,任务执行与数字员工各提供一个目标专属适配器、只返回自己的 receipt。
能力零收缩:四种目标、body / 外部 ID 接入、模板插值、现有权限与配置能力全部保留;任务输入不新增数量上限、文本预算不做转换或截断、数字员工的字段引用语法与首次准入时机不变;现有的去重、重试、错误与旧规则失效语义逐条冻结。
其他修复
/memory「按维度」的记忆卡片恢复纵向排列:记忆一多就横向堆积溢出屏幕。根因是分页 footer 的 CSS 规则被插进了一条共享规则的选择器列表中间,选择器列表在第一个{处终止,于是前两个列表被 footer 规则吞走、丢掉flex-direction: column退回横排。同样受影响的还有 agent / workflow / 仓库详情页的「记忆」子页签。
内部架构演进(RFC-360 ~ RFC-364)
这一批不改变用户可见行为,是按目标架构(RFC-294)推进的分层演进:运行时管理的用例迁到公共合同之后、运行时选择在 NodeRun 事务内冻结;执行契约的资源与脚本夹具改为注入;源码控制声明启动合同;MCP 诊断的策略与副作用分离。其中与稳定性相关的一条是 Task 的仓库准备改为先落持久化日志、再做工作区副作用——准备进度、源事实快照与补偿动作都有持久证据,daemon 重启后可以从证据恢复已准备好的 worktree,而不是留下一个说不清状态的中间态。
升级说明
- SQLite 新增迁移
0227–0229:分别是工作区准备日志(RFC-363)、提炼来源值域扩容(RFC-366)、事件自动化工作意图(RFC-365)。升级前建议备份数据库。 - PostgreSQL 新增增量升级边
0003–0005:与上面三条同构,原地应用,不需要重做 cutover(v0.19.0 起 PostgreSQL 已有不可变迁移历史与增量升级链)。 - 记忆提炼的默认覆盖面缩小了(RFC-366 能力影响清单 C1–C7,已确认):升级后,定时 / webhook / 事件 / API 启动的任务,其澄清答复、人审决定、任务留言默认都不再入队提炼——这三类此前是无条件入队的。要恢复旧行为,去设置页「记忆」卡片把对应来源加进任务来源白名单(改完即生效,不需要重启)。另外,定时任务里的留言在被准入门挡下时,接口返回的
distilled为false、distillJobId为null,UI 不再显示「已交付提炼」标记。平台内部任务一律不提炼,且没有开关可以恢复。 - 记忆蒸馏的失败现在是显性的:升级后如果蒸馏模型格式写不对,任务会变成红色的
failed并带上失败原因,而不是一个绿色的「0 条候选」。如果你的/memory → 蒸馏任务里突然出现失败行,说明这些任务此前一直在静默丢弃候选。 - 不要在升级后的数据库上直接回退旧二进制:需要降级时,请停机、换回旧版本,并恢复升级前的备份。
完整变更记录:v0.19.0...v0.19.1