siddiqitaha/ai-body
GitHub: siddiqitaha/ai-body
一个受治理的本地 AI agent 基础架构,通过确定性核心和五个可替换端口实现 fail-closed 的操作治理,确保每次模型调用、工具调用和内存写入都经过安全判定。
Stars: 0 | Forks: 0
# AI 主体
一个受治理的本地 agent 基础:将一个个人 AI 系统重构为 **五个可替换的端口,
位于一个确定性核心之后**,其中每一次模型调用、工具调用、内存写入和回答,
在通过时都会经过一道 **fail-closed 门**。以后只需编写一个 manifest 即可添加任何内容,
核心永不改变。
这不是一个框架,也不是一个 LLM 老大 agent。而是一个小巧的、自主拥有的协调器,在一套规则下将自主拥有的各个部分连接起来。
**它的证明**(方便快速阅读):
- **Fail-closed 治理,两个层级。** 每次调用都会在进程内跨越一个判定总线,而模型唯一的网络路由是一个进程外的网关。如果一个 guard 无法做出决定,或者某个 guard 宕机,答案就是 *deny*,绝不会是 *allow*。
- **原生模块化。** 所有五个端口都有一个真实的备用 adapter,每个只需一个 `register()` 即可添加,且无需对核心进行任何修改,其核心主张正是“在不触及中间部分的情况下增加一项能力”。
- **自主拥有、可移植的内存。** 一个仅追加的账本,具备混合召回功能,通过 parity gate 和经过验证的、可逆的切换进行迁移,没有任何外部存储会成为真理来源。
- **受治理的自主性。** 两个受隔离的 worker(只读 researcher + 具备写入能力的 coder)在逐 worker 的工具白名单、默认拒绝的委托以及仅向内流动的学习机制下运行。
**60 秒速览:** `python3 accept.py` 会运行所有 15 项完成度检查并打印出全绿的看板;[实时架构页面](https://siddiqitaha.github.io/ai-body/) 是其可视化展示。详情见下文。
```
flowchart TD
R(["request"]) --> D["DOORS
token auth, deny-by-default"] D -->|"check the request"| BUS subgraph BUS["VERDICT BUS · cross-cutting · fail-closed"] direction LR G1["agent-control"]:::guard G2["local-scanner"]:::guard G3["guard-model"]:::guard G4["ref-dlp"]:::guard end BUS -.- DEC["5 decisions: deny · steer · warn · log · allow
worst wins · tighten-only · a guard error = deny"]:::note BUS -->|"if allowed"| H["THE HEART
registry · organ-graph · router · one door"] H -->|"gate each call"| P subgraph P["PORTS · swappable adapters"] direction LR M["Model"]:::port MEM["Memory"]:::port T["Tool"]:::port S["Surface"]:::port E["Evaluator
(guards plug in)"]:::port end M -.->|"model in + out"| BUS T -.->|"every tool call"| BUS P --> O["OBSERVABILITY
eval store + traces to Grafana (fails open)"]:::obs classDef guard fill:#fdeaea,stroke:#d1444a,color:#111 classDef port fill:#eef2ff,stroke:#5566a0,color:#111 classDef note fill:#fafafa,stroke:#bbbbbb,color:#333 classDef obs fill:#f2f2f2,stroke:#888888,color:#111 style BUS fill:#fff5f5,stroke:#d1444a,stroke-width:2px style H fill:#e2f4f6,stroke:#0e9bb0,stroke-width:2px style D fill:#ffffff,stroke:#888888,color:#111 style P fill:#f7f8fb,stroke:#8890a8 ``` 判定总线 **不是** 一个下游端口,它是一条数据流在入口处必须经过的带子, 在每次模型 / 工具 / 内存调用时(进和出),以及在回答时,都会经过。Evaluator 端口只是 guard 的接入点;调用它们的总线是跨层级的。 ### 两个执行层级(纵深防御) 上面的总线是 **第一层级 (tier 1)**:快速、进程内,但它驻留在 agent 内部,跳过了 核心的代码也就跳过了总线。**第二层级 (tier 2)** 是一个进程外的网关(`gateway.py`),它掌握着通往模型的唯一 网络路由,并在转发前独立咨询 Agent Control: ``` agent ─▶ [tier 1: heart bus, in-proc, all 4 guards] ─▶ [tier 2: LLM gateway, out-of-proc] │ asks Agent Control :19381 ├ allow ─▶ model :8012 └ deny / AC down ─▶ 403, model never reached ``` 第一层级速度快,能拦截大部分内容;第二层级是被攻破的 agent 无法 绕过的瓶颈。经实测验证:一个良性的 prompt 会转发给模型,而一个包含机密文件的 prompt 会 在模型被调用之前就被网关拦截。将 Model adapter 的 base 指向该网关即可将其武装起来: `AIBODY_MODEL_BASE=http://127.0.0.1:19099/v1 AIBODY_GUARD_MODE=enforce python3 serve.py` 可在 两个层级(enforce 下的进程内总线 + 进程外网关)背后运行这道网络门。 完整可视化:**[实时架构页面](https://siddiqitaha.github.io/ai-body/)**(源码:[`docs/index.html`](docs/index.html))。 ## 任何 adapter 都不可破坏的七条规则 1. **Fail closed。** 无法做出决定或缺少模块的门将执行拒绝。 2. **拥有数据。** 内存账本属于我们自己,在本地设备上,仅追加。没有外部存储是真理来源。 3. **在端口上进行治理,而非在 adapter 中。** 每次调用都在契约边界处通过门。 4. **仅收紧自动化。** 自动执行者只能使事情变得更严格;放宽限制是一种带有记录的人类行为。 5. **变更时重新设防。** 计划或循环动作在触发时会根据当前校准状态重新检查。 6. **任何东西落地前都要受治理。** 新的模型/工具/技能必须经过 quarantine → scan → register-by-fingerprint → sandbox。 7. **学习向内排放。** worker 学到的内容会被提交给大脑并存储在我们的账本中,否则不予保留。 ## 五个端口(契约) | 端口 | 契约 | 当前的参考 adapter | 端口上的治理 | |---|---|---|---| | **Model** | `complete` / `embed` / `capabilities` | `LocalModel` (本地层) + 可选的 `CloudModel` (云层) | 分层感知路由:默认私有 → 本地;仅非敏感内容可卸载;出口处进行 DLP 脱敏,绝不发送原始数据 | | **Memory** | `remember` / `recall` / `supersede` / `invalidate` | `BrainMemory`,笔记 + FTS + 向量,由 RRF 融合 | 写入时扫描,按范围过滤,仅追加 | | **Tool** | `list` / `invoke` | `status` + `repo_ls` (读取) + `repo_write` (受限写入),通过 acquire 漏斗准入 | 通过指纹准入(不变性 6),每次调用前有 fail-closed 门;未知 → deny | | **Surface** | `receive` | `LocalSurface` (进程内 token 门) + `HTTPSurface` (网络门) | Bearer auth,通过 header 传递 principal(从不使用默认值),缺少 principal → deny | | **Evaluator** | `evaluate → Verdict{deny,steer,warn,log,allow}` | 判定总线(包含以下四个 guard) | 仅收紧;执行错误 → deny | | *(Worker)* | `run(task, cage)` | `ResearcherWorker` (只读) + `CoderWorker` (受治理的写入,无执行权限) | 按 worker 的工具白名单(即 cage),默认拒绝委托,学习向内排放 | **判定总线**,包含四个 guard,每个返回五种决定之一;最坏的决定胜出,evaluator 只能收紧,并且任何在执行路径上出错的 guard 都会被视为 `deny`: - `agent-control`,运行在 `:19381` 上的实时 Agent Control 服务器 (fail-closed) - `local-scanner`,运行在 `:18970` 上的本地安全扫描器 (fail-closed;需要 `SCANNER_GATEWAY_TOKEN` 才能生效) - `guard-model`,用于判定 SAFE/UNSAFE 的本地模型(可以注入一个 `judge`,例如 DefenseClaw)。**已校准**:在 55 个标注用例(`calibration_set.py`)上 Se 1.0 / Sp 1.0,因此授权使用 `enforce` 模式(阻断);默认以 `observe` 模式运行。离线已证明:UNSAFE → deny,SAFE → allow,judge 错误时会 fail closed - `ref-dlp`,确定性的密钥标记扫描 ## 运行它 ``` # 一键健康检查:全部 15 个 definition-of-done 框,若有任何失败则以非零值退出 python3 accept.py # 单元 suites(93 个测试,离线) for t in test_skeleton test_phase1 test_phase2 test_phase3 test_phase4 test_phase5 test_phase6 test_phase7 test_phase8 test_phase9 test_phase10 test_phase11 test_phase12 test_phase13; do python3 $t.py; done # 通过 live Agent Control server 的受控演练(需要在 env 中配置 AC keys) python3 phase1.py # memory rebuild + parity gate(对源 memory store 为只读) python3 migrate.py 0 # 0 = all notes; a number = sample that many python3 parity_harness.py 150 # OLD brain vs NEW core, same sample python3 cutover_live.py # prove the full cutover lifecycle on the real notes (writes a receipt) ``` `accept.py` 是用于确认 *该基础是否依然有效?* 的门,涵盖了端到端的走查、fail-closed 自检、trace + eval 存储、内存一致性、DLP 拦截、模块化测试、隔离 worker 的 委托,以及 `doctor`。全部通过 = 已验证。 ## 文件映射 | 文件 | 它是什么 | |---|---| | `ports.py` | 五个契约 + `Decision`/`Verdict` 词汇表 + Worker 端口 | | `heart.py` | registry、organ-graph、router、单门、判定总线、`Cage`、`delegate` | | `adapters.py` | 每个端口的一个参考 adapter + 四个 evaluator + 受隔离的 worker | | `manifest.py` | 使添加任何内容都成为一种配置行为的小型声明 | | `memory.py` | `BrainMemory`,仅追加笔记 + FTS + 向量,混合召回 (RRF) | | `migrate.py` | 带有 parity gate 的内存迁移(对源内存存储保持只读) | | `parity_harness.py` | 诚实的旧版与新版召回对比 | | `cutover.py` | 影子双写 + 回滚(绞杀者模式切换机制) | | `cutover_live.py` | 端到端地在真实笔记上运行完整的切换生命周期 + 写入回执 | | `acquire.py` | acquire 漏斗(不变性 6):quarantine → scan → fingerprint → sandbox;`build_toolbox()` 武装实时工具端口 | | `router.py` | 分层感知的模型路由:默认私有 → 本地,非敏感内容可卸载到云,fail-closed | | `serve.py` | 通过 HTTP 运行受治理的堆栈(`HTTPSurface` 网络门) | | `observ.py` | eval 存储 (verdicts) + OTLP trace 导出(fails open) | | `doctor.py` | 枚举每个 guard,如果没有一个能证明是活跃的,则以非零状态失败 | | `calibrate.py` | 阻断前先提升的门(在 ≥ 50 个标签上 Se/Sp ≥ 0.90) | | `phase1.py` | 组装受治理的堆栈;`build_governed()` | | `accept.py` | 一条命令的完成度定义门 | | `test_*.py` | 14 个测试套件,93 个测试用例 | ## 状态 - **基础功能已完备。** 所有五个端口都有一个真实的 adapter;受治理、受监控, 具备隔离 worker 循环和经过测试的切换机制。 - **不变性 6 已武装。** 实时工具端口现在通过 acquire 漏斗运行,因此每个工具在运行前都会被 quarantine → scanned → fingerprinted,并且摘要会在调用时重新检查 (准入后的替换将被拒绝)。第二个真实工具 `repo_ls` 通过单 adapter 的方式添加 (`admit` + `register`),无需对核心进行任何修改,证明了 Tool 端口上的模块化契约。 - **分层感知的模型路由。** 核心按层级路由每个模型调用:默认私有,因此 除非请求选择退出,否则调用将停留在本地层;仅非敏感调用可卸载到 云层;没有本地模型的敏感调用将被拒绝,绝不泄露。`CloudModel` adapter 增加了第二道防线,彻底拒绝带有密钥的输入。添加云端行只需一个 `register()`,未标记的单模型集群的行为与以前完全一致。 - **第二个接口(网络门)。** `HTTPSurface` 使得受治理的堆栈可以通过 HTTP 调用, 并带有与本地门相同的 fail-closed 契约(Bearer auth,通过 `X-Principal` 传递 principal, 缺少 principal 被拒绝,错误的 token 在到达核心之前会返回 401)。`python3 serve.py` 运行它。所有五个 端口现在都有两个 adapter 或一个经过验证的第二 adapter 路径,模块化主张在每一个上都成立。 - **两个执行层级同时武装。** `serve.py` 可以在 guard 模型处于 `enforce`(第一层级总线拦截 UNSAFE)并且模型通过第二层级网关(进程外 瓶颈)路由的情况下运行网络门,通过 `AIBODY_GUARD_MODE` 和 `AIBODY_MODEL_BASE` 控制。guard 模型采用可插拔的 `judge`,因此 DefenseClaw 或任何其他 judge 都可以为其提供支持。 - **两个真实的隔离 worker。** 一个 `researcher`(只读:recall + `repo_ls`)和一个 `coder`(读取,加上 受限在沙箱内受治理的 `repo_write`,每次写入都经过 DLP 门控和指纹准入,并且 无执行权限)。每个 worker 都有自己的由 cage 强制执行的工具白名单,只有核心才能调用它们 (委托默认是拒绝的,因此 worker 之间无法互相调用),并且两者都向内排放学习内容。 `build_governed(with_workers=True)` 注册了它们。这反映了正在运行的多 agent 集群 (researcher + coder)并对其进行了收紧:能力只能在 cage、门和漏斗背后呈现。 - **内存:** 1930 条笔记被迁移到一个副本中;确认了与源内存存储的召回一致性 (hit@12 0.913 = 0.913,delta 0.000)。 - **切换已验证且可逆。** `cutover_live.py` 在所有 1930 条真实笔记上运行了完整的绞杀者模式生命周期:影子双写(0 次失败),在实际查询上进行 `compare_recall` 一致性测试(重叠率 1.0,0 差异),切换让候选者提供读取服务,然后回滚,两种方式的读取都完好无损, 没有任何东西被破坏(回执记录在 `cutover-receipt.json` 中)。实时的源 daemon 切换仍然是一个 需要用户深思熟虑的、单独备份的操作;但它将要使用的机制现在已经在端到端得到了验证。 - **测试:** 93/93 单元测试 + `accept.py` 15/15 全通过。 ### 等待人工操作(每项只需一步) - 标注 50-100 个真实用例 → `calibrate.py` 将 guard模型从 observe 提升为阻断。 - 提供 `SCANNER_GATEWAY_TOKEN` → LocalScanner guard 生效。 - 在选定后切换实时的源 daemon → 切换机制已被证明是可逆的(见上文)。 从这里开始,AI Body 将通过每次添加一个 adapter 来引入下一个 worker、工具、模型或接口,从而实现增长。
token auth, deny-by-default"] D -->|"check the request"| BUS subgraph BUS["VERDICT BUS · cross-cutting · fail-closed"] direction LR G1["agent-control"]:::guard G2["local-scanner"]:::guard G3["guard-model"]:::guard G4["ref-dlp"]:::guard end BUS -.- DEC["5 decisions: deny · steer · warn · log · allow
worst wins · tighten-only · a guard error = deny"]:::note BUS -->|"if allowed"| H["THE HEART
registry · organ-graph · router · one door"] H -->|"gate each call"| P subgraph P["PORTS · swappable adapters"] direction LR M["Model"]:::port MEM["Memory"]:::port T["Tool"]:::port S["Surface"]:::port E["Evaluator
(guards plug in)"]:::port end M -.->|"model in + out"| BUS T -.->|"every tool call"| BUS P --> O["OBSERVABILITY
eval store + traces to Grafana (fails open)"]:::obs classDef guard fill:#fdeaea,stroke:#d1444a,color:#111 classDef port fill:#eef2ff,stroke:#5566a0,color:#111 classDef note fill:#fafafa,stroke:#bbbbbb,color:#333 classDef obs fill:#f2f2f2,stroke:#888888,color:#111 style BUS fill:#fff5f5,stroke:#d1444a,stroke-width:2px style H fill:#e2f4f6,stroke:#0e9bb0,stroke-width:2px style D fill:#ffffff,stroke:#888888,color:#111 style P fill:#f7f8fb,stroke:#8890a8 ``` 判定总线 **不是** 一个下游端口,它是一条数据流在入口处必须经过的带子, 在每次模型 / 工具 / 内存调用时(进和出),以及在回答时,都会经过。Evaluator 端口只是 guard 的接入点;调用它们的总线是跨层级的。 ### 两个执行层级(纵深防御) 上面的总线是 **第一层级 (tier 1)**:快速、进程内,但它驻留在 agent 内部,跳过了 核心的代码也就跳过了总线。**第二层级 (tier 2)** 是一个进程外的网关(`gateway.py`),它掌握着通往模型的唯一 网络路由,并在转发前独立咨询 Agent Control: ``` agent ─▶ [tier 1: heart bus, in-proc, all 4 guards] ─▶ [tier 2: LLM gateway, out-of-proc] │ asks Agent Control :19381 ├ allow ─▶ model :8012 └ deny / AC down ─▶ 403, model never reached ``` 第一层级速度快,能拦截大部分内容;第二层级是被攻破的 agent 无法 绕过的瓶颈。经实测验证:一个良性的 prompt 会转发给模型,而一个包含机密文件的 prompt 会 在模型被调用之前就被网关拦截。将 Model adapter 的 base 指向该网关即可将其武装起来: `AIBODY_MODEL_BASE=http://127.0.0.1:19099/v1 AIBODY_GUARD_MODE=enforce python3 serve.py` 可在 两个层级(enforce 下的进程内总线 + 进程外网关)背后运行这道网络门。 完整可视化:**[实时架构页面](https://siddiqitaha.github.io/ai-body/)**(源码:[`docs/index.html`](docs/index.html))。 ## 任何 adapter 都不可破坏的七条规则 1. **Fail closed。** 无法做出决定或缺少模块的门将执行拒绝。 2. **拥有数据。** 内存账本属于我们自己,在本地设备上,仅追加。没有外部存储是真理来源。 3. **在端口上进行治理,而非在 adapter 中。** 每次调用都在契约边界处通过门。 4. **仅收紧自动化。** 自动执行者只能使事情变得更严格;放宽限制是一种带有记录的人类行为。 5. **变更时重新设防。** 计划或循环动作在触发时会根据当前校准状态重新检查。 6. **任何东西落地前都要受治理。** 新的模型/工具/技能必须经过 quarantine → scan → register-by-fingerprint → sandbox。 7. **学习向内排放。** worker 学到的内容会被提交给大脑并存储在我们的账本中,否则不予保留。 ## 五个端口(契约) | 端口 | 契约 | 当前的参考 adapter | 端口上的治理 | |---|---|---|---| | **Model** | `complete` / `embed` / `capabilities` | `LocalModel` (本地层) + 可选的 `CloudModel` (云层) | 分层感知路由:默认私有 → 本地;仅非敏感内容可卸载;出口处进行 DLP 脱敏,绝不发送原始数据 | | **Memory** | `remember` / `recall` / `supersede` / `invalidate` | `BrainMemory`,笔记 + FTS + 向量,由 RRF 融合 | 写入时扫描,按范围过滤,仅追加 | | **Tool** | `list` / `invoke` | `status` + `repo_ls` (读取) + `repo_write` (受限写入),通过 acquire 漏斗准入 | 通过指纹准入(不变性 6),每次调用前有 fail-closed 门;未知 → deny | | **Surface** | `receive` | `LocalSurface` (进程内 token 门) + `HTTPSurface` (网络门) | Bearer auth,通过 header 传递 principal(从不使用默认值),缺少 principal → deny | | **Evaluator** | `evaluate → Verdict{deny,steer,warn,log,allow}` | 判定总线(包含以下四个 guard) | 仅收紧;执行错误 → deny | | *(Worker)* | `run(task, cage)` | `ResearcherWorker` (只读) + `CoderWorker` (受治理的写入,无执行权限) | 按 worker 的工具白名单(即 cage),默认拒绝委托,学习向内排放 | **判定总线**,包含四个 guard,每个返回五种决定之一;最坏的决定胜出,evaluator 只能收紧,并且任何在执行路径上出错的 guard 都会被视为 `deny`: - `agent-control`,运行在 `:19381` 上的实时 Agent Control 服务器 (fail-closed) - `local-scanner`,运行在 `:18970` 上的本地安全扫描器 (fail-closed;需要 `SCANNER_GATEWAY_TOKEN` 才能生效) - `guard-model`,用于判定 SAFE/UNSAFE 的本地模型(可以注入一个 `judge`,例如 DefenseClaw)。**已校准**:在 55 个标注用例(`calibration_set.py`)上 Se 1.0 / Sp 1.0,因此授权使用 `enforce` 模式(阻断);默认以 `observe` 模式运行。离线已证明:UNSAFE → deny,SAFE → allow,judge 错误时会 fail closed - `ref-dlp`,确定性的密钥标记扫描 ## 运行它 ``` # 一键健康检查:全部 15 个 definition-of-done 框,若有任何失败则以非零值退出 python3 accept.py # 单元 suites(93 个测试,离线) for t in test_skeleton test_phase1 test_phase2 test_phase3 test_phase4 test_phase5 test_phase6 test_phase7 test_phase8 test_phase9 test_phase10 test_phase11 test_phase12 test_phase13; do python3 $t.py; done # 通过 live Agent Control server 的受控演练(需要在 env 中配置 AC keys) python3 phase1.py # memory rebuild + parity gate(对源 memory store 为只读) python3 migrate.py 0 # 0 = all notes; a number = sample that many python3 parity_harness.py 150 # OLD brain vs NEW core, same sample python3 cutover_live.py # prove the full cutover lifecycle on the real notes (writes a receipt) ``` `accept.py` 是用于确认 *该基础是否依然有效?* 的门,涵盖了端到端的走查、fail-closed 自检、trace + eval 存储、内存一致性、DLP 拦截、模块化测试、隔离 worker 的 委托,以及 `doctor`。全部通过 = 已验证。 ## 文件映射 | 文件 | 它是什么 | |---|---| | `ports.py` | 五个契约 + `Decision`/`Verdict` 词汇表 + Worker 端口 | | `heart.py` | registry、organ-graph、router、单门、判定总线、`Cage`、`delegate` | | `adapters.py` | 每个端口的一个参考 adapter + 四个 evaluator + 受隔离的 worker | | `manifest.py` | 使添加任何内容都成为一种配置行为的小型声明 | | `memory.py` | `BrainMemory`,仅追加笔记 + FTS + 向量,混合召回 (RRF) | | `migrate.py` | 带有 parity gate 的内存迁移(对源内存存储保持只读) | | `parity_harness.py` | 诚实的旧版与新版召回对比 | | `cutover.py` | 影子双写 + 回滚(绞杀者模式切换机制) | | `cutover_live.py` | 端到端地在真实笔记上运行完整的切换生命周期 + 写入回执 | | `acquire.py` | acquire 漏斗(不变性 6):quarantine → scan → fingerprint → sandbox;`build_toolbox()` 武装实时工具端口 | | `router.py` | 分层感知的模型路由:默认私有 → 本地,非敏感内容可卸载到云,fail-closed | | `serve.py` | 通过 HTTP 运行受治理的堆栈(`HTTPSurface` 网络门) | | `observ.py` | eval 存储 (verdicts) + OTLP trace 导出(fails open) | | `doctor.py` | 枚举每个 guard,如果没有一个能证明是活跃的,则以非零状态失败 | | `calibrate.py` | 阻断前先提升的门(在 ≥ 50 个标签上 Se/Sp ≥ 0.90) | | `phase1.py` | 组装受治理的堆栈;`build_governed()` | | `accept.py` | 一条命令的完成度定义门 | | `test_*.py` | 14 个测试套件,93 个测试用例 | ## 状态 - **基础功能已完备。** 所有五个端口都有一个真实的 adapter;受治理、受监控, 具备隔离 worker 循环和经过测试的切换机制。 - **不变性 6 已武装。** 实时工具端口现在通过 acquire 漏斗运行,因此每个工具在运行前都会被 quarantine → scanned → fingerprinted,并且摘要会在调用时重新检查 (准入后的替换将被拒绝)。第二个真实工具 `repo_ls` 通过单 adapter 的方式添加 (`admit` + `register`),无需对核心进行任何修改,证明了 Tool 端口上的模块化契约。 - **分层感知的模型路由。** 核心按层级路由每个模型调用:默认私有,因此 除非请求选择退出,否则调用将停留在本地层;仅非敏感调用可卸载到 云层;没有本地模型的敏感调用将被拒绝,绝不泄露。`CloudModel` adapter 增加了第二道防线,彻底拒绝带有密钥的输入。添加云端行只需一个 `register()`,未标记的单模型集群的行为与以前完全一致。 - **第二个接口(网络门)。** `HTTPSurface` 使得受治理的堆栈可以通过 HTTP 调用, 并带有与本地门相同的 fail-closed 契约(Bearer auth,通过 `X-Principal` 传递 principal, 缺少 principal 被拒绝,错误的 token 在到达核心之前会返回 401)。`python3 serve.py` 运行它。所有五个 端口现在都有两个 adapter 或一个经过验证的第二 adapter 路径,模块化主张在每一个上都成立。 - **两个执行层级同时武装。** `serve.py` 可以在 guard 模型处于 `enforce`(第一层级总线拦截 UNSAFE)并且模型通过第二层级网关(进程外 瓶颈)路由的情况下运行网络门,通过 `AIBODY_GUARD_MODE` 和 `AIBODY_MODEL_BASE` 控制。guard 模型采用可插拔的 `judge`,因此 DefenseClaw 或任何其他 judge 都可以为其提供支持。 - **两个真实的隔离 worker。** 一个 `researcher`(只读:recall + `repo_ls`)和一个 `coder`(读取,加上 受限在沙箱内受治理的 `repo_write`,每次写入都经过 DLP 门控和指纹准入,并且 无执行权限)。每个 worker 都有自己的由 cage 强制执行的工具白名单,只有核心才能调用它们 (委托默认是拒绝的,因此 worker 之间无法互相调用),并且两者都向内排放学习内容。 `build_governed(with_workers=True)` 注册了它们。这反映了正在运行的多 agent 集群 (researcher + coder)并对其进行了收紧:能力只能在 cage、门和漏斗背后呈现。 - **内存:** 1930 条笔记被迁移到一个副本中;确认了与源内存存储的召回一致性 (hit@12 0.913 = 0.913,delta 0.000)。 - **切换已验证且可逆。** `cutover_live.py` 在所有 1930 条真实笔记上运行了完整的绞杀者模式生命周期:影子双写(0 次失败),在实际查询上进行 `compare_recall` 一致性测试(重叠率 1.0,0 差异),切换让候选者提供读取服务,然后回滚,两种方式的读取都完好无损, 没有任何东西被破坏(回执记录在 `cutover-receipt.json` 中)。实时的源 daemon 切换仍然是一个 需要用户深思熟虑的、单独备份的操作;但它将要使用的机制现在已经在端到端得到了验证。 - **测试:** 93/93 单元测试 + `accept.py` 15/15 全通过。 ### 等待人工操作(每项只需一步) - 标注 50-100 个真实用例 → `calibrate.py` 将 guard模型从 observe 提升为阻断。 - 提供 `SCANNER_GATEWAY_TOKEN` → LocalScanner guard 生效。 - 在选定后切换实时的源 daemon → 切换机制已被证明是可逆的(见上文)。 从这里开始,AI Body 将通过每次添加一个 adapter 来引入下一个 worker、工具、模型或接口,从而实现增长。
标签:Python, Streamlit, 人工智能, 无后门, 本地部署, 架构框架, 模块化设计, 用户模式Hook绕过, 自动化修复, 访问控制, 逆向工具