AGENTS.md@src/host/agent · git:20260922.cf8e5a9 · 2026-09-22 · sha256 0c71cf136c540ae8
AGENTS.md@src/host/agent git:20260922.cf8e5a9A
Immutable. This exact content never changes and is served at /api/v1/blob/0c71cf136c540ae8.
# Agent Module Rules ## 适用范围 适用于 `src/host/agent/`。本文件定义 agent 模块特有的稳定治理边界;通用规范遵循根 `AGENTS.md`,测试规范遵循 `tests/AGENTS.md`。 本文件描述治理原则,不是源码结构说明。文件移动、重命名或内部重构后,只要职责、状态所有权、生命周期与依赖边界未变,本文件不随之修改。 ## 核心职责 治理「一个角色节点 ⇄ 一个可延续子代理」这一执行单元,并承担父代理会话能力的宿主适配: - 把节点配置(角色 Prompt、provider/model/思考强度、工具白名单、两开关、协作 Prompt)确定性翻译为官方子代理运行时的创建参数; - 创建/复用节点子代理,并把本轮任务块投递进去(创建即推理,不等待完成); - 在该子代理作用域内注入 Agent 语义(角色提示词段、工具可见性、模型选择、ReAct 软截停); - 为编排层与工具层提供父代理会话宿主能力(取根/子 Agent、followup、回合终态与会话事件读取、子代理存活判定)。 判断归属:该修改是否改变「节点 → 子代理」的创建/复用/投递/作用域装配语义,或改变本模块对官方 Agent / Subagent 能力的适配契约?若主要属于其他领域,应放到对应模块。 ## 非职责 - 不拥有 Workflow Run 与节点状态:运行锁、快照、节点完成/失败/react-capped 判定、阻塞等待唤醒均属编排运行时; - 不做 Agent 语义判断:是否重规划、是否汇报、是否改图、是否更换执行策略; - 不实现 Tool 注册、Schema、工具可见性协议与调用方身份派生; - 不直接读写工作流/运行持久化数据(可经注入的存储缝读取定义,写入归 storage); - 不管理官方 Agent / 子代理会话生命周期(创建与销毁由官方服务与宿主负责)。 ## 依赖边界 允许: - 官方能力仅经 `ctx.get()` / 注入缝**运行时解析**,并以本模块自带的最小结构守卫收窄;只允许 `import type` 官方纯类型(如 `Context`); - 编排模块仅允许**类型**导入其公共入口(`NodeRunner` / `AgentHost` / `NodeStartInput` 等契约缝);本模块不得成为编排器的运行时依赖; - 存储仅类型与读取缝;图模型仅纯函数事实推导;shared 仅共享类型与协议常量;Node 内置模块(fs / async_hooks)。 禁止: - 依赖 tools / api / service / scheduler / client(任何形式,含类型); - 新增 `@deepseek-ai/*` 运行时 import 或写入 `dependencies`; - 新增跨模块能力时绕过宿主注入、直接 import 其他模块的实现类型; - 让编排器或工具层直接持有本模块内部状态对象。 **官方适配必须可追溯**:改官方 seam 适配时,注释中必须写明包名与符号、取证结论(含版本差异)、失效或缺失时的降级路径与后果。不得凭记忆或推断编写官方契约。 ## 状态所有权 本模块拥有的状态: - 子代理复用表(复用键 → childId + 配置签名)与已创建 child 集合; - 软截停护栏的按 child 迭代上限、回合计数与已触达标记。 不属于本模块: - 子代理 Agent 与会话状态(官方);运行与节点状态(编排器); - **每子代理作用域装配的生命周期(安装与撤销)归宿主层**:本模块只提供「贡献」,由宿主在子代理创建窗口内安装、在子代理处置或宿主卸载时撤销。本模块不得自建第二套作用域撤销表。 规则: - 模块外只能经公开方法/事件请求变化,不得直接修改内部表; - 新增按 child / 会话维度持有的状态必须定义释放条件;生命周期长于「单次子代理运行」的表必须有明确上界与回收路径,不允许只增不减; - 同一事实只能有一个写入边界:子代理归属、迭代上限、软截停标记各自只有一处写入者。 ## 生命周期 执行单元生命周期:创建 → 复用派发 → 进行中(不等待)→ 结束/失败/中断 → 清理(宿主统一)。 必须保证: - **复用由配置签名决定**:签名必须覆盖一切影响子代理组成的输入(角色 Prompt 实际注入文本、provider/model/思考强度、工具清单、preset、两个提示词开关、协作 Prompt)。新增影响组成的配置而不纳入签名,等于旧子代理被静默复用。 - **首次创建必须注入完整任务块**作为首条 prompt,不得依赖后续消息补齐上下文。 - 创建/复用路径**不得等待子代理完成**;完成事实只经官方事件观察,由编排层回写。 - 任何影响「本回合第一个 pre-step」的登记(如迭代上限)必须在创建/派发**之前同步完成**,不得置于 `await` 之后。 - 中断是**尽力而为**:目标不存在或已停止视为成功;调用方不得依赖中断同步生效。 - **重建子代理时,旧子代理的处置语义必须明确**(保留/中断/归属回收),并在注释中说明其事件对节点结论的影响;不得让旧子代理的事件静默影响新子代理。 - 新增监听器、定时器、等待器、订阅必须有释放路径;清理必须幂等,且不得因单个取消失败而中断整体清理。 ## 并发与异步 - 子代理**创建/复用是跨 `await` 的 check-then-act**:当前正确性依赖调用方串行化(官方工具调度默认 exclusive + 运行锁)。一旦出现并发启动路径(并行工具调用、并发 API 请求、多宿主装配),必须在此处补进行中去重,并在成功/失败/取消路径清理登记。 - 去重、waiter 注册时机、事件先后假设都属隐含契约:新增必须在注释中写明「谁先谁后、失败怎么处理」。 - 不得依赖 `sleep` 或宏任务顺序保证正确性;若确实依赖官方事件顺序,必须写明取证结论。 - 取消信号必须沿创建/派发/中断传播;吞掉取消不得伪装成成功。 - 面向官方事件的守卫必须按结构判定并容忍未知形状(形状漂移时降级而非抛错),但**降级方向必须与业务语义一致**(例如存活判定失败保守视为仍在运行)。 ## 公共接口 - 对外契约有两类:节点执行能力(`NodeRunner`)与父代理会话宿主能力(`AgentHost`);实现由宿主装配,接口归编排模块。 - 修改公共契约必须同步检查:宿主装配点、测试夹具、编排模块的依赖缝。 - **面向模型的文本是对外契约**:软截停指令、工具拒绝原因、兜底任务 prompt、提示词段名与顺序都属契约文本,改动必须说明理由,不得出于措辞偏好调整。 - 注入官方消息流的任何内容必须满足官方消息契约(role / content / source 全字段合法),来源归属必须写真实插件名,不得缺字段。 - 工具白名单是对外安全边界:父代理专属工具的隐藏必须是「白名单永不包含 + 作用域显式拒绝」双线。 ## 副作用边界 允许的副作用:创建/派发/中断子代理、注册与撤销官方作用域贡献、读取角色 Prompt 文件、读取工作流定义(db-in 连线判定)、向官方消息流注入内容。 - IO 必须 best-effort 且有明确降级:角色 Prompt 文件不可读 → 回退内联文本;连线读取失败 → 按无连线处理;护栏工具拒绝线注册失败 → 保留消息替换线。 - 降级只能降在辅助路径上:环境缺失(服务不可用、父代理未激活、provider 缺失)必须抛可行动错误,不得静默变成「不带工具/不带护栏」的错误行为。 - 副作用不得隐藏在看似纯的函数中:复用键与签名构造、provider 选择、段过滤判定必须保持纯函数。 ## 纯函数边界 复用键、配置签名、provider 首选序、提示词段保留判定、软截停计步判定等确定性逻辑必须为纯函数:相同输入相同输出、不修改输入、不读全局可变状态与时间/文件/网络。 经注入的 view/store/service 求值逻辑(白名单解析、连线判定、事件流读取)不属于纯函数:它们不得直接 import 具体服务实现,只能消费注入的最小结构缝。 ## 错误处理 - 错误信息必须可行动:说明缺什么、当前状态、如何恢复(例如「请先在对话区发送一条消息后重试」)。 - 区分「运行语义失败」与「best-effort 辅助失败」:前者不得吞掉或伪装成功,后者必须有注释标注降级链。 - 护栏类失败不得静默失效:单线失效时另一线必须在(消息替换线失败仍保留工具拒绝线,反之亦然)。 - 官方 payload 形状漂移(版本升级)按运行时守卫收窄并降级,不因未知字段抛错;但**降级后仍必须保持业务语义**,且必须在注释中写下取证结论。 ## 模块内部组织 - 文件结构不是架构契约。禁止因文件长、函数多、import 多而拆分。 - 拆分依据只能是:职责、变化原因、依赖边界、测试边界(例如:官方服务契约适配 / 子代理执行与复用 / 声明式作用域注入 / 会话事件读取)。 - 不得创建 `utils.ts`、`helpers.ts`、`common.ts`、`shared.ts`、`misc.ts` 等无明确职责的聚合文件;跨职责共享的常量放 `shared/` 的协议契约。 - 不得通过继承层扩展职责;新增能力优先组合与最小接口注入。 ## 修改前检查清单 1. 改动属于「节点 → 子代理执行/官方适配」还是其他模块? 2. 是否改变复用签名的组成?签名与测试是否同步? 3. 是否改变作用域装配的安装/撤销或子代理归属?宿主层是否需要同步? 4. 是否改变面向模型的文本、工具白名单或官方消息 payload? 5. 是否新增按 child/会话维度的状态、监听器、定时器?释放路径在哪、上界是什么? 6. 是否引入新的官方能力依赖或版本分支?取证与降级是否写明? 7. 是否引入跨 `await` 的 check-then-act 或并发路径?去重策略是什么? ## 验证 至少执行: ```text pnpm typecheck pnpm test # 至少覆盖 tests/host/agent/ 与 tests/integration/ pnpm build # 涉及官方适配、宿主装配或产物契约时必需 ``` 同时确认:无旧路径残留、无新增反向/循环依赖、复用签名与作用域装配测试同步、无未声明行为变化、面向模型文本与白名单未意外改变。 ## 核心原则 1. 节点配置确定性映射为官方子代理调用。 2. 复用由签名决定,签名必须完整。 3. 作用域装配的生命周期归宿主,模块不私建撤销表。 4. 创建即推理、不等待完成,完成只经事件观察。 5. 官方能力零运行时类型依赖,适配必须取证可追溯。 6. 每子代理状态必须有释放条件与上界。 7. 重要副作用显式声明,best-effort 必须写明降级链。 8. 面向模型的文本、工具白名单与官方消息 payload 是对外契约。 9. 文件结构可重构,治理边界不可突破。