# Heicode 全链路代码评审报告 > 评审日期:2026-06-01 > 评审范围:`HeiCode-Swarm`、`heicode-mananger`、`heicode-macos-release`、`heicode-winos-release` 四仓库代码 > 评审依据(产品内容):`taijibaga` 组织 Projects —《Heicode 项目书 v0.2》与《Agnet 蜂群能力评价标准 ASCE v0.1》 > 性质:只读代码核查,所有结论附 `文件:行` 证据;不代表对外承诺。 --- ## 0. 一句话结论 当前代码在 **happy path 能跑通单 Agent 演示**,但与项目书/ASCE 承诺的“可控、可审计、可度量的软件交付”相比,存在一个**系统性病根**和六类**业务级问题**: > **病根:关键业务概念(“任务完成”“代码交付物”“状态枚举”“默认模型”“谁来编排”“安全边界”)没有单一权威定义,而是在 Runtime / Manager / 客户端 / 文档 里各写一份,再靠下游正则和文档补丁去对齐。补丁越加越多,缺口反而越堵越漏。** 最直接的可观测后果:用户让“写一个博客系统”,系统只产出**方案总结(无真实代码)**,却仍判 `completed` 并显示“已完成”。 --- ## 1. 评审对象与产品定位对照 | 仓库 | 角色(项目书定义) | 技术栈 | 最新状态 | |---|---|---|---| | `heicode-mananger` | Manager:SaaS 控制台 + 编排控制面 + 模型网关 | Go / Gin | 生产 `1.4.19` | | `HeiCode-Swarm` | Agnet 执行层:AKS 上多 Agent 运行时 | Python(FastAPI + Agent Worker) | 单 Agent MVP,多 Agent DAG 灰度 | | `heicode-macos-release` | macOS 客户端(用户主体验 + 高危审批) | Bun/TS + Tauri | `v0.4.18` | | `heicode-winos-release` | Windows 客户端(同源) | Bun/TS + Tauri | `v0.4.17`(落后 macOS 一版) | 产品愿景(项目书 §3)要求:从想法到上线的全 SDLC、AI 团队化协作、真实资源接入、安全边界可控、成本可见、交付可追溯。 ASCE(评价标准)要求蜂群在:任务完成、能力增益、协作、通信、成本、鲁棒性、安全治理七维度可度量,并设强制降级红线。 本报告即以上述两份为标尺,逐项核查代码实现度。 --- ## 2. 问题分级总表 | 编号 | 问题 | 严重度 | 影响(对照标尺) | 修复依赖 | |---|---|---|---|---| | P1 | “任务完成”无可信定义:模型自报 status 即算完成,无产出校验 | 🔴 阻断 | 违反项目书 §12.4、ASCE §8.1;完成数据全失真 | 契约 + Runtime 闸门 | | P2 | “代码交付物”被三处各判一遍且发散,补丁互漏 | 🔴 阻断 | ASCE 交付物完整性失真;UI 自相矛盾 | 结构化契约 | | P3 | 状态枚举对不上:`completed` 不在文档枚举内 | 🟠 高 | 客户端状态机漏终态 | 枚举统一 | | P4 | 编排权威不唯一 + 三条接入路径(左右脑) | 🟠 高 | 审计/计费无法归口;心智混乱 | 产品决策 | | P5 | 默认模型四套口径,自相矛盾 | 🟡 中 | 照默认走会 400 / 无可用渠道 | 单一来源 | | P6 | 安全治理“关键路径部分强制 + 大量占位”,多处达不到 ASCE 红线 | 🟠 高 | 可能触发 ASCE 强制降级到 L1/L2 | 补齐强制 | | P7 | 鲁棒性多为“有代码但缺原子性/边界”:双执行、orphan、重试均有缺陷 | 🟠 高 | ASCE 鲁棒性维度不可标生产级 | 加锁/reconcile | --- ## 3. 详细问题 ### P1. “任务完成”无可信定义(病根的核心表现)🔴 **Runtime 端**:Agent 的成功判定,直接信任模型在 JSON 里自填的 `status`,从不校验是否真有代码产出。 ```py # HeiCode-Swarm/agent/task_executor.py:141 success = all( r["status"] in ["completed", "handed_off"] for r in results ) ``` 模型完全可以返回 `status: "completed"` + `files: []`(把内容写进散文字段),执行器照样判成功。更严重的是 Agent 明知“没有任何文件改动”仍按成功上报: ```py # HeiCode-Swarm/agent/main.py:264 result["git_skipped"] = "No workspace changes to commit" ... await self.send_task_result(task_id, result["success"], result) # success=True ``` 校验环是被**主动删掉**的(注释自述),删完没有补任何“产出门槛”: ```py # HeiCode-Swarm/agent/task_executor.py:85 # the previous parse-then-verify loop caused useful file edits to be retried away ``` Orchestrator 端无条件发 `status: "completed"`,且无文件时仍发一个 `document` 总结 artifact(最新提交把“方案总结当交付”固化为常规输出): ```py # HeiCode-Swarm/orchestrator/main.py:494 / 519 artifact_type = "deployment_manifest" if files_modified or files_deleted else "document" ... "status": "completed", ``` Manager 端收到 `completed` 直接镜像,不看产出: ```go // heicode-mananger/heicode/controller/agnet_callback.go:304 case "deployment.status_changed": status := callbackStringValue(source, "status") if status != "" { record.Status = status record.RuntimeState = status ``` **后果**:项目书 §12.4 要求 completed 至少有“代码分支/测试结果/交付物”,ASCE §8.1 的构建/测试/交付物完整性在此场景全为 0,但系统判“成功”。 --- ### P2. “代码交付物”被定义了三遍,补丁互相不一致 🔴 同一个 `artifact_type` 字段,三处独立解释、无共享契约: 1. **Runtime** 硬编码类型:`HeiCode-Swarm/orchestrator/main.py:480,494`(`code_patch` / `document` / `deployment_manifest`)。 2. **Manager** 存为自由字符串、**无枚举无校验**,判定时还不读 `artifact_type`,另起一套基于 title/summary/uri 的探测: ```go // heicode-mananger/heicode/model/agnet_artifact.go:18 ArtifactType string `gorm:"type:varchar(64);index" json:"artifact_type"` ``` ```go // heicode-mananger/heicode/controller/agnet_runtime_client.go:670 strings.Contains(uri, "/artifacts/summary") { ``` 3. **客户端** 又用一套中文正则:`heicode-mananger/docs/integration/heicode-desktop-sub-agile-api.md:300-319`(`classifyArtifact`)。 **“补丁互漏”的冒烟证据**:Manager 探测器靠 `uri` 含 `/artifacts/summary`,但 Runtime 最新提交发的 uri 是 `runtime://{swarm_id}/artifacts/{task_id}`(`orchestrator/main.py:500`)——**不含该关键字,Manager 现在抓不到**;同时 Runtime 已把“无文件”表达成 `artifact_type="document"`,Manager 探测器却完全不读它。一次上游重构就让下游补丁失效。 **后果**:同一份 artifact,Manager 认为正常、客户端弹“不是代码交付物”黄条,顶部却仍显示绿色“已完成”——三方结论打架。 --- ### P3. 状态枚举对不上:`completed` 不在文档定义里 🟠 对接文档定义的合法状态值里**根本没有 `completed`**: ``` # heicode-mananger/docs/integration/heicode-desktop-sub-agile-api.md:1399 ### Agnet Deployment.status | accepted | running | stopped | failed | ### Agnet Deployment.runtime_state | queued | runtime_syncing | runtime_accepted | runtime_sync_failed | not_configured | ``` 但代码实际写入 `completed`(`agnet_callback.go:307`),初始态 `accepted`(`agnet_control_plane.go:1076`)。客户端若按文档枚举做状态机,会漏掉真实终态。 --- ### P4. 编排权威不唯一 + 三条接入路径(“左右脑互搏”)🟠 “创建多智能体任务”存在三条语义不同、审计能力不同的路径: 1. 生产主路径:客户端 → Manager `POST /api/swarms` → Runtime(`heicode-desktop-sub-agile-api.md:71`,但该入口同时背“普通 sub 适配”和“蜂群”两种模式,过载)。 2. 旁路:`HeiCode-Swarm/desktop-client` 自带复杂度分析 + 自动扩 Pod,直连 Orchestrator 原生 `/tasks`,**绕过 Manager 契约**。 3. 客户端本地:`heicode-{macos,winos}-release` 内置整套本地多智能体(`heicode/src/utils/swarm/`、`coordinator/`,继承自 Claude Code),与云端蜂群**同名同概念**(swarm/team/sub-agent/handoff/coordinator)。 项目书 §1.6 明确愿景是“Agent 基础设施不应只在本地”,即云端蜂群才是生产执行层;但客户端那套本地编排仍随包发布、可独立拆任务,造成概念与心智的左右脑互搏,且 ASCE 评测口径无法统一(本地路径不产生 Runtime trace/审计)。 --- ### P5. 默认模型四套口径,自相矛盾 🟡 | 来源 | 默认/建议模型 | 证据 | |---|---|---| | 代码角色模板 | `claude-sonnet-4-6` / `claude-opus-4-7` | `agnet_role_template.go:49,82` | | 对接文档示例 | `agnet-model-backend`(占位名) | `heicode-desktop-sub-agile-api.md:1376` | | 文档明令禁用 | 禁止用 `agnet-model-*` 占位名 | 同上 `:48` | | 生产实际验证 | 仅 `gpt-5.4`;且说 `claude-sonnet-4-6` 走普通 sub 可能上游 400 | 同上 `:15,:49` | 照代码默认值(sonnet)走 → 文档说会 400;照文档示例(agnet-model-backend)走 → 文档自己说禁用。无单一可信来源。 --- ### P6. 安全治理:关键路径部分强制 + 大量占位,多处触及 ASCE 红线 🟠 ASCE 强制降级红线:明文密钥进 Git/日志/Markdown/前端→最高 L1;高危无审批→最高 L1;无法追踪资源→最高 L2。代码现状: | 治理项 | 现状 | 证据 | |---|---|---| | `secret_ref` 强制 `azkv://` | ✅ Agnet 部署/回调/KV 读取**已强制** | `agnet_control_plane.go:744`、`agnet_callback.go:628`、`secret_store.go:143` | | 同上(Resource CRUD `/api/resources`) | ⚠️ **未校验**,可直写任意 `secret_ref` | `resource.go:449` | | 明文密钥扫描 | ⚠️ 仅按**字段名**拦截,无**值模式**扫描(JWT/`sk-` 等),可绕过(放进非敏感 key / 字符串数组 / `secret_ref` 列) | `resource.go:33,244`、`agnet_control_plane.go:537` | | Secret Broker(Key Vault) | ⚠️ 写/读已实现,**轮换/撤销/禁用缺失** | `secret_store.go:52`;`docs/plan.md` 仍列 P2 | | 短期凭证 lease 派生 | ❌ **占位**:审批通过只生成 `lease://` 引用,不读 KV、不 mint 临时 token | `agnet_approval.go:213` | | 高危审批阻断 | ❌ Manager **不阻断**:部署 `status: accepted` 立即落库,不检查 risk_level/pending approval;阻断依赖 Runtime | `agnet_control_plane.go:1071` | | 撤销 lease 立即失效 | ⚠️ 仅改 DB,不通知 Runtime(approve 有 sync、revoke 无) | `agnet_approval.go:339` | | permission manifest 强制 | ⚠️ 仅生成下发,**无 Manager 运行时 action 校验**;`allowed_actions` 不与 binding 交叉校验 | `agnet_control_plane.go:870,885`、`resource.go:366` | | 审计落库 | ⚠️ 有结构化表,但**best-effort 非 fail-closed**,列表 API 不返回 details | `agnet_audit.go:59`、`agnet_control_plane.go:1928` | **结论**:安全是“Agnet 控制面 ingress 有可测试的强制校验,但 Secret Broker 半成品、lease 占位、高危阻断在 Runtime、权限 manifest 只给模型看、审计不 fail-closed”。对照 ASCE,**明文密钥(值级 bypass + secret_ref 直写)与高危无 Manager 阻断**两项有把整体压到 L1/L2 的风险。 --- ### P7. 鲁棒性:有代码但缺原子性与边界处理 🟠 README/文档声称“状态恢复、orphan 恢复、失败重试、双执行避免、多 Agent DAG、capability 匹配、一层 handoff”,代码核查为 happy path 有实现、生产可靠性不足: | 能力 | 评级 | 关键缺陷 | 证据 | |---|---|---|---| | 双执行避免 | ⚠️ 部分/有缺陷 | 无 Redis 原子领取/租约;`get_ready_pending_task`(lrange+lrem)与 `assign_task` 分离,REST `/tasks/assign` 与 dispatch loop 可并发对同一 task 双 assign;complete 不校验 reporting agent | `task_queue.py:114,158,242`、`main.py:1060,1399` | | orphan / 状态恢复 | ⚠️ 部分/有缺陷 | Orchestrator 启动**无 reconcile**;重启后 WS 空集,30s 后可能把仍在执行的任务重新入队 → 与旧 Agent 完成消息叠加双跑;orphan 未 ready 时只 save 不 requeue → 永不调度 | `main.py:236`、`task_queue.py:372,386` | | checkpoint 续跑 | ❌ 占位 | `checkpoint_manager.py` 完整实现但**无任何地方 import/调用**;指数退避同样未接入 | `checkpoint_manager.py:43,170` | | 失败重试 | ⚠️ 基础可用 | 真 requeue,但**无退避**;orphan/agent-dead 与业务失败共用 retry 配额 | `task_queue.py:270` | | DAG 依赖调度 | ✅ 真实现(需开关) | 但依赖任务 `FAILED/CANCELLED` 时下游**永久 not ready**、仍留在 queue 被空扫 | `task_queue.py:140`、`swarm_runtime.py:69` | | capability 匹配 | ⚠️ 部分 | `required` 为空则**恒真**;取第一个匹配 idle agent,非最优;handoff 子任务无匹配 capability 则**永不派发** | `task_queue.py:151`、`main.py:131,1234` | | 一层 handoff 父子联动 | ⚠️ 部分 | 只发 `handoff_request` 未发 `blocked_on_handoff` 时父仍 BUSY;`child_task_id` 常为 null;子永远 pending → 父**永久 BLOCKED** | `main.py:1361`、`agent/main.py:175` | 部署当前 `replicas: 1`(`k8s/orchestrator-deployment.yaml:25`)掩盖了部分竞态;一旦多副本且无分布式锁,双执行风险显著放大。 --- ## 4. 对照 ASCE 强制降级与项目书验收 | 红线 / 验收项 | 来源 | 当前是否满足 | 关联问题 | |---|---|---|---| | 任务成功必须有可验证产出 | 项目书 §12.4 / ASCE §8.1 | ❌ 否(方案总结即 completed) | P1 | | 交付物完整性(代码/测试/部署说明) | ASCE §8.1 | ❌ 否 | P1/P2 | | 明文密钥零暴露 | ASCE §10.2 强制降级 | ⚠️ 有 bypass 面 | P6 | | 高危操作 100% 审批 | ASCE §10.2 / 项目书 §8.5 | ⚠️ Manager 不阻断,依赖 Runtime | P6 | | 可追踪资源使用 | ASCE §10.2 | ⚠️ 审计非 fail-closed、API 缺 details | P6 | | 双执行避免 | ASCE §8.6 | ⚠️ 无原子保证 | P7 | | 状态可回放(trace 完整) | ASCE §12.3 | ⚠️ 本地编排路径无 Runtime trace | P4 | 按 ASCE §10.1 等级判定,**P1(无产出门槛)叠加 P6(密钥/审批)会把当前系统压在 L1~L2**,与项目书面向企业 L4/L5 的目标差距明显。 --- ## 5. 收敛建议(按优先级) > 总原则:**给每个关键概念定唯一权威定义 + 唯一裁判,由 Runtime 输出“结构化真相”,Manager 据结构化字段裁决,客户端只消费结论。删掉客户端/Manager 各自的本地正则。** 1. **P1 + P3(地基,先做)**:定一份《完成与状态契约》—— - 终态枚举统一(含 `completed` 与新增非成功终态 `completed_without_deliverable` / `needs_codegen`),文档+Go+客户端三处对齐。 - 代码任务 `completed` 的充要条件 = 结构化产出非空(`files_modified` 非空 / 有 diff / 有 commit)。落点:`HeiCode-Swarm/orchestrator/main.py` 的 `emit_task_completion_events` + `agent/task_executor.py` 成功判定 + `agent/main.py` 的“无改动”分支。 2. **P2 + P6 责任上移**:定一份《交付物与判定契约》——`artifact_type` 规范枚举;`deliverable` 判定**只依据结构化字段**(复用已有的 `files_modified` / `git_skipped` / `artifact_type=document`),Manager 据此裁决并据此降级 `completed`;删客户端 `classifyArtifact` 与 Manager `runtimeArtifactsAreSummaryOnly` 两套正则。 3. **P6 安全补齐**:值级密钥扫描(不只字段名)+ Resource CRUD 的 `secret_ref` 校验;高危操作在 Manager 侧 gate(pending 审批未通过不进入执行/不下发 plan);revoke 同步 Runtime;审计改 fail-closed 或至少告警可观测。 4. **P7 鲁棒性**:任务领取改 Redis 原子(Lua/`SETNX`+租约);Orchestrator 启动 reconcile(重建 queue/状态);接线 checkpoint + 指数退避;DAG 依赖失败的传播与父任务超时解除。 5. **P5(独立低风险)**:模型默认/允许清单收敛到单一来源,对齐生产 NewAPI,清占位名。 6. **P4(单独立项)**:明确每模式唯一编排权威(交互式=本地、无人值守/计费/审计=云端经 Manager);废弃 `HeiCode-Swarm/desktop-client` 的 `/tasks` 旁路;本地多智能体改名(local-team),“蜂群/swarm”专留云端。 建议顺序:先 1、2(地基与责任上移)→ 3、4(安全与鲁棒)并行 → 5 随手清理 → P4 作为独立产品决策推进。 --- ## 6. 证据索引(关键文件) - Runtime 完成判定:`HeiCode-Swarm/agent/task_executor.py:85,141`、`agent/main.py:264` - Runtime artifact/状态:`HeiCode-Swarm/orchestrator/main.py:445-552` - Runtime 鲁棒性:`HeiCode-Swarm/orchestrator/task_queue.py`、`agent_registry.py`、`checkpoint_manager.py`、`k8s/orchestrator-deployment.yaml:25` - Manager 回调/状态:`heicode-mananger/heicode/controller/agnet_callback.go:304,376,628,682` - Manager artifact 模型/诊断:`heicode-mananger/heicode/model/agnet_artifact.go:18`、`controller/agnet_runtime_client.go:663` - Manager 安全治理:`controller/agnet_control_plane.go`、`controller/agnet_approval.go`、`controller/resource.go`、`controller/secret_store.go`、`model/agnet_audit.go` - Manager 角色模板:`controller/agnet_role_template.go:44-115` - 客户端分类规则 / 状态枚举 / 模型口径:`heicode-mananger/docs/integration/heicode-desktop-sub-agile-api.md:48,300,1376,1399` - 客户端本地编排:`heicode-{macos,winos}-release/heicode|.` `src/utils/swarm/`、`src/coordinator/` --- *本报告为只读代码核查结论,证据均可在对应仓库 `文件:行` 复核。修复实现需在确认契约后另行评审。*