# 多 Agent 工程实施手册 版本:v0.2(环境适配版:新增 0.3 资源预算与单机运行限制 / 1.0 宿主与编排器层 / 2.1.4 无容器隔离降级路径) 配套流程文档:《多 Agent 协作流程设计文档》v2.4.4 状态:工程实施第一版 适用范围:Code 层、工具层、CI/CD、运行环境、插件拦截层 不适用范围:业务流程规则本身(流程规则以配套流程文档为准) --- ## 0. 手册定位 ### 0.1 与流程文档的边界 流程文档定义: - 什么阶段必须做什么 - 哪些动作必须人工审批 - 哪些边界不可突破 - 失败、验收、预算、重写的业务规则 本手册定义: - Code 层如何实现这些规则 - 状态如何持久化 - 并发如何隔离 - 插件如何硬拦截 - 测试如何验收 - 事故如何回滚 - 成本如何记账 冲突处理原则: 1. 流程文档的业务硬边界优先。 2. 本手册不得放宽流程文档中的硬规则。 3. 本手册可以增加更严格的工程保护。 4. 如果工程实现与流程语义冲突,必须暂停实现并提交人工裁定,不得静默改流程。 ### 0.2 工程总原则 1. **所有硬边界必须可测试**:不能只写在文档里,必须有回归用例。 2. **所有状态必须可恢复**:进程重启后不得导致重复派发、重复写入、重复部署。 3. **所有副作用必须可追踪**:写文件、执行命令、部署、迁移数据都必须有日志、哈希、回滚点。 4. **所有人工审批必须有时限**:不允许任务永久悬挂。 5. **所有规则尽量单一事实源**:可机器执行规则优先收敛到 `rules.json` 或等价配置。 --- ## 0.3 资源预算与单机运行限制 在低资源单机环境中,必须先声明资源预算,再决定并行度和任务类型。 典型低资源环境特征: 1. CPU 核心数 ≤ 2。 2. 可用内存 ≤ 1GB(本机实测:总内存 1.6GB,常态可用约 600MB)。 3. 无 swap 或 swap 不可依赖。 4. 无 Docker 或其他容器运行时(本机实测确认无)。 5. 本地磁盘有限。 在该类环境中必须启用单机保守模式: | 限制项 | 要求 | |---|---| | `max_workers` | 硬上限 ≤ 2,默认建议 1 | | 并行条件 | 仅允许轻量任务并行 | | 编译 | 不得本地并行,优先提交 CI | | 完整测试 | 不得本地并行,优先提交 CI | | 打包 / 构建 | 不得本地并行 | | 依赖安装 | 必须串行,并加锁 | | 容器构建 | 无容器环境禁止 | | 数据迁移 | 必须串行,并提前备份 | | 浏览器 / UI 测试 | 禁止 headed 实例与多实例并行;允许**单实例 headless** 轻量抓取与截图(本机实测:headless 稳定可用,headed 会导致 daemon 无响应) | 轻量任务定义: 1. 文本生成。 2. 代码阅读。 3. 小规模 diff。 4. Reviewer 验收。 5. 文档整理。 6. 日志摘要。 7. 不涉及重型编译或大量 I/O 的任务。 重活定义: 1. 编译。 2. 完整测试套件。 3. 打包。 4. 依赖安装。 5. 容器构建。 6. 数据库迁移。 7. 大文件处理。 8. 高内存工具调用。 9. 多进程并行测试。 派发前必须进行资源预检: 1. 可用内存。 2. 可用磁盘。 3. 当前负载。 4. 端口占用。 5. 是否已有重型任务运行。 6. 是否超过 `max_workers`。 资源不足时: 1. 不得启动新 worker。 2. 任务状态置为 `blocked` 或 `paused`。 3. 记录阻塞原因。 4. 已运行任务应先保存现场,再暂停或终止。 5. 不得因资源不足直接静默失败。 验收标准: 1. 在约 600MB 可用内存下,并行轻量任务不应触发 OOM。 2. 编译、完整测试、打包等重活不会在本地并行执行。 3. 超过 `max_workers` 时,新任务被阻塞而不是启动。 4. 资源不足时有明确日志和状态。 5. 重活被路由到 CI 或串行队列。 --- # 第一章 状态机与持久化 ## 1.0 宿主与编排器层 本手册默认存在一个长期运行的宿主编排器。编排器不是聊天会话,也不是短生命周期子代理,而是常驻进程或等价守护进程。 宿主形态选择: | 优先级 | 形态 | 说明 | |---|---|---| | 首选 | systemd user service | 本机现状:systemd 249(Ubuntu 22.04),已在运行 4 个 Hermes 相关 unit(gateway / apk-server / tailnet-proxy / public-proxy),编排器直接作为第 5 个 unit 加入即可 | | 备选 | supervisor / pm2 / runit | 非 systemd 环境使用 | | 最低级 | cron + wrapper | 仅适合批处理任务,不支持长驻状态 | ⚠️ 已知环境约束:systemd 249 不支持 `OOMPolicy` 等较新属性——unit 文件或 `systemd-run` 中写了会直接报 "Unknown assignment"(曾导致定时任务 worker 整体不可用)。编写 unit 时应避开新版本专有属性。 编排器必须持有并管理以下内容: 1. SQLite 或其他持久化状态库。 2. 任务状态机。 3. 文件锁、资源锁、环境锁。 4. 预算计数与熔断状态。 5. worktree / 临时工作区生命周期。 6. 工具调用日志与产物 manifest。 7. `rules.json` 或等价规则版本。 8. Checkpoint 审批状态与超时计时。 LLM 会话、子代理、delegate、临时 shell 进程都属于短生命周期执行器。它们退出、被 `/new`、被 `/stop`、崩溃或重启时,不得导致任务状态丢失。 强制要求: 1. 所有关键状态必须在每次状态迁移后落盘。 2. 子代理不得作为长期状态存储。 3. 聊天上下文不得作为任务恢复依据。 4. 每个任务必须使用独立 worktree 或独立临时工作区。 5. 编排器重启后必须从 DB 恢复到最近稳定检查点。 6. 子代理丢失时,任务状态应置为 `paused`、`needs_recovery` 或 `blocked`,不得静默消失。 禁止事项: 1. 禁止依赖“子代理还记得任务”继续执行。 2. 禁止把 `/new` 后的会话当作原任务延续。 3. 禁止用人工记忆或聊天历史替代 SQLite 状态。 4. 禁止多个任务共享同一 worktree。 5. 禁止编排器退出后未保存锁、预算和任务状态。 验收标准: 1. 杀死编排器进程后重启,可恢复任务状态。 2. 杀死子代理后,任务不会丢失,只进入可恢复状态。 3. `/new` 或 `/stop` 后,任务状态仍可从 DB 查询。 4. 两个并行任务不会写入同一 worktree。 5. 编排器重启不会重复派发已派发的非幂等操作。 --- ## 1.1 端到端任务状态机 ### 1.1.1 状态实体 至少需要五类实体: | 实体 | 说明 | |---|---| | Task | 一次完整多 Agent 任务 | | Module | Phase 2 切出的模块 | | WorkerRun | 一次 worker 执行 | | Review | 一次 reviewer 验收 | | Checkpoint | 人工审批节点 | ### 1.1.2 Task 生命周期状态 ```text created phase_minus_1 phase_0 phase_1 phase_2 phase_3 phase_4 phase_5 phase_6 blocked checkpoint_pending paused_for_budget circuit_broken escape_compromise escape_advisor escape_bypass controlled_rewrite failed passed delivered cancelled aborted archived ``` ### 1.1.3 状态迁移要求 每次状态迁移必须记录: ```json { "entity_type": "task | module | worker_run | review", "entity_id": "string", "from_state": "string", "to_state": "string", "reason_code": "string", "actor": "code | orchestrator | human | plugin", "timestamp": "ISO8601", "evidence_uri": "string | null" } ``` ### 1.1.4 关键迁移规则 | 当前状态 | 可迁移到 | 条件 | |---|---|---| | created | phase_minus_1 | 任务登记完成 | | phase_minus_1 | phase_0 | 三问通过 | | phase_minus_1 | cancelled | 任一三问不通过 | | phase_2 | checkpoint_pending | 切分完成,等待 Checkpoint ① | | checkpoint_pending | phase_3 | 人工批准 | | checkpoint_pending | phase_2 | 人工拒绝 | | phase_5 | escape_compromise | L2 首次漂移且非高危域 | | phase_5 | escape_advisor | L2 顾问或高危域漂移 | | phase_5 | controlled_rewrite | L3 人工批准 | | running | paused_for_budget | 单任务超预算 120% | | running | circuit_broken | 全局预算池耗尽 | | paused_for_budget | running | 人工批准或预算追加 | | circuit_broken | archived | 人工确认收尾 | | passed | delivered | Phase 6 通过且产物完整 | | delivered | archived | 交付归档 | ### 1.1.5 禁止事项 1. 禁止从失败状态直接跳到交付状态。 2. 禁止绕过 `checkpoint_pending` 直接进入下一阶段。 3. 禁止人工或 LLM 直接修改状态机枚举。 4. 禁止状态迁移无日志。 5. 禁止同一实体同时存在两个互斥状态。 --- ## 1.2 SQLite / DB 持久化与幂等 ### 1.2.1 持久化最小表 至少包含: | 表 | 作用 | |---|---| | tasks | 任务主状态 | | modules | 模块状态 | | worker_runs | worker 执行记录 | | reviews | reviewer 结果 | | checkpoints | 人工审批 | | budget_events | 预算事件 | | tool_calls | 工具调用记录 | | artifacts | 产物清单 | | locks | 文件/资源锁 | | debt_records | 技术债 | | cost_ledger | 成本账本 | | rule_versions | 规则版本 | ### 1.2.2 幂等键 所有副作用操作必须带幂等键: ```text idempotency_key = task_id:phase:module_id:attempt:operation_type:operation_hash ``` 示例: ```text task_123:phase4:M3b:attempt2:write_file:a1b2c3 ``` ### 1.2.3 重启恢复规则 进程重启后: 1. 读取最近一个稳定检查点。 2. 不得自动重放未确认副作用。 3. 对已执行一半的副作用必须进入 `needs_recovery`。 4. 可安全重跑的操作需显式标记 `idempotent=true`。 5. 不可幂等操作必须有补偿方案或人工审批。 ### 1.2.4 租约机制 每个运行中 worker 必须有租约: ```json { "worker_id": "string", "task_id": "string", "lease_expires_at": "ISO8601", "heartbeat_interval_seconds": 15 } ``` 规则: 1. 租约过期视为异常退出。 2. 过期后不得立即释放写锁,必须先检查工作区。 3. 强制释放必须记录审计日志。 --- ## 1.3 文件锁与资源锁 ### 1.3.1 锁对象 锁不能只覆盖文件,必须覆盖五类对象: | 锁类型 | 示例 | |---|---| | file | `src/auth/token-service/*` | | resource | 数据库、端口、容器、缓存 | | contract | 同一契约条目 | | data | 共享数据集、迁移目标表 | | environment | 共享测试环境 | ### 1.3.2 锁模式 | 模式 | 含义 | |---|---| | read | 多个任务可同时读 | | write | 独占写 | | intent_write | 准备写入,阻止新读锁 | | advisory | 建议锁,用于提示领导 | | hard | Code 层物理互斥 | ### 1.3.3 锁生命周期 锁的生命周期必须显式定义: ```text 申请 → 获取 → 续租 → 释放 / 超时回收 / 崩溃回收 ``` ### 1.3.4 崩溃回收 1. worker 崩溃后,锁不得永久保留。 2. 回收前必须保存现场。 3. 回收后必须通知领导进程。 4. 如果锁涉及写操作,必须检查工作区是否半完成。 ### 1.3.5 死锁检测 1. 必须维护锁等待图。 2. 超过 60 秒未获取锁应告警。 3. 超过 300 秒应触发人工或自动降级串行。 4. 自动解锁必须记录原因。 --- ## 1.4 进程被 kill 前的成果保全 ### 1.4.1 触发场景 包括: 1. 工具调用超限。 2. 预算熔断。 3. 手动取消。 4. 系统资源不足。 5. 安全插件阻断。 ### 1.4.2 保全动作 被终止前必须尽量完成: 1. 保存当前 workspace patch 或 git diff。 2. 保存工具调用日志。 3. 保存最后一条模型输出。 4. 释放或标记锁。 5. 写入 `termination_manifest`。 ### 1.4.3 termination_manifest ```json { "task_id": "string", "worker_id": "string", "reason": "tool_limit | budget | cancel | security_block | crash", "uncommitted_changes_path": "string | null", "lock_state": "released | needs_review", "partial_artifacts": ["string"], "resume_allowed": false, "timestamp": "ISO8601" } ``` ### 1.4.4 恢复规则 1. 默认不允许自动续跑。 2. 若允许续跑,必须通过幂等检查。 3. 有未完成写操作时必须人工确认。 --- ## 1.5 流程版本迁移 ### 1.5.1 版本绑定 每个任务启动时必须绑定: ```json { "process_doc_version": "v2.4.4", "engineering_manual_version": "v0.1", "rules_version": "rules@2026-xx-xx", "prompt_version": "string", "contract_version": "string", "db_schema_version": "string" } ``` ### 1.5.2 升级策略 | 场景 | 策略 | |---|---| | 新任务 | 使用新版本 | | 运行中任务 | 默认锁定旧版本 | | 安全漏洞修复 | 可强制升级,但需人工批准 | | DB schema 变更 | 必须写迁移脚本 | | prompt 变更 | 必须过回归测试集 | | rules.json 变更 | 必须过插件回归用例 | ### 1.5.3 旧任务兼容 1. 旧任务必须能按旧版本状态机恢复。 2. 如果旧版本无法恢复,必须转人工。 3. 不得静默用新规则恢复旧任务。 --- # 第二章 验证与测试工程 ## 2.1 测试环境隔离 ### 2.1.1 隔离原则 并行任务不得共享可变环境。 必须隔离: 1. 文件系统工作区。 2. 数据库实例或 schema。 3. 端口。 4. 缓存。 5. 对象存储路径。 6. 测试容器。 7. 环境变量。 8. 临时密钥。 ### 2.1.2 最小隔离方案 | 等级 | 方案 | |---|---| | 最低 | 独立临时目录 + 独立 SQLite 文件 | | 中等 | 独立 Docker 容器 + 独立数据库 schema | | 推荐 | 独立容器 + 独立端口 + 独立卷 + 独立网络命名空间 | ### 2.1.3 清理 任务结束后必须清理: 1. 临时目录。 2. 测试数据库。 3. 端口占用。 4. 后台进程。 5. 未释放锁。 6. 临时凭据。 --- ### 2.1.4 无容器隔离降级路径 当运行环境没有 Docker、Podman 或其他容器运行时,隔离不能直接失败,必须降级为轻量隔离档。 隔离档位分为两档: | 档位 | 适用环境 | 隔离方式 | |---|---|---| | 容器档 | 有 Docker / Podman / 等价容器运行时 | 独立容器、独立卷、独立端口、独立网络命名空间 | | 轻量档 | 无容器运行时,或低内存单机 | 独立 worktree、独立临时目录、独立端口、独立 SQLite 文件 | 轻量档最低要求: 1. 每个任务独立 `git worktree`;**任务目录不是 git 仓库时,退回独立临时目录档**。 2. 每个任务独立 SQLite 文件或独立数据库文件名。 3. 每个任务独立端口或端口范围。 4. 每个任务独立环境变量文件。 5. 每个任务独立缓存目录。 6. 每个任务独立日志目录。 7. 每个任务独立锁文件或锁命名空间。 8. 每个任务独立产物目录。 轻量档禁止共享: 1. 同一个 SQLite 文件。 2. 同一个构建目录。 3. 同一个依赖缓存目录。 4. 同一个端口。 5. 同一个浏览器实例。 6. 同一个本地服务进程。 7. 同一个临时 HOME。 8. 同一个 worktree。 轻量档限制: 1. 不适合并行运行重型编译。 2. 不适合并行运行完整测试套件。 3. 不适合并行运行数据库迁移。 4. 不适合并行启动多个长驻服务。 5. 重活必须走 CI、远程执行器或串行队列。 轻量档清理要求: 1. 任务结束后删除临时目录。 2. 释放端口。 3. 关闭子进程。 4. 删除或归档临时 SQLite 文件。 5. 清理锁文件。 6. 保留必要日志与产物 manifest。 验收标准: 1. 两个并行任务的文件路径无交集。 2. 两个并行任务不会争抢同一端口。 3. 一个任务崩溃后,另一个任务不受污染。 4. 清理脚本可删除任务残留。 5. 无容器环境下仍能完成轻量任务的隔离执行。 --- ## 2.2 Flaky 测试处理 ### 2.2.1 判定 | 现象 | 判定 | |---|---| | 首次失败,自动重跑通过 | 疑似 flaky | | 同一测试 3 次中随机失败 | 标记 flaky | | 连续失败且指纹稳定 | 不计 flaky,进入失败流程 | | 环境类错误 | 走环境重试,不直接判测试缺陷 | ### 2.2.2 处理 1. 疑似 flaky 测试不得直接导致验收失败。 2. 必须自动重跑一次。 3. 重跑通过后进入 `flaky_quarantine`。 4. 被隔离测试不得计入正式通过率。 5. 被隔离测试必须记录负责人和关闭期限。 ### 2.2.3 禁止事项 1. 禁止把真实失败伪装成 flaky。 2. 禁止无限重跑直到通过。 3. 禁止 reviewer 手动忽略失败测试。 --- ## 2.3 行为契约统一执行器 ### 2.3.1 目标 行为层契约不能只说“写成 CI 测试”,必须有统一入口。 ### 2.3.2 执行器输入 ```json { "contract_version": "string", "contract_entries": ["access_token.ttl_seconds", "refresh_token.rotation"], "target_module": "string", "environment_image": "string", "timeout_seconds": 600, "test_suite_uri": "string" } ``` ### 2.3.3 执行器输出 ```json { "status": "passed | failed | timeout | environment_error", "results": [ { "contract_entry": "string", "passed": true, "evidence_uri": "string", "failure_fingerprint": "string | null" } ] } ``` ### 2.3.4 失败归属 | 错误类型 | 归属 | |---|---| | 测试环境启动失败 | 环境类 | | 契约测试生成错误 | 契约/生成器 | | 新实现违反契约 | 实现方 | | 契约本身有误 | Checkpoint ③ | --- ## 2.4 Phase 1 搜索完成标准 ### 2.4.1 目标 “确认没有”必须有完成标准,不能靠感觉。 ### 2.4.2 必查来源 至少包括: 1. 当前代码仓库。 2. 当前依赖树。 3. 内部知识库/文档。 4. 公开包管理器。 5. 已知参考仓库。 6. 开源搜索引擎或代码搜索。 ### 2.4.3 查询要求 | 项 | 要求 | |---|---| | 关键词变体 | 至少 5 个 | | 同义词 | 至少 2 组 | | 时间范围 | 按项目定义,默认近 3 年 | | 许可初筛 | 必须记录 | | 失败原因 | 若存在但不适配,必须记录 | ### 2.4.4 停止条件 满足以下之一可停止: 1. 找到可直接用/参考改写候选。 2. 时间盒到期,转“未完成/超时”。 3. 所有必查来源均已查询且无候选。 4. 人工批准提前停止。 ### 2.4.5 禁止事项 1. 时间盒超时不得直接判“确认没有”。 2. 验证失败不得降级为“确认没有”。 3. 搜索记录不得缺 `search_trace`。 --- ## 2.5 双 Reviewer 隔离 ### 2.5.1 独立性要求 双 Reviewer 不得共享以下内容: 1. 对方输出。 2. 对方评分。 3. 对方证据链。 4. 同一轮领导总结。 5. 相同随机种子下的相同提示顺序。 ### 2.5.2 推荐配置 | 条件 | 推荐 | |---|---| | 模型 | 尽量不同模型或不同档位 | | 提示 | 相同评审规则,但不同表达模板 | | 顺序 | 随机 | | 温度 | 低温度 | | 上下文 | 只给验收所需切片 | ### 2.5.3 相关性控制 1. 如果两个 reviewer 长期 100% 一致,必须抽检。 2. 如果所有分歧都被同一方发现,需要检查另一方是否能力不足。 3. 必须记录两个 reviewer 的模型版本和 prompt 版本。 --- ## 2.6 复用候选适配矩阵 ### 2.6.1 适用场景 Phase 1 中候选结论为: 1. 直接可用。 2. 参考改写。 3. 存在但不适配。 ### 2.6.2 适配矩阵 | 维度 | 检查项 | 证据 | |---|---|---| | 功能 | 是否覆盖目标能力 | 冒烟测试 | | 许可 | 是否兼容商用/闭源 | 许可证文本 | | 依赖 | 是否引入冲突依赖 | 依赖树 | | 安全 | 是否有已知漏洞 | 扫描报告 | | 性能 | 是否满足预算 | 基准测试 | | 维护 | 是否活跃 | 提交记录 | | 测试 | 原仓库测试是否可复现 | 测试日志 | | 验收 | 是否覆盖我方验收子集 | 验收 ID 映射 | ### 2.6.3 结论规则 1. 原仓库测试通过只是证据之一。 2. 许可不兼容直接判 `exists_but_incompatible`。 3. 安全高危漏洞未修复直接判 `exists_but_incompatible`。 4. 无法复现测试走豁免审批,不得直接判失败。 --- ## 2.7 指纹标定统计要求 ### 2.7.1 样本来源 标定不能只用人工注入样本,必须混合: | 类型 | 比例建议 | |---|---| | 人工注入故障 | 30% | | 历史真实失败 | 50% | | 跨模块复杂故障 | 20% | ### 2.7.2 最低样本量 1. 起步标定:至少 30 个样本。 2. 正式上线前:至少 100 个样本。 3. 每个故障类别至少 20 个样本。 ### 2.7.3 输出要求 必须输出: 1. 混淆矩阵。 2. 准确率。 3. 召回率。 4. 误聚率。 5. 漂移误判率。 6. 95% 置信区间。 ### 2.7.4 调参规则 1. 不得只看准确率就调指纹。 2. 卡死 L1 出现时必须优先查粒度过粗。 3. 直冲 L3 升高时必须查粒度过细、任务不适配、环境不稳定。 4. 每次调参必须保留旧规则版本以便回滚。 --- # 第三章 安全、风险与合规 ## 3.1 妥协模式风险分级 ### 3.1.1 风险等级 | 等级 | 含义 | 是否允许默认妥协 | |---|---|---| | low | 不影响安全/数据/资金 | 允许 | | medium | 影响维护性或非核心行为 | 允许,但必须登记 | | high | 影响认证、权限、数据一致性 | 禁止默认妥协 | | critical | 影响支付、生产配置、隐私、不可逆操作 | 禁止妥协,直接人工 | ### 3.1.2 高危域禁用清单 以下模块禁止默认落妥协模式: 1. 认证。 2. 授权。 3. 支付。 4. 数据迁移。 5. 生产配置。 6. 密钥管理。 7. 审计日志。 8. 回滚脚本。 9. 隐私数据处理。 10. 安全中间件。 ### 3.1.3 高危域处理 高危域出现指纹漂移: ```text 默认不进入妥协模式 → 进入 L2 顾问或升级 L3 ``` --- ## 3.2 技术债闭环 ### 3.2.1 技术债记录字段 ```json { "debt_id": "string", "module_path": "string", "task_id": "string", "owner": "string", "created_at": "ISO8601", "due_date": "date", "risk_level": "low | medium | high | critical", "ticket_id": "string", "status": "open | in_progress | closed | waived", "blocking_rewrite": true } ``` ### 3.2.2 阻断规则 1. 未关闭技术债可阻断该模块进入受控重写。 2. 高风险以上技术债必须阻断新增功能。 3. 逾期技术债必须升级人工。 4. 豁免必须记录批准人和有效期。 --- ## 3.3 密钥治理 ### 3.3.1 基本原则 1. 禁止长期密钥直接注入 worker。 2. 禁止密钥出现在日志、摘要、错误信息中。 3. 禁止密钥写入普通产物目录。 4. 优先使用临时凭据。 5. 最小权限原则。 ### 3.3.2 注入方式 | 场景 | 推荐 | |---|---| | 本地测试 | 临时环境变量 + 自动过期 | | 云服务 | 短期 token | | 数据库 | 只读账号或限定 schema | | 部署 | 专用部署身份 | ### 3.3.3 审计 每次密钥使用必须记录: 1. 任务 ID。 2. worker ID。 3. 权限范围。 4. 使用时间。 5. 是否产生副作用。 --- ## 3.4 高风险操作审批 ### 3.4.1 高风险操作清单 1. 删除数据。 2. 修改生产配置。 3. 发布生产。 4. 修改权限。 5. 迁移生产数据。 6. 销毁环境。 7. 修改密钥。 8. 修改契约并重新冻结。 9. 强制解锁。 10. 跳过验收。 ### 3.4.2 审批要求 | 操作 | 要求 | |---|---| | 生产发布 | 人工批准 + 回滚点 | | 数据删除 | 人工批准 + 备份 | | 权限变更 | 人工批准 + 审计 | | 配置变更 | dry-run + 人工批准 | | 强制解锁 | 人工批准 + 现场保存 | ### 3.4.3 禁止事项 1. 禁止 LLM 自行批准高风险操作。 2. 禁止无 dry-run 直接执行生产变更。 3. 禁止无回滚点部署。 --- ## 3.5 供应链与许可证 ### 3.5.1 许可证策略 | 类别 | 处理 | |---|---| | MIT / Apache-2.0 / BSD | 通常可用 | | GPL / AGPL | 必须人工审批 | | 未知许可 | 禁止采用 | | 无许可证 | 禁止采用 | | 商业组件 | 按采购流程 | ### 3.5.2 依赖检查 每个外部依赖必须检查: 1. 许可证。 2. 最近更新时间。 3. 已知漏洞。 4. 维护者可信度。 5. 是否与现有依赖冲突。 ### 3.5.3 采用记录 所有采用代码必须记录: ```json { "source": "url", "license": "string", "commit": "string", "security_scan": "string", "approval": "auto | human", "used_in": ["path"] } ``` --- ## 3.6 日志脱敏与保留 ### 3.6.1 日志分级 | 级别 | 内容 | 访问 | |---|---|---| | public | 指标、状态 | 项目组 | | internal | 普通日志 | 开发 | | sensitive | 含用户数据/密钥片段 | 受限 | | audit | 人工审批/安全事件 | 审计 | ### 3.6.2 脱敏规则 必须脱敏: 1. API key。 2. token。 3. 密码。 4. 私钥。 5. 用户手机号。 6. 邮箱。 7. 身份证号。 8. 数据库连接串。 9. 云凭据。 ### 3.6.3 保留期 | 日志类型 | 建议保留 | |---|---| | 普通运行日志 | 30 天 | | 审计日志 | 180 天以上 | | 安全事件 | 365 天以上 | | 任务产物日志 | 随任务归档 | --- # 第四章 交付工程 ## 4.1 契约版本兼容策略 ### 4.1.1 版本号 契约必须使用语义化版本: ```text major.minor.patch ``` ### 4.1.2 兼容规则 | 变更 | 版本变化 | 处理 | |---|---|---| | 新增可选字段 | minor | 向后兼容 | | 修改字段类型 | major | 不兼容 | | 删除字段 | major | 不兼容 | | 修改枚举值含义 | major | 不兼容 | | 修改行为约束 | minor/major | 按影响判断 | ### 4.1.3 锁定规则 1. 每个任务必须锁定契约版本。 2. 跨批次模块必须使用同一契约版本。 3. 契约升级不得自动影响运行中任务。 4. 不兼容升级必须走 Checkpoint ③。 --- ## 4.2 分支 / Worktree 与合并策略 ### 4.2.1 工作区 每个模块必须有独立工作区: ```text workspaces/task_id/module_id/ ``` 推荐使用: 1. `git worktree` 2. 独立分支 3. 独立临时目录 4. 独立构建产物目录 ### 4.2.2 分支命名 ```text task/{task_id}/{module_id} ``` ### 4.2.3 提交粒度 每个提交必须满足: 1. 只属于一个模块。 2. 可独立回滚。 3. 有对应任务 ID。 4. 有对应验收项 ID。 ### 4.2.4 合并顺序 1. 先合并无依赖模块。 2. 再合并下游模块。 3. 契约相关模块必须通过类型层和行为层检查。 4. 冲突必须由明确 owner 处理。 ### 4.2.5 合并失败 1. 保留原分支。 2. 不得强推。 3. 必须记录失败原因。 4. 可回滚到合并前检查点。 --- ## 4.3 常规交付回滚 ### 4.3.1 回滚点 每次副作用前必须创建回滚点: | 操作 | 回滚点 | |---|---| | 代码合并 | commit hash | | 数据库迁移 | migration version + backup | | 部署 | image tag / release id | | 配置变更 | config snapshot | | 数据清洗 | 原始快照或反向补丁 | ### 4.3.2 回滚要求 1. 每个部署必须有回滚命令或步骤。 2. 数据迁移必须有备份或补偿脚本。 3. 配置变更必须能一键恢复。 4. 回滚必须演练过一次,或至少有明确验证步骤。 --- ## 4.4 数据迁移一致性 ### 4.4.1 迁移协议 数据迁移必须包含: 1. 事务边界。 2. 批次大小。 3. 校验和。 4. 断点。 5. 重放策略。 6. 回滚策略。 7. 隐私处理。 ### 4.4.2 推荐流程 ```text 备份 → 干跑 → 小批迁移 → 校验 → 全量迁移 → 二次校验 → 观察期 → 完成 ``` ### 4.4.3 校验项 | 校验 | 说明 | |---|---| | 行数 | 源/目标行数一致或可解释 | | 主键 | 无重复 | | 外键 | 引用完整 | | 校验和 | 关键字段一致 | | 空值 | 非空约束满足 | | 枚举 | 值合法 | ### 4.4.4 禁止事项 1. 禁止无备份迁移。 2. 禁止不可回放的迁移脚本。 3. 禁止迁移中途静默改字段映射。 4. 禁止生产数据直接给普通 worker。 --- ## 4.5 非 Token 成本账本 ### 4.5.1 成本项 | 成本项 | 说明 | |---|---| | token | 模型调用 | | tool_call | 工具调用次数 | | ci_time | CI/测试时间 | | cloud_resource | 容器/云资源 | | human_review | 人工审批/评审 | | waiting | 等待人工或环境的时间 | | storage | 产物存储 | ### 4.5.2 记账事件 ```json { "cost_id": "uuid", "task_id": "string", "phase": "string", "module_id": "string | null", "cost_type": "token | tool_call | ci_time | cloud_resource | human_review | waiting | storage", "amount": 0, "unit": "string", "unit_price": 0, "total": 0, "timestamp": "ISO8601" } ``` ### 4.5.3 ROI 实测 结案实测 ROI 必须使用: ```text 实际人工节省收益 ÷ 实际总成本 ``` 实际总成本包括: 1. 实际 token。 2. 工具调用。 3. 云资源。 4. CI 时间。 5. 人工评审。 6. 等待成本。 不得继续使用立项预估分母。 --- ## 4.6 产物 Manifest 与哈希 ### 4.6.1 每个交付任务必须有 manifest ```json { "task_id": "string", "created_at": "ISO8601", "process_doc_version": "string", "contract_version": "string", "artifacts": [ { "path": "string", "sha256": "string", "kind": "code | doc | log | config | migration | rollback_plan", "source": "worker | ci | human", "required": true } ], "test_reports": ["uri"], "review_verdicts": ["uri"], "checkpoint_approvals": ["uri"] } ``` ### 4.6.2 校验规则 1. 摘要必须能从落盘文件重新计算哈希。 2. 领导只看摘要时,必须能追溯到完整产物。 3. 缺少必要产物不得进入 `delivered`。 4. manifest 必须归档。 --- ## 4.7 取消、暂停与优先级 ### 4.7.1 操作定义 | 操作 | 含义 | |---|---| | cancel | 终止任务,不再继续 | | pause | 暂停任务,可恢复 | | resume | 恢复任务 | | preempt | 高优先级任务抢占资源 | ### 4.7.2 安全终止流程 1. 停止派发新任务。 2. 等待运行中工具调用进入安全点。 3. 保存现场。 4. 释放锁。 5. 写入终止原因。 6. 对已产生副作用检查回滚。 ### 4.7.3 优先级规则 1. 生产事故修复优先。 2. 安全修复优先。 3. 已完成大半的任务不轻易抢占。 4. 抢占必须记录成本损失。 5. 抢占不得导致静默丢失产物。 --- ## 4.8 行为契约 DSL 与生成边界 ### 4.8.1 能力边界 契约自动生成适合: 1. 类型结构。 2. 字段必填性。 3. 枚举范围。 4. 基本请求/响应格式。 5. 简单数值范围。 不完全适合: 1. 幂等性。 2. 轮换语义。 3. 安全语义。 4. 状态机。 5. 跨服务事务。 6. 性能约束。 7. 复杂业务时序。 ### 4.8.2 人工审核 以下行为契约必须人工审核: 1. 认证。 2. 授权。 3. 支付。 4. 数据迁移。 5. 回滚。 6. 审计。 7. 任何不可逆操作。 ### 4.8.3 禁止事项 1. 禁止声称行为契约完全自动生成。 2. 禁止未审核的行为契约直接进入生产验收。 3. 禁止手写替代白测试而不记录豁免。 --- # 第五章 变更控制 ## 5.1 验收清单变更控制 ### 5.1.1 变更触发 以下情况可触发验收清单变更: 1. Phase 0 需求写错。 2. 发现遗漏验收项。 3. 契约变更。 4. 法规/安全要求变化。 5. 人工审批要求补充。 ### 5.1.2 变更流程 ```text 提出变更 → 影响分析 → 人工审批 → 版本号递增 → 重新覆盖性 diff → 重验受影响模块 ``` ### 5.1.3 影响分析必须包含 1. 哪些 brief 受影响。 2. 哪些模块需要重验。 3. 哪些契约条目受影响。 4. 预算是否变化。 5. 是否需要重新 Checkpoint ①。 ### 5.1.4 禁止事项 1. 禁止执行中静默追加验收项。 2. 禁止删除验收项不留审计。 3. 禁止已派发 brief 自动继承新验收清单。 4. 禁止变更验收清单不递增版本。 --- # 第六章 规则单一事实源与插件硬拦截 本章对应框架级第 4 项的工程落地: 将可执行硬规则收敛为版本化规则文件,并通过插件层执行 `approve / modify / block`。 ## 6.1 单一事实源目标 以下规则必须逐步从文档、prompt、代码三处重复,收敛到一个机器可读规则源: 1. `max_workers` 2. `max_tool_calls_per_worker` 3. `token_fuse_ratio` 4. `brief_rewrite_auto_limit` 5. `brief_rewrite_total_limit` 6. `environment_retry_backoff` 7. `checkpoint_timeout_actions` 8. `forbidden_commands` 9. `high_risk_domains` 10. `budget_borrow_limit_ratio` ## 6.2 rules.json 最小结构 ```json { "version": "rules@2026-xx-xx", "hard_limits": { "max_workers": 3, "max_tool_calls_per_worker": 15, "token_fuse_ratio": 1.2, "brief_rewrite_auto_limit": 1, "brief_rewrite_total_limit": 2, "budget_borrow_limit_ratio": 0.5 }, "retry": { "environment_backoff_seconds": [1, 4, 16], "jitter": true, "total_retry_limit_seconds": 300, "retryable_error_whitelist": ["ETIMEDOUT", "ECONNRESET", "SERVICE_UNAVAILABLE"] }, "security": { "forbidden_commands": ["rm -rf /", "curl | sh"], "high_risk_domains": ["auth", "payment", "permission", "data_migration", "prod_config"] }, "checkpoints": { "sla_high_risk_hours": 4, "sla_normal_hours": 24, "timeout_high_risk_action": "reject_and_hold", "timeout_normal_action": "hold_safe_state" } } ``` ## 6.3 插件动作定义 | 动作 | 含义 | |---|---| | approve | 放行 | | modify | 修改参数或命令后放行 | | block | 阻断 | ### 6.3.1 返回结构 ```json { "action": "approve | modify | block", "message": "string", "modified_payload": {}, "rule_id": "string", "rules_version": "string" } ``` ## 6.4 Fail-Closed 规则 插件必须默认失败关闭。 ```text 插件异常 → block 规则文件缺失 → block 规则文件解析失败 → block 无法确认规则版本 → block ``` 禁止: ```text 插件异常 → approve ``` ## 6.5 启用与热更 | 对象 | 规则 | |---|---| | 插件启用 | 首次启用需重启进程 | | 插件禁用 | 需重启或明确热禁用接口 | | rules.json | 可热更 | | 规则缓存 | 必须加锁 | | 规则版本 | 每次拦截必须记录 | 推荐实现: 1. 每次工具调用现读 `rules.json`。 2. 若使用缓存,必须使用读写锁。 3. 文件变更后必须刷新缓存或版本号。 ## 6.6 并发安全 1. 工具并行运行时,插件会并发触发。 2. 共享规则缓存必须加读写锁。 3. 禁止在并发下写坏缓存。 4. 禁止读取半写入状态的规则文件。 ## 6.7 覆盖边界 | 层 | 拦截方式 | |---|---| | 工具调用 | `pre_tool_call` | | 模型输出 | `pre_verify` 或等价校验 | | 文件写入 | 文件系统权限 + 写入白名单 | | 预算 | Code 层预算计数器 | | 状态迁移 | 状态机校验 | ## 6.8 插件回归用例 每次修改规则插件后必须运行回归用例。 ### 6.8.1 用例环境 1. 临时 `HOME`。 2. 隔离配置目录。 3. 测试插件。 4. 测试规则文件。 5. 断言脚本。 ### 6.8.2 最小断言 | 用例 | 断言 | |---|---| | block | 命中禁词时工具不执行,返回拦截错误 | | modify | 原始命令被替换,实际执行修改后命令 | | approve | 正常命令放行 | | fail_closed | 插件异常时返回 block | | hot_reload | 修改规则后无需重启即可生效 | | concurrency | 并发调用下规则不串、不漏 | | no_plugin | 无插件时门控跳过,不影响正常执行 | ### 6.8.3 回归通过标准 ```text 所有断言通过,且日志中可看到规则版本与动作。 ``` --- # 第七章 工程验收清单 ## 7.1 状态机验收 - [ ] 所有状态枚举已落库。 - [ ] 所有状态迁移都有日志。 - [ ] 非法状态迁移会被拒绝。 - [ ] 重启后可恢复到稳定检查点。 - [ ] 不会重复执行非幂等副作用。 ## 7.2 锁与并发验收 - [ ] 文件锁可物理互斥。 - [ ] 资源锁覆盖数据库/端口/环境。 - [ ] 锁超时可回收。 - [ ] 崩溃后锁不会永久泄漏。 - [ ] 强制解锁有审计。 ## 7.3 预算验收 - [ ] 单任务超 120% 会进入 `paused_for_budget`。 - [ ] 全局池耗尽会进入 `circuit_broken`。 - [ ] 借调不超过 50%。 - [ ] 借调事件进入 Checkpoint 汇报队列。 - [ ] 非 token 成本可归集。 ## 7.4 验收流程验收 - [ ] Reviewer verdict 可机器比对。 - [ ] 空报告规则按“未执行检查”判定。 - [ ] 高危阻断项不走子集容忍。 - [ ] 双 Reviewer 独立隔离。 - [ ] Checkpoint 有 SLA 和超时动作。 ## 7.5 安全验收 - [ ] 高危域禁止默认妥协。 - [ ] 技术债有 owner、期限、阻断规则。 - [ ] 密钥不进日志。 - [ ] 高风险操作有审批。 - [ ] 外部依赖有许可与安全记录。 ## 7.6 插件硬拦截验收 - [ ] `rules.json` 版本可追踪。 - [ ] 插件支持 `approve / modify / block`。 - [ ] 插件异常时 fail-closed。 - [ ] 规则热更可用。 - [ ] 并发调用安全。 - [ ] 回归用例全部通过。 --- # 附录 A:最小状态迁移审计表 ```sql CREATE TABLE state_transitions ( id INTEGER PRIMARY KEY, entity_type TEXT NOT NULL, entity_id TEXT NOT NULL, from_state TEXT NOT NULL, to_state TEXT NOT NULL, reason_code TEXT NOT NULL, actor TEXT NOT NULL, evidence_uri TEXT, created_at TEXT NOT NULL ); ``` # 附录 B:最小锁表 ```sql CREATE TABLE locks ( lock_key TEXT PRIMARY KEY, lock_type TEXT NOT NULL, lock_mode TEXT NOT NULL, owner_id TEXT NOT NULL, task_id TEXT NOT NULL, acquired_at TEXT NOT NULL, lease_expires_at TEXT NOT NULL, state TEXT NOT NULL ); ``` # 附录 C:最小成本账本表 ```sql CREATE TABLE cost_ledger ( cost_id TEXT PRIMARY KEY, task_id TEXT NOT NULL, phase TEXT, module_id TEXT, cost_type TEXT NOT NULL, amount REAL NOT NULL, unit TEXT NOT NULL, unit_price REAL, total REAL, created_at TEXT NOT NULL ); ``` # 附录 D:插件伪代码 ```python def pre_tool_call(tool_name, payload, context): try: rules = load_rules_with_lock() if rules.is_forbidden(tool_name, payload): return { "action": "block", "message": "blocked by rules", "rule_id": rules.matched_rule_id, "rules_version": rules.version } if rules.should_rewrite(tool_name, payload): new_payload = rules.rewrite(payload) return { "action": "modify", "modified_payload": new_payload, "rule_id": rules.matched_rule_id, "rules_version": rules.version } return { "action": "approve", "rules_version": rules.version } except Exception as e: return { "action": "block", "message": f"plugin failure: fail-closed: {e}", "rules_version": "unknown" } ``` # 附录 E:回归用例骨架 ```text 1. 创建临时 HOME 2. 写入测试插件 3. 写入测试 rules.json 4. 启动隔离环境 5. 断言 block 用例 6. 断言 modify 用例 7. 断言 approve 用例 8. 断言插件异常时 fail-closed 9. 断言规则热更生效 10. 断言并发调用无串规则 11. 输出测试报告 ``` --- ## 结尾说明 本手册 v0.1 覆盖: 1. C 组 28 项工程缺口。 2. 框架级第 4 项“单一事实源 + 插件硬拦截”的落地方案。 3. 流程文档中所有“由 Code 层执行”的硬边界所需的最小工程规格。 本手册不改变流程文档的业务规则。 后续如果流程文档升级到新版本,本手册必须同步进行回归验证。