Coding Agent Tool Execution & Environment 深度体系
目标:把 Coding Agent 的工具层理解为一套可证明、可恢复、可观测的 effect system,而不是“模型会调用几个函数”。
线上复核截止:2026-08-03。Tool/Environment 的逐文件源码判断固定到不可变提交
dfc55a5;同日公开main已继续推进至75395f6,其增量为 lifecycle hook/heartbeat contract,未改动本章审计的核心 tool files。文中明确区分固定源码事实、滚动版本事实、产品 contract、工程判断、实验结果与未知后端。
0. 先给出完整结论
一个工具调用不是:
result = function(args)
而是:
tool definition
+ model-produced intent
+ bound environment snapshot
+ resolved resources/effects
+ authority decision
+ scheduled execution attempt(s)
+ effect receipt / reconciliation
+ normalized observation
Coding Agent 的工具层同时承担五种职责:
- 能力接口:把文件、进程、Git、测试、IDE、浏览器、远端服务暴露给模型;
- effect control plane:在动作发生前解析目标、权限、冲突、风险与预算;
- execution data plane:真正管理进程、文件、网络、PTY、远端环境和输出流;
- evidence plane:把发生了什么固化成 receipt、artifact、diff、trace 与 verifier 输入;
- semantic adapter:把异构工具结果转成模型可消费、但不丢失关键语义的 observation。
工具层的首要质量标准不是“调用成功率”,而是以下乘积:
Tool-system quality
= intent fidelity
× execution fidelity
× state fidelity
× evidence fidelity
× authority compliance
任何一项为零,最终文本看起来正确也不构成可靠完成。
0.1 六个不可破坏的不变量
- Intent ≠ Effect:模型产生 tool call 只代表提议动作,不能代表动作已执行。
- Timeout/Cancel ≠ No Effect:超时和取消是控制面状态,不是副作用不存在的证明。
- Result ≠ Receipt:给模型看的摘要是有损 observation;receipt 才是执行事实。
- Success ≠ Postcondition:进程退出码为 0、HTTP 2xx、工具
isError=false都不自动证明用户目标成立。 - Retry requires semantics:没有幂等、dedupe 或 reconciliation contract,就没有安全自动重试。
- Authority binds resolved effect:权限判断必须绑定规范化后的真实目标和 effect,而不能只看工具名或模型字符串。
0.2 版本与证据边界快照
| 证据面 | 截止 2026-08-03 的固定点 | 使用边界 |
|---|---|---|
| Kimi Code | dfc55a5c |
只说明公开仓库该提交,不代表 Moonshot 内部生产部署 |
| JSON Schema | 2020-12 仍是 current version | schema 只证明实例符合 dialect,不证明业务/effect 语义 |
| POSIX | POSIX.1-2024 / Base Specifications Issue 8 | 约束可移植接口语义,不等于 Linux/macOS/Windows 实现完全一致 |
| LSP | 3.18 | 协议能力仍受 server、client、workspace configuration 与文档版本约束 |
| CDP | stable 1.3 是较小子集;tip-of-tree 持续变化 | 自动化端应绑定实际浏览器暴露的协议,不把 tip-of-tree 当稳定 API |
| MCP | 2026-07-28 Tools;Tasks 已迁移为独立 draft extension | Tasks extension 仍是 experimental,且 wire interoperability 不提供本地 effect policy 或 exactly-once |
| OpenTelemetry GenAI | core semconv v1.41 是本文引用的发布节点;独立 GenAI 仓库固定 9af08349,依赖 core v1.43.0、尚未发布 Schema URL,相关模型仍是 Development |
必须 pin 实际 model/依赖提交,不能把字段名当稳定 ABI |
Idempotency-Key |
WG draft-07 已于 2026-04-18 过期并归档 | 仅作设计参考,不是现行 RFC 或可假设的服务端 contract |
| 2026 论文 | 均按文末列出的 arXiv 版本;除注明的 non-archival workshop 外,无页面可见正式 venue | 数字是作者在特定 benchmark/harness/model 下的报告,不是全行业常数 |
1. 精确定义:工具系统里到底有哪些对象
1.1 Tool Definition
静态、可版本化的能力描述:
name / version / source;- 输入、输出 schema;
- 人类与模型可读的语义说明;
- capability 与 effect class;
- 可能访问的资源类型;
- 默认 timeout、输出上限、并发策略;
- permission 与 trust 要求;
- 兼容性、退役和 discovery 元数据。
当前发布版 JSON Schema 仍是 2020-12。它能验证 JSON 实例内可表达的结构和值约束,包括类型、必填、枚举、pattern/range、条件与组合约束;它不能自行验证路径边界、authority、部署后果或外部对象当前状态。后者属于 semantic preflight。
1.2 Tool Intent
模型提出的动作:
type ToolIntent = {
callId: string; // 逻辑调用身份
definitionVersion: string;
name: string;
rawArguments: unknown;
proposedAt: string;
turnId: string;
stepId: string;
};
Intent 还没有绑定:
- 实际路径、仓库、进程或远端资源;
- 当前 workspace 版本;
- 真实 effect set;
- 执行身份与权限;
- 某一次 attempt;
- 动作是否真的发生。
1.3 Resolved Execution
在 schema validation 之后、effect 发生之前,将意图解析成可审批、可调度的执行闭包:
type ResolvedExecution = {
callId: string;
normalizedArguments: unknown;
environmentSnapshotId: string;
authorityContextId: string;
accesses: ResourceAccess[];
effects: EffectSpec[];
preconditions: Predicate[];
postconditions: Predicate[];
idempotency: IdempotencyContract;
timeout: TimeoutContract;
cancellation: CancellationContract;
output: OutputContract;
run(signal: AbortSignal): Promise<RawExecutionResult>;
};
这是极其重要的深模块边界:模型字符串在这里变成 host 能理解的资源、effect 与政策对象。
1.4 Execution Attempt
一次真实执行尝试。逻辑调用与执行尝试必须分离:
call_id = 用户语义上的一次动作
attempt_id = transport/process 层的一次尝试
同一个 call_id 可能因为 pre-start transport failure 产生多个 attempt_id;但如果 effect commit 状态未知,不能直接再开新 attempt。
1.5 Effect Receipt
可用于 dedupe、恢复、审计和验证的事实记录:
type EffectReceipt = {
receiptId: string;
callId: string;
attemptId: string;
effectFingerprint: string;
commitState: "not_started" | "committed" | "partial" | "unknown";
targetVersionsBefore?: VersionVector;
targetVersionsAfter?: VersionVector;
externalOperationId?: string;
producedArtifacts: ArtifactRef[];
observedAt: string;
verifierEvidence?: EvidenceRef[];
};
Receipt 不是 stdout 的别名。比如“已创建 PR”的可靠 receipt 至少应包含 repository、PR number/URL、head SHA、base branch 和服务端 request ID;“已编辑文件”应包含 path、before hash、after hash、diff artifact。
1.6 Observation
给下一次模型推理的有损投影:
Observation = project(receipt, result, output policy, context budget)
它需要保留下一步决策所需的最小充分信息,但完整输出、二进制、大 diff 和详细 trace 应放到 artifact store,通过 handle 按需读取。
1.7 Verifier Evidence
独立于生成动作的检查证据:
- test report / exit code / failing cases;
- compiler diagnostics;
- Git diff / tree hash;
- LSP diagnostics snapshot;
- browser screenshot / DOM snapshot / network receipt;
- API read-after-write 结果;
- 用户或审批者的接受状态。
Verifier 不能只是复述不带保证的 tool result。若权威 receipt 的事务语义已经明确承诺某个 postcondition,它本身可以成为证据;receipt 未覆盖或风险更高的条件,才必须用独立 read-after-write、test、diff 或其他观测面验证。
2. 完整数据流与状态机
2.1 从模型输出到新世界状态
两个关键的 commit point:
- Intent commit:provider stream 中的 tool call 已经完整、合法,host 可以开始处理。半截 JSON 不能猜测补全后执行。
- Effect commit:底层系统已经接受或完成副作用。它可能发生在客户端收到响应之前,因此 crash 后可能进入
effect_unknown。
2.2 Tool Call 生命周期状态机
必须拒绝的错误建模:
started -> timeout -> failed -> retry
因为 timeout 后真实状态可能是 committed、partial、still_running 或 unknown。正确路径先 reconciliation,再决定是否重试、补偿或人工介入。
2.3 三套状态必须分开
| 状态域 | 例子 | 不能替代什么 |
|---|---|---|
| Control state | queued、running、cancel requested、detached | effect 是否发生 |
| Effect state | not started、partial、committed、unknown | 用户目标是否满足 |
| Evidence state | unobserved、receipt available、verified、conflicted | 执行是否还在运行 |
例如:进程可能已退出(control terminal),文件也已修改(effect committed),但日志丢失且未运行测试(evidence insufficient)。
3. Tool Contract:schema 只是最外层
3.1 一个完整 contract 应包含什么
| Contract 面 | 必须回答的问题 |
|---|---|
| Identity | 工具、版本、来源、实现与配置是谁? |
| Syntax | 输入输出形状是什么?未知字段如何处理? |
| Semantics | 每个字段的真实含义、单位、默认值、组合约束是什么? |
| Target resolution | 相对路径、别名、URL、branch、workspace 怎样规范化? |
| Preconditions | 执行前什么必须为真?由谁检查?检查绑定哪个版本? |
| Effects | 读、写、执行、联网、通信、权限变化、不可逆动作有哪些? |
| Postconditions | 什么才算成功?怎样独立验证? |
| Idempotency | 相同意图重复执行会怎样?key 的 scope/TTL/fingerprint 是什么? |
| Retry | 哪些错误可重试?effect unknown 时怎样 reconcile? |
| Cancellation | 取消传播到哪里?何时能确认停止?部分输出/副作用怎样处理? |
| Timeout | 是 deadline、detach 还是 kill?soft/hard timeout 分别是什么? |
| Streaming | progress、stdout/stderr、partial artifacts 的顺序和完整性怎样定义? |
| Backpressure | 消费端慢、输出过大、事件拥塞时怎样降载? |
| Concurrency | 读写资源集合、隐式全局资源、隔离级别是什么? |
| Errors | validation、policy、environment、execution、postcondition 如何分类? |
| Evidence | receipt、artifact、diff、request ID、trace 如何返回? |
| Data handling | 输出是否不可信、是否含秘密/PII、保留多久? |
3.2 Syntax validation、semantic validation、precondition 不是一回事
| 层级 | 例子 | 失败后是否能执行 |
|---|---|---|
| Parse | JSON 是否完整 | 不能 |
| Schema | timeout 是否正整数 |
不能 |
| Semantic validation | run_in_background=true 时是否有 description |
不能 |
| Target resolution | cwd 规范化后指向哪里 |
尚不能 |
| Security preflight | 是否越 workspace、碰敏感文件、走 symlink | 未授权不能 |
| State precondition | before hash、HEAD SHA、resource version 是否仍匹配 | 不匹配不能 |
| Business precondition | deploy target 是否允许、消息 recipient 是否正确 | 不匹配不能 |
高水平答案要指出 TOCTOU:precondition 检查与 effect commit 之间世界会变化。解决方式不是“检查一次”,而是:
- 把版本绑定进原子操作,例如 content hash CAS、Git blob identity、HTTP
If-Match; - 把检查与写入放进同一事务/服务端条件请求;
- 无法原子化时,在 receipt 里记录 before/after 版本并做冲突处理。
3.3 Postcondition 必须高于 transport success
| 工具结果 | 只能证明 | 不能证明 |
|---|---|---|
| shell exit 0 | 顶层命令按其约定成功退出 | 子进程正确、测试完整、目标满足 |
| HTTP 200/201 | 服务端接受并返回成功响应 | 最终一致状态已经可见、内容正确 |
edit isError=false |
编辑器报告写入成功 | 没覆盖并发修改、代码能编译 |
| test process exit 0 | 被实际执行的测试集通过 | 所需测试都被发现且没有缓存误命中 |
| Git commit created | 本地对象/引用已更新 | 用户修改没有被混入、远端已推送 |
| deploy accepted | 控制面接受部署 | 新版本健康、流量已切、可回滚 |
3.4 Tool description 也是协议,不是文案
模型会依据描述学习:
- 何时调用;
- 参数组合;
- 风险与 side effects;
- 结果格式;
- timeout 与 background 的行为;
- 下一步怎样读取 artifact 或验证。
因此 description 的回归会直接改变 policy。它应具备:稳定版本、契约测试、模型覆盖 eval;不能把决定性约束只写在描述里,host 还必须强制执行。
4. Effect Taxonomy:不是一条“危险等级”轴
4.1 六个最低 effect 类别
| Effect | 定义 | 例子 | 默认控制 |
|---|---|---|---|
| Read | 读取状态,不意图改变目标 | 文件读取、grep、Git status、GET | scope、秘密过滤、output budget |
| Write | 改变持久状态 | edit、写文件、Git index、数据库更新 | CAS/diff、权限、receipt、回滚 |
| Execute | 启动代码或进程 | shell、test、build、script、MCP server | sandbox、resource limits、process tree |
| Network | 发起网络连接或下载 | package install、curl、browser fetch | egress allowlist、DNS/IP/redirect policy |
| Communicate | 对人或外部系统产生可见表达 | 发消息、评论、PR、issue | recipient、content preview、身份、审计 |
| Irreversible / consequential | 难回滚或后果重大 | 删除数据、生产部署、支付、公开发布 | 独立 gate、明确 intent、强验证 |
注意:execute 常常是 effect 组合器。一条 shell 命令可以同时 read + write + execute + network + communicate + irreversible。因此把 Bash 标成一个固定风险级别是不成立的。
4.2 每个 effect 还要沿八个维度标注
Effect = operation
× target boundary
× scope/cardinality
× reversibility
× determinism
× privilege
× information flow
× user consequence
| 维度 | 低风险端 | 高风险端 |
|---|---|---|
| Boundary | task scratch | workspace → home → org → production |
| Cardinality | 单文件/单对象 | glob、recursive、批量、全租户 |
| Reversibility | pure read、new draft | overwrite、delete、publish、pay |
| Determinism | content-addressed local op | live UI、external mutable service |
| Privilege | unprivileged sandbox | secret-bearing admin identity |
| Information flow | local public data | secrets/PII 到外部网络或消息 |
| Visibility | private artifact | customer-facing / public communication |
| Temporal reach | one shot | cron、daemon、webhook、self-triggering automation |
4.3 Authority 决策公式
ALLOW iff
principal may use capability
AND effect is within delegated intent
AND resolved targets are in scope
AND data flow is allowed
AND environment trust is sufficient
AND risk budget is not exceeded
AND required approval is bound to this exact effect fingerprint
“用户批准了 Bash”不是可靠授权;“用户批准 git push origin feature-x,目标 repo/head SHA 与 preview 相符,审批尚未过期”才接近可执行授权。
4.4 Effect fingerprint
用于 approval binding、dedupe 与 audit 的 fingerprint 不应直接 hash 原始 JSON,而应 hash canonical semantics:
fingerprint = H(
tool version,
normalized operation,
canonical targets,
relevant payload digest,
authority principal,
environment snapshot,
semantic options
)
不要把 volatile 字段(timestamp、随机 request ID)混进去;也不要遗漏 recipient、branch、cwd、recursive flag 等会改变后果的字段。
5. 幂等、去重、重试与 crash boundary
5.1 四种常被混淆的性质
| 性质 | 含义 |
|---|---|
| Mathematical idempotence | 同一操作重复应用,最终状态不再变化 |
| API idempotency | 服务端按 key/fingerprint 将重复请求收敛为一次逻辑动作 |
| Deduplication | host 识别重复 intent,避免再次开始或复用旧 receipt |
| Reconciliation | effect 状态不确定时查询真实世界,判断是否已提交 |
PUT file=X 可能状态幂等,却仍会重复触发 webhook、更新时间或计费;DELETE 在 HTTP 语义上通常幂等,却可能第一次成功、第二次返回 404。Agent 关心的是 用户后果与可观测事件是否只发生一次,不只是最终字段相同。
5.2 安全重试决策表
| 失败发生点 | Effect 状态 | 自动重试? | 正确动作 |
|---|---|---|---|
| schema/preflight | not started | 否,先修参数 | 返回结构化可纠正错误 |
| scheduler 排队中取消 | not started | 仅用户仍需要时 | 新 attempt 可复用 call intent |
| connect 前失败 | confirmed not started | 通常可以 | jitter/backoff + budget |
| 请求已发送,未收到响应 | unknown | 不可盲重试 | idempotency lookup / reconciliation |
| process 中途退出 | partial/unknown | 视 effect | 检查 workspace、进程、外部 receipt |
| verifier 失败 | committed but postcondition false | 不是原样 retry | 诊断并生成修复动作或 compensation |
| observation 丢失 | committed, receipt exists | 不执行 | 重新投影/读取 receipt |
IETF HTTPAPI WG 的 Idempotency-Key draft-07讨论 key 的唯一性、有效期和 fingerprint 责任,但已于 2026-04-18 过期并归档;它只能作为历史设计参考,不是现行 RFC,更不能假设任意服务端都会遵守。Host 必须依据具体工具 contract 判断。
5.3 Exactly-once 不是一个布尔属性
跨进程/网络很难同时原子提交:
external effect commit
|| crash window ||
local receipt commit
可靠方案是业务级 exactly-once illusion:
- 先持久化 intent 与 idempotency key;
- 服务端按 key 接受/返回同一逻辑结果;
- 写入 external operation ID;
- crash 后以 key/operation ID 查询;
- 生成或恢复 receipt;
- 若服务端没有幂等能力,转成 at-most-once + 人工 resolution,或设计 compensation。
5.4 去重不能只看 toolName + rawArgs
要区分:
- same-step duplicate:一次模型响应里相同 effect;通常直接抑制;
- cross-step repeat:可能是合理 polling,也可能是无进展循环;
- same syntax, different world:文件或远端状态已变,不能简单复用旧结果;
- different syntax, same effect:相对/绝对路径、别名、参数顺序不同但语义相同;
- read retry:读取新状态可能有信息增益;
- write replay:必须依赖 idempotency/reconciliation。
因此 dedupe key 最好包含 canonical effect 和相关 state version;loop breaker 还需看“是否产生新证据”,而不是只数重复次数。
6. Cancellation、Timeout、Streaming 与 Backpressure
6.1 Cancellation 是协议链,不是一个 AbortSignal
完整传播链:
user interrupt
-> turn/step cancellation
-> queued tasks removed
-> approval request cancelled
-> tool execution signal
-> process group / remote request / browser action cancel
-> output stream drain or close
-> effect reconciliation
-> terminal event + partial artifacts
每一段都可能不支持强取消。正确 contract 至少区分:
cancel_requested:控制面已经发出请求;cancel_acknowledged:执行器接受取消;cancelled_confirmed:已确认不再继续产生 effect;cancelled_with_partial_effect:已停止,但留下部分状态;cancel_unknown:无法确认。
6.2 Timeout 有四种语义
| Timeout 类型 | 到时发生什么 | 典型用途 |
|---|---|---|
| Queue deadline | 尚未开始就过期 | 避免陈旧动作 |
| Soft execution timeout | 请求优雅停止 | build/test/process |
| Foreground detach timeout | 不再阻塞当前 turn,但任务继续 | 长 build/server |
| Hard kill timeout | 强制终止进程/容器 | 资源保护 |
必须在工具 schema/description/result 中说清楚。否则模型会把“超时移到后台”误解为“命令失败”,或把“客户端超时”误解为“服务端没执行”。
6.3 Shell process tree 的真实问题
杀掉 shell PID 不代表杀掉子孙进程。POSIX job control 以 session、process group 和 controlling terminal 建模;当前 POSIX.1-2024 General Terminal Interface规定:在 line discipline 启用 ISIG 且配置 interrupt character 时,该字符会向前台 process group 发送 SIGINT;“Ctrl-C 一定能停止全部子孙”并不成立。Node child process 文档则说明 detached 在非 Windows 平台会让 child 成为新 process group/session 的 leader,并明确后台进程与 stdio 的关系。
典型两阶段停止:
SIGTERM process group
-> grace period
-> verify descendants / wait
-> SIGKILL process group
-> drain stdout/stderr briefly
-> mark partial/unknown effects
Windows 没有完全等价的 POSIX signal/job-control 语义;process-tree cancellation 需要 Job Objects 或 tree-termination 等平台机制,而 restricted token、AppContainer、ACL/firewall 解决的是 authority 与 containment,不应和 signal 语义混为一谈。OpenAI 2026 年的 Codex Windows sandbox 工程说明明确记录:AppContainer 被评估但不适合其开放式开发工作流;文章所述方案组合了独立本地 principal、write-restricted token、ACL 与 firewall,并需要一次 elevated setup。它只证明 2026-05 的该架构快照,不代表 Codex 所有模式或 Windows sandbox 的普适 contract。
6.4 Pipe 与 PTY 决策
| 维度 | Pipe | PTY |
|---|---|---|
| 机器可预测性 | 高,stdout/stderr 可分 | 低,输出常合并并含控制序列 |
| TTY 检测 | false | true |
| 交互式程序 | 易挂起或改变行为 | 可用 |
| job control / Ctrl-C | 需显式 process group | 接近真实终端 |
| 颜色/progress UI | 通常关闭 | 可能产生动态重绘 |
| 密码/确认提示 | 应禁用并失败快 | 可能等待输入 |
| 适用 | tests/build/grep/script | REPL、调试器、TUI、需要交互的 CLI |
默认 Coding Agent 工具应优先非交互 pipe;host 可显式设置 NO_COLOR=1、TERM=dumb、GIT_TERMINAL_PROMPT=0 等环境来减少交互和动态输出。它们仍属于 environment manifest 的语义输入,尤其 CI=1 会改变部分 runner 的 watch、snapshot、warning 或失败行为,不能无条件注入后还声称实验环境未变。确实需要交互时再进入 PTY contract。PTY 是双向状态机,不是“更好看的 stdout”;Linux pty(7)把 PTY 定义为 master/slave 双向通道,slave 对进程表现为经典终端。
6.5 Streaming 不是最终结果的替代品
流事件可包括:
started -> stdout/stderr/progress/status/custom -> effect receipt -> terminal result
必须定义:
- event sequence 与每流单调
seq; - stdout/stderr 是否保序、是否合并;
- retry 后 sequence 如何区分 attempt;
- partial update 是否持久化;
- final result 是否包含完整性标记;
- 断线重连从哪个 cursor 恢复;
- UI 展示顺序与 provider tool-result 顺序是否不同。
流式输出可以让人看到进度,却不能作为 postcondition。最后必须有 terminal status 或明确的 non-terminal task handle。
6.6 Backpressure 的正确分层
process stdout
-> bounded byte buffer
-> policy-governed artifact sink
-> sampled/coalesced UI stream
-> bounded model observation
四层策略不同:
- 执行器层:必须持续 drain pipe,否则子进程可能因管道满而阻塞;
- artifact 层:按秘密/合规/容量与 retention policy 决定是否完整保留,可压缩、分片、redact、限 TTL 或明确禁留;
- UI 层:可合并 progress、限帧、丢弃中间动画;
- model 层:只给 head/tail、错误局部、统计与 artifact handle。
截断必须显式返回:truncated=true、已知的原始 byte/line count、retention/redaction policy 与 full_output_available;只有完整输出确实被保留时才提供 artifact handle。无声截断会制造 execution-alignment failure:模型以为“没有错误”,其实错误在被剪掉的尾部。
7. Concurrency:按 effect 冲突,不按 tool call 数量
7.1 Resource access set
每个 resolved execution 应声明:
type ResourceAccess = {
resourceType: "file" | "tree" | "git-index" | "ref" | "process" |
"port" | "cache" | "database" | "browser" | "remote-api";
canonicalId: string;
mode: "read" | "write" | "readwrite" | "execute" | "admin";
recursive?: boolean;
isolation?: "snapshot" | "serializable" | "best-effort";
};
最小冲突规则:
read/read -> usually parallel
read/write -> conflict if resource overlaps
write/write -> conflict if resource overlaps
all/* -> conflict
unknown effect -> conservative serialization
7.2 文件资源的难点
字符串路径不等于资源身份。冲突检测至少考虑:
.、..、绝对/相对路径;- case sensitivity 与 Unicode normalization;
- symlink、hardlink、bind mount;
- parent/child recursive overlap;
- glob 在执行时扩展出的动态集合;
- rename 改变 path-to-object 绑定,并可能改变旧路径、新路径及别名的冲突关系;同一文件系统内 rename 通常不改变底层 inode 身份;
- editor、formatter、build tool 可能改写额外文件;
- network filesystem 的一致性与缓存。
只做 lexical normalization 可阻止常见 ../ 逃逸,却不能证明 symlink 后的真实 inode 在边界内。强安全边界应优先依赖 OS sandbox/mount namespace;如果 host 必须在应用层判定,就要用 descriptor-based traversal、openat/no-follow 策略,并在最终 open 时绑定,不要先 realpath 再稍后打开而留下 TOCTOU。
7.3 隐式全局资源
即使两个命令写不同文件,也可能冲突:
- Git index / refs / object maintenance;
- package-manager lockfile 与全局 cache;
- 同一端口、socket、PID file;
- build directory、generated code;
- test database/schema;
- browser profile、cookie jar、active tab;
- rate limit、quota、deployment target;
- system package manager、daemon、keychain。
Shell 如果无法可靠分析 effect,应声明 all 或在隔离 workspace/sandbox 中并发。静态解析 shell AST 可以提高精度,却无法完全理解脚本、别名、子 shell、动态扩展和被调用程序的行为。
7.4 调度公平性和失败传播
冲突图只是第一步。调度器还要定义:
- 队列顺序与饥饿保护;
- 一个调用
stopBatchAfterThis后,后续未开始调用怎样结算; - 同批调用一个失败时,其他无关调用是否继续;
- cancel 是否只影响一个 attempt、一个 batch 还是整个 turn;
- result 给 UI 按完成顺序,给 provider 是否需按原 call order;
- 资源声明不足时如何检测和回退;
- 长任务持锁还是转为 snapshot isolation。
7.5 并发决策表
| 调用 A | 调用 B | 默认决策 | 备注 |
|---|---|---|---|
| 读文件 X | 读文件 X | 并行 | 绑定同一 snapshot 更好 |
| grep tree | 写 tree 子文件 | 串行或 snapshot | 否则搜索结果撕裂 |
| edit X | edit Y | 可并行 | 仍需检查 formatter/build 侧写 |
| edit X | test read-only snapshot | 可并行于隔离 snapshot | 在 live workspace 可能读到中间态 |
git status |
edit source | snapshot 或串行 | status 结果可能瞬间过时 |
git add |
git commit |
串行 | 共享 index/refs |
| 两个 tests | 两个隔离 temp DB/ports | 并行 | 必须真实隔离 |
| 两个 shell unknown | unknown | 串行 | 除非各自在独立 sandbox |
| 两个外部 POST | 不同 idempotent resources | 视 quota/identity | 还需 rate limit |
8. Tool Result Normalization:把执行事实变成可用观察
8.1 统一 envelope,而不是统一掉语义
type NormalizedToolResult = {
callId: string;
attemptId?: string;
toolName: string;
status:
| "succeeded"
| "failed"
| "denied"
| "cancelled"
| "timed_out"
| "detached"
| "effect_unknown";
error?: {
domain: "input" | "policy" | "environment" | "execution" |
"transport" | "postcondition" | "internal";
code: string;
retryability: "no" | "after_fix" | "safe" | "reconcile_first";
message: string;
};
structured?: unknown;
modelText: string;
artifacts: ArtifactRef[];
receipt?: EffectReceipt;
truncation?: {
truncated: true;
originalBytes?: number;
strategy: "head" | "tail" | "head_tail" | "summary";
fullArtifact?: ArtifactRef;
};
provenance: Provenance;
};
这个 envelope 统一生命周期、错误和证据;它不应该把每种工具都压成一段字符串,也不应该丢掉:exit code、HTTP status、diagnostics range、Git SHA、browser target ID、task handle 等领域语义。
8.2 Protocol error 与 tool/domain error
| 类型 | 例子 | 模型应该做什么 |
|---|---|---|
| Protocol | JSON-RPC framing、unknown method、transport disconnect | host/connector 处理,必要时重连 |
| Input | schema invalid、unknown field | 修正参数 |
| Policy | denied、approval needed | 不伪装成执行失败;改变方案或等待授权 |
| Environment | binary missing、dependency/version 不符 | 检查环境或选择替代工具 |
| Execution | exit nonzero、HTTP domain error | 使用结构化诊断 |
| Postcondition | 写成功但 read-back 不匹配 | 不原样重试,重新诊断 |
| Internal | normalization/hook/storage bug | fail fast,保留原始 evidence |
MCP 2026-07-28 Tools明确:工具执行或领域错误应放在 tool result 内并设 isError=true,使模型有机会修正;unknown tool、malformed request、server/internal failure 等仍是协议级 JSON-RPC error。即便采用别的协议,这个分层仍然成立。
8.3 双通道输出
同一个结果至少有两种消费者:
- Human/UI view:实时、可读、带 diff/progress/风险信息;
- Model view:紧凑、结构化、明确下一步、避免大噪声。
它们可以有不同展示顺序和截断策略,但必须引用同一个 call_id / receipt_id / artifact_id,否则调试时无法对齐。
8.4 输出是 untrusted data
repo 文件、测试日志、网页、MCP result、compiler error 都可能包含 prompt injection。结果 envelope 应带 provenance/trust label:
source = repository | process | network | user | system | external_agent
trust = trusted_policy | trusted_code | untrusted_content | secret
模型可阅读 untrusted content,但它不能因此获得新 capability、扩大 scope 或改变系统策略。高风险 effect 仍通过独立 policy gate。
8.5 结果压缩应保留什么
优先保留:
- terminal status 与 error code;
- 真实 target 与关键 version;
- 最小失败局部:文件/行、stack root cause、failed tests;
- truncation/partial/unknown 标记;
- receipt/artifact handle;
- 下一步可执行的恢复信息。
不要让 LLM“总结”掉 exit code、失败数量、changed files、未完成状态或安全警告。
9. Coding Agent 关键工具域
9.1 File / Read / Write / Patch
Read contract
读取不只是 read(path):
- path 必须 canonicalize,并绑定 workspace/snapshot;
- 限制 bytes/lines,识别 encoding/BOM/line endings/binary;
- 返回 content hash、mtime/size 只能作辅助,不应把 mtime 当强版本;
- symlink policy 与秘密文件策略明确;
- 大文件分页必须稳定,不因前面插入行导致页漂移;
- observation 标记 truncated 和 remaining range。
Write contract
安全写入至少需要:
read/bind expected version
-> generate minimal change
-> validate target and permissions
-> write temp file
-> fsync as durability requires
-> atomic rename where filesystem permits
-> read back / hash
-> emit diff + receipt
Linux rename() 对同一文件系统内目标替换提供原子可见性,rename(2)明确说明目标存在时会原子替换;这不等于持久性已经落盘,也不自动跨文件系统、对象存储或网络文件系统成立。
Edit / Patch contract
三种常见策略:
| 策略 | 优点 | 失败模式 |
|---|---|---|
| exact-string replace | 简单、可解释、天然要求上下文 | 重复片段、并发修改、格式漂移 |
| unified patch | 多文件、可审阅、带上下文 | hunk drift、path escape、binary/mode |
| AST transform | 结构正确、适合机械重构 | parser/version/language coverage、格式丢失 |
安全编辑原则:
old_string要求唯一,或明确replace_all;- 绑定 before hash,提交时 CAS;
- patch path 不能越 workspace;
- 默认全 patch 原子应用,不接受一半 hunk 悄悄成功;
- 冲突返回
expected / actual / diff,不要覆盖; - 写后运行 parse/format/局部 diagnostics;
- diff 是 receipt 的一部分,不是 UI 装饰。
Git 官方 git apply支持 --check、--index、3-way,并默认在任一 hunk 失败时不触碰 working tree;--reject 会改变为部分应用,Agent 必须显式知道这种语义。
9.2 Shell / Process / PTY
Shell 是最强、最便宜、也最难证明的 capability-composition language。
Shell contract 至少绑定
- shell binary 与版本、是否 login/interactive;
cwd、environment allowlist、PATH 来源;- stdin 是否关闭,是否允许 prompt;
- stdout/stderr pipe 或 PTY;
- foreground/background/detach;
- timeout、signal、kill tree、drain grace;
- network、filesystem、secret、resource sandbox;
- max output、artifact path;
- exit code/signal/core dump;
- shell parser/approval fingerprint;
- process/task ID 与恢复接口。
常见 shell 隐性 effect
command substitution: $(...)
redirection: >, >>, 2>, heredoc
pipeline: upstream/downstream partial success
short-circuit: &&, ||
subshell / background: (...), &
globs and expansion
aliases/functions/shell startup files
scripts invoked indirectly
package-manager lifecycle hooks
Git hooks
test/build plugins
所以静态命令预览只是一条风险信号,不能构成安全沙箱。
Exit code 语义
- pipeline 默认常返回最后一段命令状态;是否
pipefail会改变结果; grep的 1 可表示“无匹配”而非执行故障;- test runner 可能在“没有发现测试”时返回 0 或特殊码;
- shell 被 signal 终止和程序主动返回非零应区分;
set -e有复杂例外,不能当事务语义;- 顶层命令 0 不证明后台进程或 spawned daemon 健康。
9.3 Git:Working Tree、Index、Objects、Refs、Remote 是不同状态
一个严谨 Coding Agent 必须能回答:改变发生在哪层?
| 动作 | 主要 effect | 风险 |
|---|---|---|
| edit file | working tree | 覆盖用户未提交改动 |
git add |
index | 把不相关内容放入 staged set |
| commit | objects + local ref | identity/message/hooks/signing |
| rebase/reset | refs + index/worktree | history/用户改动丢失 |
| push | remote refs + network | 外部可见、可能触发 CI/deploy |
| PR create/comment | communicate + remote state | 对外表达与身份后果 |
Agent 操作 Git 的不变量
- 开始前识别真正 git root、worktree、branch、HEAD、upstream;
- 分开 tracked/untracked、staged/unstaged、conflicted;
- 不把既有用户修改归功于 Agent;
- 不用 destructive reset/clean 覆盖不确定状态;
- commit 只包含已审计的 intended diff;
- push 前绑定 remote URL、refspec、expected old remote SHA;
- hooks、submodules、sparse checkout、LFS、worktree 都可能改变语义;
- Git command 使用 machine-readable
--porcelain -z等稳定输出,避免解析本地化人类文本。
Git worktree 文档说明多个 worktree 共享 objects、普通 refs 和默认 repository config;每个 worktree 有独立的 HEAD、index,以及若干 pseudo/per-worktree refs。只有启用 extensions.worktreeConfig 后,config.worktree 才提供每 worktree 的配置覆盖。因此“不同目录”不等于完全没有共享冲突。Git 用户手册也明确这一分层。
9.4 Build / Test / Dependency / Cache
构建和测试结果应绑定与结论相关的 reproducibility envelope,并声明 hermeticity 等级、已知未捕获输入与外部依赖;现实系统很少能证明 manifest 绝对“完整”。最低记录包括:
source tree hash
lockfile hashes
toolchain/compiler/runtime versions
OS/arch/kernel/container image
environment allowlist
network mode
dependency registry/mirror
build flags/features
test selection/sharding
cache key/provenance
random seed/timezone/locale
external service fixtures
否则两次“同样的 test command”不是同一个实验。
测试成功的证明链
discovery evidence
-> selected tests
-> actual executed test IDs
-> results + duration + retries
-> coverage/mutation/regression oracle as needed
-> artifact and environment manifest
要特别检测:
- zero tests discovered;
- cached success 对应旧 source/config;
- flaky retry 把不稳定掩成通过;
- test process 退出前 child process 泄漏;
- only-focused tests (
.only)、skip、quarantine; - timeout 后部分报告被当完整;
- formatter/generated files 产生未审计 diff。
Cache 是性能系统,也是正确性/安全系统
cache key = H(all semantic inputs)
漏掉 compiler flags、environment、dependency mirror、secret-dependent output 或 platform,会产生 false hit。Docker 官方 cache invalidation 文档指出,普通 RUN cache 主要依赖命令字符串,并不会检查容器内部随后变化的文件;build secrets 的内容也不自动进入 cache checksum。Agent 必须理解具体 build system,而不是笼统相信“cache 命中”。Docker cache optimization还说明共享 cache mount 的并发约束,例如 apt cache 需要 sharing=locked。
9.5 Search:Lexical、Symbol、AST、Graph、Semantic
| 搜索面 | 最擅长 | 盲点 |
|---|---|---|
lexical (rg) |
精确标识符、错误字符串、配置键 | rename、动态语言、语义别名 |
| file/glob | 快速缩小目录/类型 | 不知道代码关系 |
| symbol index | definition/reference | index freshness、生成代码、动态 dispatch |
| AST/tree-sitter | 语法结构、机械匹配 | 不完整语义、macro/type resolution |
| LSP | language-aware definition/reference/diagnostics | server 状态、workspace config、版本同步 |
| graph | import/call/build/ownership | 图构建成本和不完备性 |
| semantic retrieval | 自然语言概念 | exact evidence 与版本漂移 |
| Git history | why/when/owner/regression | history 噪声、squash、重写 |
好的 repository exploration 是假设驱动的多轮策略:
issue evidence
-> cheap lexical/file probes
-> candidate symbols/modules
-> language/graph queries
-> read minimal surrounding code
-> test or trace falsification
-> update ranked hypothesis
2026 年 SWE-Explore v1用 848 个 issue、10 种语言、203 个 repo,把探索单独评为 coverage、ranking 与 context efficiency;它发现现代方法的 file-level localization 已较强,区分度更多来自 line-level coverage 和高效排序。这说明“有没有搜索工具”远不够,必须评测在固定 line budget 下拿到了哪些决策性证据。其 ground truth 来自至少两条成功修复轨迹所读区域的交集,再经模型 refinement 与人工审计;它是 useful context 的经验近似,不是“未被读到的代码都无关”的证明。论文报告的 downstream correlation 只来自 150-task 子集,也不能外推为所有 repo 的因果关系。
9.6 LSP / IDE / AST
LSP 是 editor 与 language server 的 JSON-RPC 协议层。截至复核日,官方站点列出的最新规范为 LSP 3.18,其价值是复用 completion、definition、references、rename、diagnostics、workspace edit 等语言能力。
Agent 接入 LSP 时必须处理:
- initialize capability negotiation;
- workspace folders、project root 与 config;
- 跟踪
didOpen与didChange携带的 document version;明确didSave只携带TextDocumentIdentifier(可选正文),不携带 version,保存后要靠本地状态或 resync 建立版本对应; - diagnostics 对应哪个 document version;
- request cancellation 与 progress;
- server crash/restart、index warming;
- workspace edit 的版本与冲突;
- generated files、multi-root、monorepo;
- LSP result 与 disk snapshot 不一致;
- rename/refactor 后由 compiler/test 独立验证。
最危险的误区:把 LSP diagnostic 当实时真相。它只对 language server 已同步的文档版本、配置和依赖图成立。每个结果应带 server identity、workspace/config hash、document URI/version;应用 workspace edit 前再做版本检查。
9.7 Browser / Computer Use
浏览器工具同时具有:
- read:DOM、accessibility tree、screenshot、network;
- write:form、cookie、local storage、download;
- network:任意站点/redirect;
- communicate:submit、post、send;
- irreversible:purchase、delete、publish。
浏览器状态不是截图一张图:
browser context/profile
-> target/tab/frame
-> navigation/document version
-> DOM + accessibility + visual state
-> cookies/session/identity
-> pending network/dialog/download
Chrome DevTools Protocol按 DOM、Runtime、Network、Debugger 等 domain 暴露命令与事件。官方同时说明:tip-of-tree 频繁变化且不保证向后兼容;stable 1.3 是 Chrome 64 起的较小子集。Agent connector 应 pin 兼容的 browser build/schema,或从实际 browser 的 /json/protocol 读取能力,并持有 target/frame/execution-context ID,不能只凭“第 2 个按钮”。
高风险动作应在提交前重新验证:origin、active identity、recipient/object、amount/content、按钮语义;提交后读取 server receipt,而不是仅看页面出现绿色 toast。截图适合人类审计,DOM/network receipt 更适合确定性验证,两者互补。
9.8 Network / External API / Communicate
网络工具至少控制:
- DNS resolution 与 rebinding;
- URL scheme、hostname、IP range、port;
- redirect 每一跳;
- localhost、metadata service、Unix socket;
- TLS/certificate/proxy;
- request/response size、stream、decompression bomb;
- auth principal 与 token scope;
- rate limit、retry-after、quota;
- idempotency key、conditional request;
- secret redaction 与 data egress;
- SSRF、prompt injection、malicious download。
Communicate effect 要额外绑定:
sender identity + recipients + audience + exact content digest
+ visibility + edit/delete ability + thread/context + attachments
“创建草稿”和“发送”必须是不同 capability;“创建本地 commit”和“push/开 PR”也必须分离。
9.9 MCP / Plugin / Remote Tool Discovery
远端工具协议解决的是 discovery、transport 和 interoperability,不会自动解决 effect、authority、idempotency 或 trust。最新的 MCP 2026-07-28 Tools要求 server 声明 tools capability,通过 tools/list 发现工具;只有 client 先通过 subscriptions/listen 订阅并请求 toolsListChanged: true 后,server 才用相应 notification 告知 catalog 变化。工具定义、description、annotations、结果内容仍是 server 提供的数据,client 不能把它们直接当本地安全策略。
Tasks 已不再以 2025-11-25 core wire protocol 为当前依据,而是迁移为 extension id io.modelcontextprotocol/tasks 的 draft Tasks extension,通过每请求 capability negotiation 使用 tasks/get、tasks/update、tasks/cancel 等方法。它与旧协议不兼容且仍属 experimental:task result 是 server-directed polymorphic result;取消是 cooperative、eventually consistent,tasks/cancel 的空 ACK 只证明请求被接受,任务仍可能以非-cancelled 终态结束。Host 仍需自行建模 partial/unknown effect 与 reconciliation。
一个可靠 registry entry 应绑定:
connector/server identity
+ protocol version and negotiated capabilities
+ authorization scope
+ deterministic catalog digest / definition fingerprint
+ input and output schema dialect
+ transport and trust policy
+ tool provenance and lifecycle
关键边界:
- tool name 规范只要求在单个 server 内 SHOULD 唯一,不是协议保证;聚合多个 server 时必须使用稳定 connector identity 做 namespace,不能依赖可能重名的
serverInfo.name; - catalog 可分页、缓存并变化;收到已订阅的 list-changed notification 或 TTL 到期后应重新发现,已 resolve/审批的执行仍需绑定原 definition fingerprint,不能让同名新定义替换旧语义;
- 工具集合可以随请求 authorization scope 不同,但不应被同一 connection 上其他请求的隐式副作用改变;缓存键必须含 principal/scope;
inputSchema只验证调用形状;client 还要做本地 effect resolution、permission 与 sandbox。server 的 behavioral annotations 默认不可信;- 有
outputSchema时 server 必须返回符合 schema 的 structured result,client 仍应验证;验证失败是 connector/protocol contract failure,不能把畸形数据包装成成功; - resource link、embedded resource、text/image/audio 都是 untrusted output;URI 不能绕过 client 的 filesystem/network policy;
- 远端 state 不能依赖隐式 connection continuity。MCP 2026 的 non-normative guidance 要求用显式 opaque handle 串联有状态调用;server 每次仍需重新检查 caller 对 handle 所指资源的权限,并定义 lifetime/expiry;
input_required是同一逻辑工作流的多轮状态,不等于原请求失败后重试。规范只定义可选 stringrequestState,要求 client 作为 opaque value 原样回送;把它在 server 端绑定 tool、principal、arguments digest 与 expiry 是推荐 hardening,不是 MCP 的规范要求。用户拒绝/取消仍必须成为可审计状态;- plugin/MCP server 本身是 supply-chain 与 code-execution 边界:版本、签名/来源、更新策略、secret scope、egress、resource limits、日志与卸载后残留都要纳入环境 manifest。
因此 MCP client 的正确职责不是“把远端 schema 原样塞给模型”,而是:
discover untrusted remote capability
-> validate and namespace definition
-> project into local effect contract
-> bind local policy, identity and environment
-> execute through connector
-> validate output and record remote receipt
-> expose bounded observation
协议互通扩大了工具面,也扩大了 blast radius;client-side control plane 不能下放给 server description。
10. Sandbox 与 Remote Environment:限制能力,不是相信行为
10.1 Sandbox 的目标函数
Risk heuristic ≈ probability of harmful outcome × reachable impact
这是用于拆解风险的启发式,不是可校准的精确公式。模型行为防线主要降低概率;sandbox、least privilege、egress control、ephemeral identity 主要缩小 blast radius。两者互补,不能互相替代。
10.2 一个实际 sandbox 的隔离维度
| 维度 | 需要控制的对象 |
|---|---|
| Filesystem | read roots、write roots、mounts、symlinks、devices、tmp |
| Network | namespace、DNS、HTTP/SOCKS proxy、domain/IP/port、redirect |
| Process | PID namespace、process tree、signals、ptrace、daemon |
| Identity | UID/GID/token/SID、cloud/service account、Git identity |
| Secrets | injection-on-demand、scope、non-exportability、redaction |
| OS enforcement | seccomp-BPF syscall filtering、macOS Seatbelt profile、Windows restricted token/ACL/WFP/Job Objects;具体组合取决于 threat model |
| IPC | Unix socket、named pipe、shared memory、keychain/credential helper |
| Resources | CPU、memory、disk、inode、pids、wall clock、GPU |
| Persistence | ephemeral overlay、workspace mount、artifact export |
| Supply chain | base image、tool binary、MCP/plugin、package registry |
容器不是天然安全边界;VM 也不是天然正确环境。需要回答具体威胁模型、host kernel exposure、mount/egress/credentials 和更新策略。
10.3 Filesystem 与 network 必须同时收敛
Anthropic 2025 年发布的 Claude Code sandboxing基于 Linux bubblewrap 与 macOS Seatbelt,强调 filesystem 和 network 双重隔离,并报告其内部使用中 permission prompt 减少 84%。其开源 sandbox runtime默认拒绝写入和 network,但默认允许读取,除非另配 denyRead;violation monitoring 截至复核日只在 macOS 可用。该仓库仍明确标为 Beta Research Preview,其 Windows Alpha runtime 也不等于 Claude Code 产品已经在 native Windows 使用同一完整集成,不能把它当稳定的跨平台安全标准。
Filesystem + network containment 是必要维度,但仍不充分:domain allowlist 本身就是 capability grant,若不绑定 identity、credential provenance 与请求语义,攻击者仍可能借允许域外传。Anthropic 2026 年的 containment 总结披露过经允许的 api.anthropic.com、使用攻击者凭据外传的路径,说明“域名正确”不等于“调用者与数据流可信”。同样,Claude Code 的 OS sandbox 直接包围 Bash 及其 descendants;Read/Edit/Write permission 与 Computer Use 属于其他控制面,不能笼统宣称一个 shell sandbox 已覆盖所有工具。
Fail-closed 也必须显式配置:该 runtime 在 sandbox 不可用时可以告警后 fallback 到 unsandboxed execution;高风险部署应启用 sandbox.failIfUnavailable=true,并按 threat model 禁用 escape hatch。这里描述的是该实现快照,不是所有 sandbox 的通用默认值。
单边隔离不足:
- 只限写不禁网:仍可能读取/泄露秘密,或下载并执行供应链代码;
- 只禁网不限文件:可改 shell rc、Git hooks、PATH executable,等待未来高权限进程触发;
- 只做应用层 path check:子进程仍可能直接 syscall 越界;
- 只做 permission prompt:用户会审批疲劳,也难评估 shell 复合 effect。
Anthropic 2026 年 containment 工程总结报告其遥测里用户批准约 93% permission prompts,用来说明 prompt 本身并非强安全边界;同一文章也提醒 containment 的复杂失败面。这个数字是其产品数据,不应无条件外推,但结构结论成立:高频低信息审批会退化。
10.4 Local、ephemeral sandbox、persistent devbox
| 环境 | 优势 | 核心风险 | 适合 |
|---|---|---|---|
| 用户本地 workspace | 最真实、依赖完整、反馈快 | 私有文件/秘密/未提交改动、blast radius 大 | 高互动、小范围任务 |
| Ephemeral sandbox/VM | 易销毁、快照、并发;绑定 source/image/toolchain/network/identity/seed/fixtures 后才可重放 | 环境准备/依赖冷启动、与本地漂移;真实隔离强度取决于底层 primitives | 自动化、评测、批量任务 |
| Persistent devbox | cache/索引/依赖热、长任务 | stale state、跨任务污染、secret residue | 大 repo、持续开发 |
| Remote production-like | 最接近真实部署 | 权限、成本、数据与不可逆后果 | 受控验证/部署阶段 |
选择不是“安全 vs 方便”二元,而是把真实环境依赖拆成:source snapshot、dependency snapshot、identity、secret、network、cache、external fixtures,然后只持久化真正有价值的部分。
10.5 Environment snapshot manifest
type EnvironmentManifest = {
source: { treeHash: string; dirtyDiffArtifact?: string };
platform: { os: string; arch: string; kernel?: string };
runtime: Record<string, string>;
toolchain: Record<string, string>;
dependencies: { lockHashes: string[]; imageDigest?: string };
environment: { allowlistedKeysHash: string; locale: string; timezone: string };
networkPolicyVersion: string;
sandboxPolicyVersion: string;
identityRef: string;
cacheNamespace: string;
externalFixtures: Record<string, string>;
createdAt: string;
};
不要把秘密值写入 manifest;记录 secret identity/scope/version 的不可逆引用即可。
10.6 Dependency 与 build 环境
依赖安装不是无害准备步骤。它可能:
- 运行 pre/post-install scripts;
- 访问网络和私有 registry;
- 修改 lockfile 或 generated code;
- 读取环境变量/credential helpers;
- 污染全局 cache;
- 通过 dependency confusion 获取错误包;
- 改变 toolchain resolution 和 PATH。
可靠策略:
- lockfile + registry/mirror pin;
- install scripts 作为 execute effect 明示;
- ephemeral credential、least scope、禁止写入日志;
- cache 按 trust/source/lock hash 分区;
- package provenance/SBOM;
- 离线或 allowlisted network 模式;
- 安装前后 workspace diff 与 dependency manifest。
10.7 Secret boundary
首选:secret 不进入模型 context。通过 broker 在已批准的 tool execution 时注入短期、最小 scope credential;工具输出和 trace 默认 redaction。需要防止:
env、set、crash dump、stack trace 泄露;- shell history、process argv、
ps可见; - child process 继承整个环境;
- artifact/cache 保存秘密;
- browser cookie/profile 跨任务复用;
- tool output 被模型转发到外部。
10.8 Sandbox violation 不是自动重试信号
EPERM 可能表示:
- 正确阻止恶意/越界行为;
- 合法依赖未声明;
- path canonicalization/平台适配错误;
- sandbox policy drift;
- 工具试图走备用路径。
结果应返回被阻止的 capability、resolved target、policy branch 和建议的最小权限变化,但不能把敏感路径全文暴露给不可信模型/日志。
11. Execution Alignment:推理、工具反馈、世界状态与证据必须同向
11.1 精确定义
Execution alignment 不是价值对齐的同义词。这里指:
the agent's next belief and action remain causally grounded in
actual tool feedback + current workspace state + required output contract
四个对齐面:
| 对齐面 | 问题 |
|---|---|
| Intent alignment | tool effect 真的是当前计划需要的吗? |
| State alignment | 模型理解的 workspace/environment 是否仍是当前状态? |
| Feedback alignment | 下一步是否正确吸收 tool success/error/truncation? |
| Evidence alignment | 完成声明是否由 verifier/receipt 支持? |
11.2 典型失配
- 测试失败,但模型继续按原假设写代码;
- command timeout 后假设没有改文件;
- grep 无结果是因为路径/ignore 规则,却推断符号不存在;
- output 被截断,模型把缺失尾部当成功;
- LSP index stale,模型相信旧 references;
- edit 冲突却继续基于旧 diff;
- browser 点击后页面导航到另一账号/环境;
- package install 改了 lockfile,模型没检查;
- background task 仍运行,模型启动冲突的第二个 server;
- tool 返回自然语言“成功”,没有 server-side receipt;
- final answer 声称“通过全部测试”,实际只跑了一个 targeted test。
11.3 First Bad Effect Decision
失败分析不要从最终错误倒推一个笼统“模型 hallucination”。沿轨迹找到第一个让世界或信念偏离正确路径的决定:
expected state before step
-> selected tool and intended information/effect
-> actual resolved effect
-> actual result/receipt
-> agent interpretation
-> next action
根因可落到:definition、schema、normalization、preflight、policy、scheduler、execution、environment、observation、model interpretation 或 verifier。
11.4 2026 实证信号
- Harness-Bench v1在 106 个 sandboxed offline tasks、5,194 条轨迹上发现明显的 model-harness pairing 差异,并把“合理推理脱离工具反馈、workspace state、evidence 或输出 contract”归为 recurring execution-alignment failures。任务是人工审查的本地离线工作流;5,194 条是配置轨迹,不是 5,194 个独立任务,也不能把完整 harness 差异归因到单一组件。
- Claw-SWE-Bench v1在 full-350、同一 GLM 5.1 下,bare/minimal direct-diff adapter 为 19.1%,full adapter 达 73.4%;固定 OpenClaw 时 observed model spread 最大为 29.4pp,固定 Qwen 3.6-flash 时 observed harness spread 最大为 27.4pp。前者是能否可靠满足 SWE-bench workspace/patch/scoring contract 的 diagnostic comparison,不是 full adapter 内部组件的消融;这些数字只属于该实验。
- 2026 年 tool surface ablation v1在 Artifact 上 n=93、SWE Mini 上 n=100,以 3 个 seeds、两个 agent-model pair 比较
baseline、bash_only与code_only:bash_only仍保留 read/glob/grep,code_only是单个 MCP 工具中的 persistent Python+Bash REPL,并非“只有裸 shell”。论文发现 pass rate 在其单元格内统计相近,而 cache-adjusted cost 依赖任务 regime 与 agent design。它是 KDD 2026 Agentic SE workshop 的 non-archival preprint,结论应视作新信号而非普遍定律;关键启示是工具面要同时评 outcome、cost 和 harness 适配,不能凭直觉断言“越多越好”。
11.5 Alignment guardrails
- observation 明确 status、partial、truncation、state version;
- tool error 提供结构化 recovery class;
- write 后 read-back/diff,execute 后 receipt;
- 关键阶段插入 verifier,而非只在结尾验证;
- background/remote tasks 作为显式 task handle;
- state-changing action 前检查当前 snapshot;
- 重复动作要求声明预期新信息;
- final claim 绑定 evidence IDs;
- 评测 first bad decision,不只看最终 pass/fail。
12. 关键架构决策表
12.1 Structured tool 还是 shell
| 条件 | 选择 |
|---|---|
| 高频、语义稳定、effect 高风险 | structured tool |
| 需要强 schema、receipt、idempotency | structured tool |
| 低频长尾、本地开发探索 | shell |
| 多个现成 CLI 组合且 sandbox 强 | shell |
| 需要精确 permission/retry | 不要只暴露 shell |
| 工具面过大、模型选择成本高 | shell/execute-code 或动态披露,但做受控 ablation |
深层判断:structured tool 把语义从 prompt/字符串提升到 host contract;shell 提供长尾组合能力。顶级系统通常两者并存:高后果动作用深 contract,开放式本地探索用强 sandbox 下的 shell。
12.2 Exact edit、patch 还是 AST
| 任务 | 优先工具 |
|---|---|
| 单点、小范围、已知上下文 | exact edit + before hash |
| 多文件可审阅变更 | atomic patch + check |
| 大规模结构化重构 | AST/LSP workspace edit + version binding |
| unknown language / broken syntax | text patch |
| 格式敏感、macro/生成代码 | language-specific tool + compiler verifier |
12.3 Local 还是 remote sandbox
| 主导条件 | 选择 |
|---|---|
| 需要私有本地状态、低延迟互动 | local + narrow sandbox |
| 高自治、长任务、批量并发 | ephemeral remote |
| 大 repo 冷启动昂贵 | persistent devbox + snapshot discipline |
| 生产凭证/后果 | isolated executor + explicit approval + receipt |
| 可复现评测 | pinned offline sandbox |
12.4 何时并行
| 是否知道精确 access set | 是否隔离 snapshot | 决策 |
|---|---|---|
| 是,互不冲突 | 任意 | 并行 |
| 是,有冲突 | 否 | 串行 |
| 有冲突 | 是,结果可 merge | 并行后合并/冲突处理 |
| 不知道 | 强隔离 | 可并行,资源预算限制 |
| 不知道 | 共享 live state | 保守串行 |
12.5 Retry policy
| Tool 类 | 默认 retry |
|---|---|
| pure local read | transient failure 可有限重试 |
| content-addressed read | 可重试 |
| file write with CAS | conflict 不重试原写,重新读取重算 |
| shell | 默认不自动重放 |
| external GET | 条件请求/退避 |
| external POST | 仅有服务端 idempotency contract |
| communicate/deploy/delete | reconciliation first,通常需强 gate |
12.6 Approval 还是 sandbox 自动允许
下表不是行业通用默认,而是在这些前提下的风险分级示例:用户已经委托该任务;workspace snapshot 可恢复;敏感路径与 Git control path 被排除;进程树、本地 IPC 和 network policy 受控。任何前提不成立,都要收紧为 ask/deny。
| Effect | Sandbox 可确定收敛? | 默认 |
|---|---|---|
| workspace 内可回滚 edit | 是 | 自动 |
| scoped read,无秘密 | 是 | 自动 |
| 测试/构建,禁网限资源 | 是 | 自动 |
| workspace 外读取/写入 | 部分 | ask/deny |
| network egress | 需 host/target policy | allowlist 或 ask |
| push/PR/message | 用户意图不可纯技术判定 | preview + ask/explicit delegation |
| production/delete/pay | 否 | 强制确认或禁止 |
13. 极端案例与正确处理
| 案例 | 错误实现 | 正确处理 |
|---|---|---|
| Provider 在 tool JSON 中途断流 | 猜补 JSON 并执行 | intent 未 commit,拒绝执行;保留 wire error |
| POST 已发出后连接断 | 自动再 POST | effect unknown,按 idempotency key 查询 |
| Bash timeout 时已改三文件 | 标为“失败,无变化” | timeout + partial/unknown,diff/reconcile |
| Ctrl-C 只杀 shell | 认为 task 已停止 | kill process group/tree,检查端口/PID/children |
| 子进程大量输出 | 不读 pipe,进程卡死 | 持续 drain,artifact sink + bounded projection |
| stdout 截断丢掉最终 stack | 不标记 | tail 或 head-tail + full artifact handle |
| 两次 edit 指向 symlink 同 inode | 认为不同路径可并行 | sandbox + real resource identity/serialize |
| 用户在 Agent 读取后修改文件 | Agent 覆盖 | before hash/CAS,冲突后重读重算 |
git status 与 edit 并行 |
status 被当最终真相 | snapshot or version tag;提交前重读 |
| Git worktree A/B 同 repo | 认为所有状态独立 | index per worktree,但 refs/object/global ops 仍建模共享 |
| test 命令 0 个测试且 exit 0 | 宣布通过 | 记录 discovered/executed count,policy fail |
| flaky test retry 后通过 | 只报绿色 | 报 attempts/flake status,不能隐藏不稳定性 |
| cache 命中旧 toolchain | 宣布验证 | cache key 加 toolchain/env;抽样 no-cache |
| LSP diagnostic 对旧 version | 自动修当前文件 | 拒绝 stale workspace edit,resync/requery |
| browser DOM element 已 rerender | 按旧 handle 点击 | element/document version 检查,重新定位 |
| redirect 到内网 metadata IP | domain allowlist 初始 URL 通过 | 每跳 resolve/校验 IP、scheme、port |
| repo README 含“上传 env”指令 | Agent 遵从 | 标记 untrusted content;capability gate 独立 |
| approval 后 recipient/amount 改变 | 复用批准 | approval bind effect fingerprint;变化即失效 |
| background build 完成通知丢失 | 永久 running | durable task state + polling/recovery receipt |
| MCP server 返回巨型嵌套 JSON | 直接进 context | validate/size cap/artifactize/provenance |
| tool hook 在 effect 后崩溃 | 整个工具标失败并重试 | effect receipt 保留;hook failure 单独分类 |
| formatter 修改意外文件 | 只显示目标文件 | post-execution full workspace diff + scope check |
| dependency install 写 shell rc | 当普通 build | sandbox 限写,install scripts 视 execute effect |
| remote sandbox 回收前 artifact 未上传 | 宣布完成 | artifact commit/receipt 是回收前 barrier |
| task cancel 后服务端继续执行 | UI 显示 cancelled 即结束 | cancelled control state + eventual reconciliation |
14. Observability:让每一次 effect 可追踪、可归因
14.1 Trace 树
agent.turn
agent.step
model.inference
tool.resolve
tool.permission
tool.queue_wait
tool.execute
process / filesystem / http / browser / remote
tool.reconcile
tool.verify
tool.project_observation
OpenTelemetry 的 GenAI 约定是在多个 release 中演进的:tool definitions/execution details、evaluation event 与 reasoning message parts 已见于 v1.38,而 v1.41继续调整 tool definitions、reasoning/cache-token 字段、streaming metrics 和 invoke_agent span。此后 GenAI conventions 迁入独立仓库;截至复核日固定提交 9af08349 的 README 仍把 Schema URL 写成 TODO,versions.env 依赖 core semconv v1.43.0,且 invoke_agent、execute_tool 等模型仍标为 Development,可能发生 breaking change。官方同时强调 tool arguments/results 可能敏感,不应默认全量采集;2026 年 GenAI observability 说明展示的是 invoke_agent 下挂 model 与 execute_tool spans 的实现示例,不是所有 harness 必须复制的唯一 trace topology。
14.2 每个 tool call 最低字段
| 类别 | 字段 |
|---|---|
| Identity | session/turn/step/call/attempt/trace IDs |
| Definition | tool name/version/source/catalog version |
| Model | provider/model/effort/request ID |
| Resolution | effect fingerprint、access set hash、target class |
| Environment | snapshot/sandbox/policy/identity versions |
| Decision | policy branch、approval ID、queue reason |
| Timing | resolve/approval/queue/start/first update/end durations |
| Execution | exit/status/error domain/code、retry/reconcile state |
| Output | bytes/lines、truncation、artifact IDs |
| Effect | receipt ID、commit state、before/after versions |
| Verification | verifier IDs、result、evidence refs |
不要默认记录:完整源码、完整 shell output、prompt、secret、token、私钥、客户数据。可以记录 hash、分类、大小、经授权采样的 artifact reference。
14.3 事件模型
tool.intent.committed
tool.preflight.rejected
tool.permission.decided
tool.approval.requested/resolved
tool.scheduled/started
tool.progress
tool.cancel.requested/acknowledged
tool.timeout/detached
tool.effect.receipted/unknown/reconciled
tool.result.normalized
tool.output.truncated
tool.verification.completed
tool.observation.projected
事件日志应 append-only,每个 attempt 的 sequence 单调;materialized state 必须能从事件确定性重放。业务状态本身可以合法循环,例如 working → input_required → working;重试使用新 attempt_id,同一逻辑 effect 保持 call_id。
14.4 指标树
Outcome
- verified task success;
- regression-free / user accepted;
- postcondition pass;
- destructive incident / unauthorized effect。
Tool correctness
- invalid args / unavailable tool / wrong-target rate;
- preflight rejection reason;
- tool execution success by domain;
- postcondition failure despite tool success;
- effect-unknown / reconciliation rate;
- unintended changed-resource count。
Efficiency
- tool calls、attempts、queue time;
- time to first useful evidence;
- bytes produced vs bytes consumed by model;
- context tokens spent on tool definitions/results;
- cache hit/miss correctness;
- parallelism utilization vs conflict wait。
Reliability
- timeout/cancel confirmation latency;
- orphan process/task rate;
- background task recovery;
- duplicate effect / dedupe hit;
- retry amplification;
- tool availability and version drift。
Human burden
- permission prompts/task;
- approval rate by risk cohort;
- interruptions、takeover、rollback;
- false-positive sandbox/permission blocks;
- time spent interpreting output。
14.5 关键派生指标
Execution fidelity
= correctly realized intended effects / approved intents
Evidence sufficiency
= completion claims with required verifier evidence / completion claims
Observation fidelity
= decisions based on correctly represented tool state / tool-dependent decisions
Safe autonomy yield
= verified successes without unauthorized effect or unnecessary intervention / tasks
Retry amplification
= physical attempts / logical calls
Useful evidence density
= decision-relevant evidence bytes / total tool output bytes
单看 tool success rate 会奖励把复杂错误吞掉、把 postcondition 不达标也报成功的实现。
15. Evaluation:工具层应怎样被单独测透
15.1 Evaluation Cube
Task regime
× Tool surface
× Environment
× Effect class
× Failure injection
× Model/harness
× Budget
× Verifier
报告必须固定并披露:model、harness commit、tool catalog/version、prompt、sandbox/image、workspace snapshot、network、turn/token/time/cost budget、parallel policy、retry、cache、verifier。
15.2 Contract tests
每个工具至少测:
- schema accept/reject 边界;
- normalization/canonicalization;
- precondition 与 TOCTOU;
- permission binding;
- effect set 是否完整;
- timeout/cancel/detach;
- stdout/stderr streaming order;
- truncation/artifact;
- idempotency/dedupe;
- retry/reconciliation;
- concurrent conflict;
- crash before/after effect commit;
- secret/provenance redaction;
- platform parity。
15.3 Fault injection matrix
| 注入点 | 故障 |
|---|---|
| Provider stream | partial tool JSON、duplicate call ID、disconnect |
| Registry | tool disappears/version changes |
| Preflight | symlink swap、state version conflict |
| Approval | timeout、cancel、stale approval reuse |
| Scheduler | queue cancel、starvation、wrong access declaration |
| Process | spawn error、signal ignored、orphan child、output flood |
| Filesystem | disk full、permission、rename failure、concurrent edit |
| Network | DNS change、redirect、429/5xx、response lost after commit |
| Remote sandbox | VM restart、artifact upload fail、clock skew |
| Result | invalid shape、huge binary、prompt injection、secret echo |
| Verifier | flaky/broken test、zero discovery、stale diagnostic |
15.4 Trajectory eval 高于 final-output eval
Auditing Agent Harness Safety v2 提出的 HarnessAudit在 210 个任务、8 个 domains、10 种 harness 配置上强调:final output 正确不代表轨迹遵守资源访问和信息流约束,违规会随 trajectory length 累积。工具评测因此至少同时评分:
- task outcome;
- boundary compliance;
- execution fidelity;
- evidence sufficiency;
- system stability;
- cost/latency/intervention。
LivePI v3在真实但受控 VM 上覆盖 WhatsApp group、Telegram group、Slack channel、email、local docs、repository links 与 Gist 七个输入面,报告五个所测 backbone 在每模型 169 个 executable cases 上的总攻击成功率为 10.7%–29.6%;wallet 是恶意目标/工具接口之一,不是输入面。其 prompt filtering + pre-execution tool authorization 两层防御只在 GPT-5.3-Codex 上验证,且没有分别消融两层。这一结果支持把 pre-execution authorization 作为独立防线单独评测,不能证明某个通用 gate 已对所有模型和部署“必要且充分”。
15.5 Tool-surface ablation
比较 tool-rich、shell-only、execute-code-only、LSP-enabled 时应固定:
- 相同任务、model、system prompt 的非工具部分;
- 相同 wall/token/cost budget;
- 相同 sandbox/workspace/verifier;
- tool definitions 的 token 与 prefix-cache 成本;
- pass rate、cache-adjusted cost、latency、trajectory length;
- wrong-target、repair loop、destructive effect;
- 按 task regime 分层。
“结构化工具更多”可能降低参数错误,也可能增加选择/上下文成本;“一个 execute_code”可能压缩接口,也可能把安全与可观测语义藏进动态代码。只有 crossed ablation 能判断。
15.6 Eval Case 的最小记录
task_id: ...
required_postconditions: [...]
forbidden_effects: [...]
initial_snapshot: ...
tool_catalog_version: ...
environment_manifest: ...
fault_profile: ...
budgets: ...
trajectory_artifact: ...
effect_receipts: [...]
verifier_results: [...]
first_bad_effect_decision: ...
outcome: ...
16. Kimi Code 公开源码映射
截至 2026-08-03,公开 main 已前进至 75395f6。下面 tool contract、executor、scheduler、permission、path、edit、Bash、task、truncation、Git、terminal 与 MCP adapter 的分析固定在 dfc55a5:逐文件比较 dfc55a5...75395f6 后,这些核心文件没有变化;新增提交只扩展 external lifecycle hooks。固定旧的、已逐文件审计的实现快照,比把所有链接机械改成最新 SHA 更可复现。公开代码也不代表 Moonshot 内部生产架构的全部实现。
16.1 已确认架构
Tool contract 与两阶段 resolution
toolContract.ts区分 staticToolDefinition、ExecutableTool.resolveExecution(input)、RunnableToolExecution和 finalizedToolResult。RunnableToolExecution携带accesses、display/description、approval rule、execute closure;执行 context 带turnId、toolCallId、trace、metadata、AbortSignal和 updates callback。- 这是“tool 不是一个裸函数”的直接源码证据:参数先被解析成一个绑定资源、权限展示与执行闭包的对象。
Executor pipeline
toolExecutorService.ts负责 registry resolution、args parse/schema validation、guard、before-veto、will/did hooks、scheduler、streaming updates、abort grace、normalization、truncation、event 与 telemetry。- 没有声明
accesses的工具默认ToolAccesses.all(),是合理的 fail-closed concurrency posture。 - batch execution 可按完成顺序产出 timed results,同时每个 result 独立 finalization;这要求上层明确 UI completion order 与 provider wire/order contract。
onDidExecuteToolhook 自身失败会把 finalized result 变成 error;工程上必须记住:底层 effect 可能已经发生,不能因此盲重试。
Conflict-aware scheduler
toolScheduler.ts允许无冲突任务重叠,冲突任务等待 active 与排在它前面的 queued conflicting tasks。ToolAccesses当前公开建模主要是 file read/write/readwrite/search、recursive tree 与all。- 设计强点:effect-aware scheduling 已进入核心 contract。继续深化的问题:Git index/ref、port/process/cache/browser/remote API 等非文件资源怎样变成一等 access type;path conflict 目前是 lexical/case-folded 近似,不等同真实 inode/symlink identity。
Dedupe 与无进展循环
toolDedupeService.ts对 canonical args 建 key/hash,抑制 same-step duplicates,并对同一 turn 内连续 cross-step repeats 分层注入“预期新信息、反证/缺输入/结束”的提醒;阈值 3/5/8,连续 12 次强停。turnId改变时 streak 会重置,不是 session-global 计数器。- 这比简单“最多 N 个 tool calls”更接近 progress contract,因为它要求模型解释信息增益。
- 边界:syntax-level/canonical-args repeat 不完全等于 semantic effect repeat;合理 polling、世界状态变化、路径 alias 与等价不同写法仍需要更丰富的 state/effect fingerprint。
Permission chain
permissionPolicyService.ts按有序 policy chain 处理 mode、用户 allow/ask/deny、session approval history、敏感路径、Git control path、workspace write、fallback 等。permissionGateService.ts作为 before-execute veto listener,把 approve/ask/deny 与 telemetry 接到 executor pipeline。git-control-path-access-ask.ts识别普通.git目录、linked-worktree/submodule 的gitdir:control path 后 ask,说明 Git control state 已被单独视为更高风险边界。
Path、Edit 与 concurrency
path-access.ts做跨平台 lexical canonicalization、workspace membership 标记、相对路径逃逸约束、显式 absolute-outside 处理与敏感文件模式;默认guardMode是absolute-outside-allowed,因此用户给出的绝对 workspace 外路径可以继续进入后续 policy,而不是被这一层一律拒绝。源码也明确不做realpath/symlink following;它是 policy input,不是完整 containment,真实边界仍应由 permission 与 OS/sandbox 承担。EditTool声明单文件readWriteaccess,使用 exact-string replacement、唯一性/replace_all与 line-ending preservation。FileEditService公开实现是 read → pure edit → write;源码层没有显式 before-hash CAS。同一次executeBatch内,scheduler 能避免已声明 access 的冲突;它不覆盖后续 step、另一 batch、用户/外部进程,也不覆盖 scheduler 已释放后仍在写入的 detached Bash。跨边界并发是否另有约束,需要内部行为与 trace 验证,不能从这段代码推断已解决。
Bash、background task 与 process tree
bash.ts把 foreground/background timeout、description、disable-timeout 等写入 schema;默认前台 60 秒、最大 5 分钟,后台默认 10 分钟、最大 24 小时。bashTool.ts用非交互 shell,设置NO_COLOR=1、TERM=dumb;GIT_TERMINAL_PROMPT只有在 host 环境未设置时才默认0。前台 timeout 可按配置转为 background,返回 task ID/PID/自动通知语义。前台输出发生截断后才触发持久化;只有 snapshot 报告fullOutputAvailable且存在outputPath时,result 才附task_id、path 与 bytes,并非所有调用都保证完整路径。taskService.ts编排 detached task、timeout、持久化、通知、abort、grace 与forceStop;具体 shell 进程的 soft/hard 信号映射在process-task.ts:abort 请求SIGTERM,grace 后forceStop请求SIGKILL。kaos local process在 POSIX 用 negative PID signal process group,在 Windows 用taskkill /T /F处理 process tree,体现平台语义差异。- Bash 的
resolveExecution没声明细粒度accesses,所以 executor 默认all,即同批其他 effect 与 shell 保守冲突;这牺牲并行度但避免静态误判 shell effect。
Truncation 与 artifact
toolResultTruncationService.ts只处理纯字符串或全部为 text parts、超过 50,000 字符且尚未标记 truncated 的结果;它把全文写入 agent-scoped filesystem storage,返回 2,000 字符 preview、字符/字节大小与output_path。含媒体、已截断结果不会走该路径;保存失败会返回原结果。Bash 另有 task-output 持久化路径。- 这是正确的 context/evidence 分层:完整输出不直接挤进 model context,但 truncation 必须显式。
Git 与 terminal
GitService公开 surface 只看到产品状态/diff 所需的git status --porcelain、git diff、worktree discovery 与 PR metadata,没有内建 Git mutation tool;commit/push 等仍可由 Bash 执行,而 permission policy 特别识别 Git control path。terminal.ts定义 interactive PTY contract,包含 terminal/session IDs、cwd/shell/cols/rows、sequence、attach cursor、write/resize/kill;terminalService.ts管理 session 级生命周期,hostTerminalService.ts落到 node-local backend。它们和给模型的 Bash pipe 工具是不同产品/协议面。
MCP adapter 的 at-least-once 边界
mcp.ts把远端 MCP tool 适配为ExecutableTool。server 已回答的 JSON-RPC error 或 client-side malformed-result error 不重连;raw socket/fetch 等 ambiguous failure 会先 ping,连接仍活时原地重试一次,确认连接死亡时重连一次再调用。- 源码注释明确把这定义为 at-least-once:若 server 已执行、response 在返回前丢失,retry 可能复制副作用;跨 reconnect 没有协议级 dedupe。这是公开实现中最值得面试追问的 reliability trade-off:哪些 tool 可自动重试、哪些必须先 reconciliation、怎样把服务端 idempotency contract 接入 adapter。
75395f6 的 lifecycle-hook 增量
feat(agent-core-v2): add lifecycle hook events and enrich hook payloads新增TurnStarted、UserPromptQueued、TaskStarted、SessionHeartbeat;hook payload 增加 session title,SessionStart增加 model/profile,archive 时SessionEndreason 改为archive。- Agent-scope adapter 把
turn.started、prompt.queued、task.started转为外部事件;Session-scope adapter只在配置了SessionHeartbeat时启动一分钟周期 timer,并随 hook index reload 装卸。新增 runnerready、onDidReload、hasHooksFor,避免无 hook 的 session 无谓持有定时器。 - 这不是 tool executor 语义变化,而是 observability/automation surface 的扩展。面试时还应追问:fire-and-forget hook 失败如何观测;heartbeat 是否需要抖动与负载治理;hook payload 的 prompt/output/session metadata 怎样做 secret classification;外部 hook 是否有稳定 delivery/ordering/dedupe contract。
16.2 公开代码不能确认、面试最值得追问的边界
- 本地、SSH/remote、Web sandbox 的 effect/receipt contract 是否完全一致?
- Bash/tool cancellation 在 remote transport 断线时怎样 reconcile?
- file edit 是否计划加入跨进程 CAS、atomic write 和 before/after hash?
ToolAccesses是否会扩展为 Git/ref/port/process/browser/API resource graph?- permission approval 是否绑定 normalized effect fingerprint、target version 与 expiry?
- tool result/artifact 的 provenance、taint 和 secret classification 怎样传播?
- LSP/symbol/AST 是否作为内建 tool plane,或经 IDE/ACP/MCP 提供?在该提交中未看到明显的内建 LSP tool domain。
- task/background receipt 是否支持 daemon crash 后对真实进程/远端 job reconciliation?
- test/build discovery、cache provenance、zero-test guard 是否属于 verifier 层?
- harness eval 如何按 tool surface、environment、effect cohort 做 ablation?
这些是问题,不应伪装成对 Kimi 内部现状的结论。
16.3 公开 frontier cross-check:Codex、Claude Code 与 pi
这不是先进性排行榜。公开官方源码与文档的价值,是提供可复核的设计样本;它们不能证明厂商未公开的生产实现,也不能脱离威胁模型、产品定位和兼容约束推导谁“更强”。本节固定于 2026-08-03:Codex main 为 bb5054fe,Claude Code 公开 release 仓库 main 为 7ef6eec9,pi main 为 c6eb6281。pi 最新稳定 tag 是 v0.83.0,c6eb6281 含未发布变更,不能等同稳定二进制。
| 系统 | 可复核的证据底座 | 公开边界 |
|---|---|---|
| Codex | 完整 Rust CLI/runtime、sandbox、MCP client/server、hooks、skills 与 patch implementation;官方滚动文档 | 公开客户端不等于 OpenAI 托管控制面、模型策略或内部生产运行时全貌 |
| Claude Code | 官方滚动文档、release notes、plugins/examples,以及独立公开的 Sandbox Runtime | anthropics/claude-code 不含核心 CLI/harness 源码且许可为 all-rights-reserved;实现内部只能写成“官方产品 contract”,不能写成“源码证明” |
| pi | 完整 TypeScript monorepo、coding-agent 文档、实现与 examples | main 可领先稳定 release;第三方 extension 的 MCP/sandbox 行为不能外推为 pi core contract |
Runtime、terminal 与长进程
Codex 在每次 sampling request 先固定一份 StepContext:environment snapshot、capability roots、MCP binding、tool router 与 AGENTS instructions 不在同一步执行中漂移。其 UnifiedExecProcessManager再把 shell 执行建模为有状态 process plane:process store、process ID、可选 PTY、poll/write_stdin、取消 token、异步 watcher、并发上限,以及 bounded head/tail buffer。它还主动设置 NO_COLOR=1、TERM=dumb、C.UTF-8 locale、pager=cat 等受控环境;这是 Codex 的 reproducibility/parseability 选择,不是 shell 的普适要求。
Claude Code 的 Tools reference把 Bash 定义为每次调用一个独立进程,不是持久 PTY;默认 timeout 两分钟、模型可请求到十分钟,超时或长调用可进入 background task,完整输出落 session artifact。cwd 可由 harness 在允许目录内延续,export 不跨调用持久化;启动 shell 中抓取的 alias/function/options 则可应用到每次调用。background task 返回后仍可能继续改文件,因此“tool call 已返回”不等于 effect plane 已静止。
pi 的 bash是 shell -c + pipe,不是 PTY;timeout 默认关闭,核心刻意不内建 background Bash,交互/长进程建议交给 tmux 或 extension。取消时 POSIX 对 process group 发 SIGKILL,Windows 用 taskkill /F /T,没有 TERM→grace→KILL 两阶段。显示层保留最后 2,000 行或 50 KiB,超限时把全文写入随机临时文件。Pi TUI 支持高级 terminal protocol,不代表模型的 Bash 子进程也拥有 TTY——这是面试里很容易混淆的两层。
可迁移结论不是“都做成某一种 shell”,而是必须显式回答:调用是 one-shot、session process 还是 job;有没有 PTY;进程树怎样终止;背景 effect 怎样继续观测;环境怎样继承;output 的 preview、artifact 与 retention contract 是什么。
Editing 与并发一致性
Codex 为 apply_patch保留专用 handler、runtime 和 grammar,而不是把所有修改降格为自由 shell。完整 patch 会先解析、在目标环境验证、做路径/审批判断,再进入 filesystem sandbox;但实现仍是逐 hunk/文件提交,首个错误后停止且不自动回滚。Move to 也是先写目标再删源,不是 atomic rename。结构化 mutation 让路径、diff、部分提交与 policy 更可观察,不代表事务、文件版本未漂移、patch 后语义正确或多写者安全。
Claude Code 的 Edit 是 exact-string replacement:目标需要精确且唯一,并基于当前磁盘内容重新确认;Read permission 也约束 Edit/Write/NotebookEdit。它不是 fuzzy patch,也不是 digest/CAS。Checkpoint 主要覆盖 Claude 自己的 file-edit tools,不能假定 Bash、外部进程、所有 subagent 或 link alias 都可恢复。
pi 的 edit支持一次调用内多个不重叠替换,全部相对同一 original content 计算并逆序应用;实现先 exact,失败后做 NFKC、行尾空白、智能引号、dash/space 的受控 normalization,匹配仍须唯一。它保留 BOM/line ending并返回 diff/patch。进程内 file-mutation-queue串行同文件的 Edit/Write,现存路径用 realpath 合并部分 alias;但它不覆盖 Bash、IDE、Git、另一 Pi 进程,也没有 before-hash CAS 或 atomic rename。取消可能发生在写入完成以后,不能解释成 rollback。
这里不存在单一“最佳 edit tool”。真正的审查序列是:matching semantics → expected version/digest → alias identity → mutation atomicity → competing writers → receipt/diff → verifier。Kimi 当前的 batch-scoped access scheduler 与这些机制解决的是不同问题:scheduler 控 batch 内冲突,CAS 控 stale writer,atomic write 控 partial mutation,verifier 控 postcondition;四者不能互相替代。
Sandbox、permission 与 trust 的不同轴
Codex 的 sandbox contract将 spawned command 及 descendants 放进平台原生边界:macOS Seatbelt、Linux/WSL bubblewrap、native Windows restricted token/ACL/firewall/Job Object 路径。sandbox policy 与 approval policy 分离;legacy workspace-write 也不能被误读为“只能读取 workspace”。仍标为 experimental 的 Rules用 Starlark prefix policies,支持 match/not_match 单元测试;对无法安全拆分的复杂 shell 保守整体判断。它说明命令 policy 本身也应可测试,而不是散落字符串正则。
Claude Code 的 sandbox直接覆盖 Bash 及其 descendants;Read/Edit/Write 等内建工具仍主要由 permission system 管理,不能说“整个 tool plane 都在同一个 OS sandbox 内”。macOS 用 Seatbelt,Linux/WSL2 用 bubblewrap;native Windows 产品面仍要求 WSL2。sandbox 初始化失败默认会警告后 unsandboxed 执行,只有 sandbox.failIfUnavailable=true 才成为 hard gate;allowUnsandboxedCommands=false 才关闭 escape hatch。域名 allowlist 也是 capability grant,不是数据流安全证明:允许域、具体 endpoint、请求 identity 和 credential provenance 必须一起审查。
pi 官方 Security明确:核心无 sandbox,内建工具与 TypeScript extensions 都以 Pi 用户权限运行;Project Trust 只决定项目本地 settings/extensions/skills/packages 等是否加载,不限制模型之后能访问哪些文件或命令,AGENTS.md/CLAUDE.md 也不因此变成可信输入。需要隔离时,官方方向是把整个 Pi 放入 container/OpenShell,或用 operations override 把内建 I/O 路由到 VM。示例只代理到 VM 的工具不能保护仍在 host 运行的其他 extension tool。
因此要分开四件事:workspace trust 决定“加载谁的代码/配置”;permission 决定“这次 effect 是否授权”;sandbox 决定“进程实际上能触达什么”;credential/egress boundary 决定“可把什么数据以谁的身份送到哪里”。把四者合成一个 safe_mode 是架构错误。
Skills、hooks 与 extension trust
三者都采用或兼容 Agent Skills 的 progressive disclosure,但细节不同:
- Codex Skills启动时只暴露 name/description,按需读完整
SKILL.md;支持 repo/user/admin/system/plugin scope、显式/隐式 invocation 和依赖提示。公开实现还对初始 skill listing 设 context budget。skill 是 instruction/resource packaging,不是 capability boundary。 - Claude Code Skills合并旧 custom commands,支持 user/project/plugin/enterprise scope、nested-directory lazy discovery、live reload、
context: fork、allowed-tools与disable-model-invocation。这里的allowed-tools是调用期间的 permission grant,不等于 OS sandbox;带 deploy/commit/send 等副作用的 skill 应主动关闭模型自主 invocation。 - pi Skills同样只先注入 metadata,显式
/skill:name才把正文加入消息;project skill 受 Project Trust 的加载门控制。当前源码没有执行文档中实验性allowed-tools的逻辑,因此不能把它写成已实现的授权边界。
Hooks 也不是天然的安全执行层:
- Codex Hooks覆盖 tool、permission、prompt、compaction、subagent、stop、session 等 lifecycle;项目 hooks 受 project trust,用户批准绑定具体 hook definition hash。当前文档同时标明:实际只执行 command handler,prompt/agent handler 虽可解析仍会跳过,async 选项也尚未执行;必须区分 config schema 与 runtime support。
- Claude Code Hooks支持 command、HTTP、MCP-tool、prompt、agent 等 handler 和更广事件面。
PreToolUsecommand hook 只有约定的阻断返回才会拦截;HTTP 非 2xx、连接失败或 timeout 默认可继续,匹配本身也是 best-effort。要做 hard policy,必须选择可阻断事件、定义 failure mode,并与 permission/sandbox 组合,不能因为触发是 deterministic 就宣称 enforcement fail-closed。 - pi Extensions是进程内、拥有完整用户权限的 TypeScript 模块。
tool_call在 schema validation 后可 block 或原地改写 input,改写后不会自动重新验证;handler 抛错会 fail-safe 阻止调用。tool_result又可改写 content/details/isError/usage。安全 trace 因而必须区分 validated args、hook-mutated args、真实 effect/result、postprocessed observation 四层。
MCP 与大工具面
Codex MCP支持 stdio 与 Streamable HTTP、OAuth/bearer/ChatGPT auth、server startup/timeout、tool allow/deny 与 approval policy、server instructions,以及受信任 project config;公开仓库同时包含 MCP client/server 代码。每 step 捕获不可变 McpBinding和 catalog revision,目录变化后拒绝 stale call,这是比“按名字查当前 registry”更强的 drift control。bb5054fe 的默认 protocol mode 仍提出 2025-06-18;2026-07-28 lifecycle 已进源码但受 feature/transport 条件约束,不能说已对所有用户默认切换。普通 tools/call 没有通用 transient retry,但带 session ID 的 404 会触发 session 重建后重放原 operation,且没有通用 idempotency key/dedupe;因此连接恢复仍可能进入副作用不确定区,绝不能推出 exactly-once。
Claude Code 当前 MCP product contract更像一套动态 capability plane:HTTP、deprecated SSE、stdio 与 WebSocket;默认 Tool Search 延迟加载 MCP schemas,auto 才是旧式 10% threshold 模式,alwaysLoad 可豁免;list_changed refresh 失败保留上一份成功 catalog;HTTP/SSE 断线最多五次 exponential-backoff reconnect,stdio 不自动重启;OAuth refresh/header helper 可在 401/403 后 reconnect 并重试一次;resources、prompts、elicitation、per-server wall/idle timeout 与 output cap 都是显式产品面。这里确认的是 discovery、connection/auth watchdog 等 contract,不是副作用调用的 exactly-once。
pi 核心明确没有 built-in MCP。它选择用 CLI + Skill 或 Extension 接入外部能力;因此 transport、capability negotiation、OAuth、reconnect、catalog refresh、retry/dedupe 都由具体 extension 承担,任何第三方 adapter 都不能代表 pi core。与此同时,pi 已支持动态工具加载:extension 可先注册轻量 loader/search tool,再增量激活命中工具;provider 不支持原生 deferred representation 时回退完整 active list。这证明“没有 MCP”与“没有 tool-surface engineering”不是同一件事。
大工具面的共同问题是 definition/schema 占用 context、选择歧义、连接时序、权限可见性与 catalog drift。Codex 的 tool system 也显式区分 Direct、Deferred、DirectModelOnly、Hidden exposure,说明“host 已注册”不等于“schema 永久完整进模型”。正确的抽象不是无限注册 endpoint,而是:workflow-level tools + progressive/deferred discovery + stable names/version + bounded result + explicit trust/approval + capability-change trace。
对 Kimi Code 的可迁移判断
- 把 lifecycle 当作 contract,而非 UI 事件:
75395f6已扩展 hook coverage,下一步更重要的是 delivery、ordering、failure visibility、payload taint 与版本,而不只是继续增加 event names。 - 补齐跨时间的 resource ownership:Kimi 的 batch scheduler 已解决单步内声明式冲突;background task、下一 step、外部进程和 remote job 仍需 receipt、lease/CAS/reconciliation,而不是把 scheduler 范围夸大成 session isolation。
- 把 tool surface budget 化:参考三套系统的 progressive disclosure/dynamic loading,但必须按 Kimi 的 provider mix 测 cache、selection accuracy、latency、cold discovery 和 failure recovery,不能照搬某个阈值。
- 明确 extension/hook 的 authority class:command hook、in-process plugin、remote MCP tool 的代码权限、数据权限、failure mode、审计与信任来源不同,不应共享一个模糊的“插件已启用”状态。
- 坚持公开证据的边界:可以从 Codex/pi 源码比较具体机制,从 Claude Code 官方文档比较 product contract;不能用公开程度替代设计质量,也不能把没公开的实现猜成缺失。
面试时最高质量的回答不是“应该像 Codex/Claude/pi”,而是:“在什么 threat model 和 task regime 下,哪条 contract 是 load-bearing;如果换 model、provider、平台或 deployment,它是否仍成立;用哪组 trace/fault injection/ablation 证明。”
17. 一套统一的设计审查框架
看到任何新工具、MCP server、CLI、IDE capability 或 remote executor,按以下顺序审查:
A. 语义边界
- 它真正封装了什么复杂性?
- tool call 与真实 effect 的 commit point 分别在哪里?
- success/postcondition/verification 怎样区分?
B. State 与 Environment
- 目标资源怎样 canonicalize?
- 调用绑定哪个 workspace/environment snapshot?
- 是否有 CAS、transaction、conditional request?
C. Authority 与 Safety
- principal、capability、effect、target、data flow 如何决策?
- sandbox 限制整个 process tree 还是只有 top-level tool?
- secret 是否进入模型/argv/log/artifact?
D. Reliability
- 幂等范围、key、TTL、fingerprint?
- timeout/cancel 后 effect 如何确认?
- crash 恢复是 replay 还是 reconcile?
E. Concurrency
- resource access set 是否完整?
- aliases、Git index、ports、cache 等隐式资源怎样建模?
- 结果顺序、失败传播、锁与 snapshot isolation?
F. Observation 与 Evidence
- 原始结果、receipt、artifact、model observation 是否分层?
- 截断、partial、stale、untrusted 是否显式?
- verifier 是否独立?
G. Eval
- 在固定 model/harness/environment 下有 tool-surface ablation 吗?
- outcome、cost、boundary compliance、first bad effect decision 是否同时测?
- 是否有 crash/fault/injection/concurrency cases?
如果对这些问题只剩“我们 prompt 里写了”“工具返回了 success”“超时就重试”,说明系统还停留在 demo 语义。
18. 二十组面试深追问
以下不是背诵答案,而是每一组需要能从第一原则连续推演的追问树。
1. 为什么 Tool 不是 function?
主问:tool(args) -> result 有什么根本缺陷?
回答骨架:函数模型没有表达外部状态、权限、资源冲突、异步进程、部分副作用、crash window、receipt 和 verifier。正确对象链是 definition → intent → resolved execution → attempt → effect receipt → observation。
继续追问:
- 哪一步绑定真实 cwd/path/identity?
- hook 在 effect 后失败,工具应该是成功还是失败?
- 为什么 model observation 不能承担 receipt?
高阶落点:控制面失败与 effect 状态必须正交;最终 status 可以是 internal-finalization-failed + effect-committed,而不是一个布尔 isError 抹平。
2. 怎样设计一个完整 Tool Contract?
主问:除了 JSON Schema,还缺什么?
回答骨架:schema 只管 syntax;还要 semantics、target resolution、pre/postcondition、effects、idempotency、retry/cancel/timeout、stream/backpressure、concurrency、error taxonomy、evidence 与 data handling。
继续追问:
- description 和 host enforcement 怎样分工?
- tool version 变化时旧 session 怎样恢复?
- 默认值是在 provider、schema 还是 host normalization 里应用?
高阶落点:definition version、normalized args 和 environment snapshot 进入 effect fingerprint;恢复时不能用新语义悄悄解释旧 intent。
3. Schema validation 为什么不足?
主问:路径是合法 string,为什么还不能执行?
回答骨架:还需 semantic validation、canonical target、sensitive/workspace policy、state precondition、business intent;并处理 TOCTOU。
继续追问:
../、symlink、hardlink、case-folding 如何处理?realpath后再 open 为什么仍有 race?- 如何把 precondition 与 write 原子绑定?
高阶落点:使用 sandbox/mount boundary 和 descriptor/conditional-write/CAS;应用层字符串检查只是 defense-in-depth。
4. Effect Taxonomy 怎样设计?
主问:按 Read/Write/Shell 三类授权够吗?
回答骨架:不够。至少 read/write/execute/network/communicate/irreversible,并沿 boundary、scope、reversibility、determinism、privilege、information flow、visibility、temporal reach 标注。
继续追问:
git push属于什么?npm install为什么不是单纯 execute?- 创建 PR draft 和评论/merge 为什么应拆 capability?
高阶落点:工具名不决定风险,resolved effect composition 才决定 policy。
5. 如何做到 exactly-once tool effect?
主问:API 调用发出后客户端崩溃,怎么办?
回答骨架:通用 exactly-once 很难;用 durable intent、服务端 idempotency key、effect fingerprint、external operation ID、receipt 与 reconciliation 实现业务级 exactly-once illusion。
继续追问:
- 服务端不支持 idempotency 呢?
- key 多久过期?同 key 不同 payload 怎么办?
- receipt 写失败是否可以重放?
高阶落点:无服务端能力时只能选择 at-most-once + unknown/manual resolution,或补偿事务;不能伪称 exactly-once。
6. 去重与防循环怎样区分?
主问:相同 tool name/args 连续出现就都应该拦吗?
回答骨架:same-step duplicate、cross-step repeat、legitimate polling、same syntax/different state、different syntax/same effect 都不同。需 canonical effect + state version + information gain。
继续追问:
- 读 status 三次何时合理?
- 如何检测“换命令但没有新证据”?
- 强停前给模型什么恢复机会?
高阶落点:loop breaker 应从次数阈值升级为 progress/evidence contract;Kimi 公开 dedupe 已有分层 reminder,可继续结合 semantic effect fingerprint。
7. Timeout 后是否能 retry?
主问:shell/API timeout 以后该怎么处理?
回答骨架:先区分 queue/soft/detach/hard timeout;timeout 不证明 effect 未发生。进入 partial/unknown,检查 task/process/workspace/server receipt,再重试、补偿或人工决定。
继续追问:
- foreground timeout 转后台时返回什么?
- HTTP client timeout 与 server deadline 区别?
- verifier timeout 是否改变 effect state?
高阶落点:control、effect、evidence 三套状态独立;retry decision 来自 effect state,不是错误字符串。
8. Cancellation 怎样传播到底层?
主问:用户按 Ctrl-C,怎样确认 Agent 真停了?
回答骨架:取消 model、approval、queued tasks、execution;对 process group/remote job 发 cancel;soft grace 后 hard kill;drain output;reconcile partial effects;写 terminal event。
继续追问:
- 子孙进程如何处理?
- Windows 与 POSIX 差异?
- cancel 后服务器继续执行怎么办?
高阶落点:cancel_requested、acknowledged、confirmed、partial/unknown 必须分开。
9. Pipe 和 PTY 怎样选?
主问:为什么测试一般不该跑在 PTY?
回答骨架:pipe 更可预测、stdout/stderr 可分、无 TTY 动态行为;PTY 适合 REPL/TUI/job control,但带控制序列、交互输入、前台 process group 和窗口尺寸状态。
继续追问:
- 程序检查
isatty()会怎样? - Ctrl-C 该写字符还是发 signal?
- detach 后 controlling terminal 怎样处理?
高阶落点:PTY 是持久双向会话对象,需 sequence/cursor/resume/resize/kill contract,不是输出格式选项。
10. 如何处理无限 stdout?
主问:命令每秒输出几 MB,怎样不挂死、不污染 context?
回答骨架:持续 drain bounded buffer;完整输出流向 artifact;UI 采样/合并;model 只拿 head-tail/错误摘要/handle;显式 truncation 与原始大小;资源超限再停进程。
继续追问:
- artifact sink 也慢怎么办?
- stderr 尾部和 stdout 顺序如何保留?
- 断线恢复怎样避免丢事件?
高阶落点:per-stream seq + bounded queues + spill-to-disk/object store;backpressure policy 分消费者,不能让 model context budget 反压死子进程。
11. 多个 Tool Calls 怎样并行?
主问:模型一次发 5 个 tool calls,何时并行?
回答骨架:先 resolve access/effect set,构建冲突图;read/read 或隔离资源并行;overlapping write、Git index/ref、port/process/cache 等串行;unknown shell 保守 all 或独立 sandbox。
继续追问:
- queued task 公平性?
- 结果按完成顺序还是调用顺序?
- 一个失败是否取消其他?
高阶落点:execution completion、UI delivery、provider result ordering 三者可以不同,但要稳定绑定 call IDs。
12. 怎样防止并发编辑覆盖用户修改?
主问:Agent 读完文件后,用户改了同一文件怎么办?
回答骨架:read 返回 content version;edit/patch 绑定 expected hash;commit CAS;冲突重读并重算;atomic write/read-back;保留 diff。
继续追问:
- exact-string 仍唯一是否足够?
- formatter 同时改文件呢?
- 多文件 patch 怎样原子?
高阶落点:唯一字符串避免 ambiguity,不等于并发安全;需要 version binding。多文件事务可在隔离 snapshot 应用并以 tree swap/merge 提交。
13. Git 为什么必须单独建模?
主问:为什么所有 Git 操作不能都当普通 shell?
回答骨架:Git 有 working tree/index/objects/refs/remote 分层、共享 worktree 元数据、用户 dirty state、hooks 与外部通信;effect/冲突/回滚均不同。
继续追问:
- 如何保证 commit 只含 Agent diff?
- push 如何避免覆盖远端更新?
- linked worktree 哪些状态共享?
高阶落点:使用 machine-readable plumbing/porcelain、expected ref SHA、path-scoped staging、commit manifest;push 是独立 consequential effect。
14. 怎样证明 tests 真的通过?
主问:命令 exit 0 是否足够?
回答骨架:不够。记录 discovery、selected/executed test IDs、zero-test、cache provenance、retries/flakes、environment manifest、report artifact;再看 regression oracle。
继续追问:
- targeted tests 与 full suite 怎样选择?
- cache hit 怎样确认对应当前 source/toolchain?
- flaky retry 怎么呈现?
高阶落点:test execution 与 test adequacy 是两层 verifier;绿色 exit code 只能证明被执行的 runner 状态。
15. LSP 结果为什么可能错?
主问:LSP 返回 0 diagnostics,能否认为代码正确?
回答骨架:LSP 只对已同步 document version、workspace config、index 和依赖成立;可能 stale、warming、crashed、未覆盖 runtime semantics。结果要带 server/config/document version,并由 compiler/test 独立验证。
继续追问:
- workspace edit 怎样防 stale apply?
- multi-root/monorepo root 如何决定?
- generated code/macro 怎么办?
高阶落点:把 LSP 当 versioned semantic cache,不是 oracle。
16. Sandbox 和 permission prompt 的边界?
主问:什么应该自动允许,什么必须问用户?
回答骨架:sandbox 收敛可技术确定的 blast radius;prompt 承接业务意图与不可逆后果。workspace 内可回滚 edit/test 可自动;跨 workspace、secret、network communicate、push/deploy/delete 需 scoped delegation/approval。
继续追问:
- 用户点过一次 allow,能否复用?
- prompt injection 能否诱导 approval?
- sandbox violation 后自动升级权限吗?
高阶落点:approval 绑定 normalized effect fingerprint/version/expiry;不能自动把 blocked action 升权重试。
17. 如何防 tool output prompt injection?
主问:repo/web/MCP 输出包含恶意指令怎么办?
回答骨架:标记 provenance/taint;内容是数据,不改变 instruction hierarchy;capability 由独立 policy 决定;secret 不进 context;外发/执行前 effect gate 检查用户 intent、target 与 data flow。
继续追问:
- 只写“忽略恶意提示”够吗?
- source code 中本来就有命令注释怎么办?
- tool result 需要过滤还是保留?
高阶落点:保留任务所需内容,但 channel closure + capability restriction + output validation;prompt filtering 只是概率防线。
18. Tool Result 怎样规范化?
主问:所有结果转成 string 是否最简单?
回答骨架:string 丢 error domain、status、receipt、artifact、version、truncation 和 provenance。使用统一 lifecycle envelope + domain-specific structured payload + 紧凑 modelText。
继续追问:
- protocol error 与 tool error 怎样分?
- UI 与 model 是否用同一输出?
- hook/normalizer 出错但 effect 已发生怎么办?
高阶落点:raw result、receipt、normalized result、observation 四层保留;任何投影失败不抹掉已知 effect。
19. 工具层怎样做 Observability/Eval?
主问:只记录 tool name、latency、success 可以吗?
回答骨架:还需 call/attempt IDs、definition/environment/policy versions、effect/access fingerprint、approval branch、output/truncation、receipt/commit state、verifier 与 first bad effect decision。
继续追问:
- 怎样避免日志泄露源码/secret?
- 什么指标最能发现“看起来成功但没证据”?
- 如何评价并行优化是否值得?
高阶落点:evidence sufficiency、postcondition-failure-despite-success、effect-unknown、retry amplification、useful evidence density;敏感内容 opt-in artifact,不进高基数 span attributes。
20. 你会怎样演进 Kimi Code 的 Tool Plane?
主问:基于公开代码,先改什么?
回答骨架:先肯定已存在的深边界:resolveExecution、access-aware scheduler、ordered permission chain、dedupe、background task、truncation。再以 trace/eval 决定优先级,而非凭 feature 清单。
三个结构性候选:
- Effect/receipt contract:把 commit state、attempt、idempotency、reconciliation、一等 artifact/verification 放入核心类型;
- Resource graph 扩展:从 file accesses 扩展 Git/index/ref、port/process/cache/browser/remote API;
- Versioned edit/environment:file CAS/atomic write、environment manifest、test/cache provenance。
继续追问:
- 哪个先做?
- 怎样避免抽象过度?
- 如何证明提升来自机制而不是模型/benchmark noise?
高阶落点:从真实 failure cohort 选 first bad boundary,做最小类型/运行时改动;固定 model/task/environment 做 ablation,同时看 verified success、unknown effect、intervention、cost 与 destructive incidents。没有内部 trace 不能武断排优先级。
19. 2025–2026 一手证据与使用边界
Kimi / Moonshot
- Kimi Code repository
- Tool contract at
dfc55a5 - Tool executor
- Conflict-aware scheduler
- Dedupe / repeat breaker
- Permission policy chain
- Bash tool
- Task lifecycle
- Process task signal mapping
- Path access
- Edit service
- Result truncation
- MCP tool adapter
- Terminal contract、session service、node-local backend
- Lifecycle hooks increment at current
main75395f6
Codex、Claude Code 与 pi 公开实现/产品 contract
- OpenAI Codex repository at
bb5054fe、Unified Exec process manager、apply_patchruntime - Codex sandbox、exec rules、hooks、skills、MCP
- Anthropic Claude Code release repository at
7ef6eec9、all-rights-reserved license、fixed CHANGELOG - Claude Code tools、sandbox、hooks、skills、MCP
- pi repository at
c6eb6281、coding-agent README、Security、Containerization - pi extensions、skills、edit、bash
运行时、Sandbox 与协议
- Anthropic: Claude Code Sandboxing, 2025
- Anthropic: How We Contain Claude, 2026
- Anthropic Sandbox Runtime
- OpenAI: Building Codex Windows Sandbox, 2026
- MCP 2026-07-28 design background(RC 阶段文章)
- MCP 2026-07-28 Tools
- MCP Tasks extension overview
- MCP Tasks draft specification / cooperative cancellation
- OpenTelemetry semantic conventions releases
- OpenTelemetry GenAI independent repository at
9af08349
系统与工具规范
- JSON Schema specification
- POSIX.1-2024 General Terminal Interface
- Node.js Child Process
- Linux pty(7)
- Git apply
- Git worktree
- LSP 3.18 specification
- Chrome DevTools Protocol
- Docker Build Cache
- Docker Cache Invalidation
- IETF HTTPAPI Idempotency-Key draft-07(已过期,仅作历史设计参考)
2026 实证研究
- Harness-Bench v1:model-harness pairing 与 execution-alignment diagnostics。
- Claw-SWE-Bench v1:固定模型下 adapter/harness 可带来大幅结果差异。
- SWE-Explore v1:repository exploration 的 coverage/ranking/context-efficiency。
- When Does Restricting a Coding Agent to execute_code Help? v1:KDD 2026 Agentic SE workshop、non-archival;tool surface × task regime × agent design ablation,谨慎外推。
- Auditing Agent Harness Safety / HarnessAudit v2:full-trajectory boundary compliance 与 final outcome 分离。
- LivePI v3:生产式受控 VM 中的 indirect prompt injection 与 pre-execution authorization。
如何使用这些证据
- 标准/官方源码说明 contract 和实现事实;
- 工程博客提供 生产经验信号,但数字只属于其产品与样本;
- benchmark/preprint提供 可复现实证或假设,不能直接当所有 Coding Agent 的普遍定律;
- 真正的 Kimi 优先级必须由内部 trace、failure cohort、用户后果和受控 ablation 决定。
20. 最终掌握标准
“讲透 Tools & Environment”不是能列出 Read/Edit/Bash/Git,而是能在任何极端场景中稳定回答:
- 模型提出的 intent 是什么?
- host 实际解析出的 effect 和 target 是什么?
- 它绑定哪个 environment/state version?
- 谁以什么 authority 执行?
- 哪些调用冲突,为什么?
- effect 在哪个 commit point 发生?
- timeout/cancel/crash 后真实状态是什么?
- 能否安全 retry,依据什么 contract?
- receipt 与 verifier evidence 在哪里?
- 给模型的 observation 是否忠实表达 partial、stale、truncated、untrusted?
- 怎样从 trace 找到 first bad effect decision?
- 用什么 ablation 证明这项工具设计真实提升 verified task success,而不是只让 demo 更顺?
能够把这十二问落到 shell、filesystem、Git、test、LSP、browser、sandbox 和 Kimi Code 公开实现,才算真正掌握这一层。