<!-- 文档分类: OPS-MAN-018 | 阶段: 运维 | 原路径: docs/指南/khy-编程智能体-风险预防-2026-05-30.md -->
# KHY 编程智能体风险预防与诊断计划 (2026-05-30)

## 目标

把 `khy` 作为编程智能体长期使用时最常见的异常提前暴露、提前诊断、提前降级，避免出现“能聊天但不能稳定交付代码”的假可用状态。

## 高优先级风险

1. KHY 协议优先级被上游适配器二次覆盖
   - 现象: 用户要求中文，但适配器仍输出英文，或 `khy.md` 被兼容文件覆盖
   - 风险适配器: `codex`、`claude`、`cursor`、`windsurf`、`trae`、`vscode`
   - 现有控制:
     - 网关统一注入 KHY 最高优先级协议
     - `khy gateway status`
     - `khy gateway debug-prompt`
     - `khy doctor`
   - 后续控制:
     - 对高风险适配器增加首包语言一致性检查
     - 支持按 adapter 维度回放最新注入摘要

2. 通道连通但编程代理工作流不可用
   - 现象: 能回复，但不会稳定读文件、改文件、执行命令或校验结果
   - 风险来源: 仅连通测试通过，不代表 coding workflow 可执行
   - 控制方向:
     - 在 `khy doctor` 中加入 coding-agent smoke test
     - 区分“通道可用”和“编程代理可用”

3. 长任务无输出，看似卡死
   - 现象: 长时间停留在模糊状态，用户无法判断是否仍在推进
   - 控制方向:
     - 统一 activity-based idle timeout
     - 所有适配器输出动作 + 目标 + 进度
     - 关键循环发出 heartbeat / progress 事件

4. 上下文过大导致指令漂移
   - 现象: 多轮后忘记语言协议、忽略用户限制、误改无关文件
   - 控制方向:
     - 保持 KHY 协议块短而硬
     - 长会话自动 compact
     - 大文件默认摘要化

5. 脏工作区被误覆盖
   - 现象: 用户已有修改被智能体新补丁覆盖
   - 控制方向:
     - 写文件前识别 dirty target
     - 对目标文件已有非本轮改动时切换谨慎模式

## 中优先级风险

1. 代理 / 网络 / API 池切换导致行为忽好忽坏
2. 模型切换后能力不一致
3. 回复格式正确但实际未执行
4. 排障链有日志但缺少全链路关联

## 落地顺序

1. `doctor` 增加 coding-agent smoke test
2. 网关请求、工具调用、最终回复增加统一 `request-id`
3. 对高风险适配器增加语言一致性首包检查
4. `gateway status --json` 增加 `agentReadiness`
5. 增加脏工作区保护提示

## 验收标准

1. 用户执行 `khy doctor` 时，能直接看到编程智能体是否具备:
   - 活跃通道
   - coding tool profile
   - 关键工具组
   - 临时工作区写入能力
2. 用户执行 `khy gateway status --json` 时，能看到:
   - 活跃通道
   - KHY 协议风险
   - 最近一次注入摘要
   - 后续扩展的 agent readiness
3. 高风险适配器出现语言漂移时，能快速回溯到:
   - adapter
   - 注入时间
   - system/prompt 摘要
   - request-id

## 当前执行状态

- 已完成:
  - 网关统一注入 KHY 最高优先级协议
  - `gateway status` 暴露协议风险
  - `gateway debug-prompt`
  - `doctor` 集成 KHY 协议风险诊断
  - `debug-prompt` 支持 `--adapter`
  - `status --json` 暴露最近注入摘要
  - `doctor` coding-agent smoke test
  - 全链路 `requestId` 统一贯穿 `diagnosticEvents / aiGateway / toolUseLoop / toolCalling / toolPipeline`
  - 高风险适配器首段语言一致性检查
  - `gateway status --json` / `doctor` 暴露最近交付链路摘要
  - `khy gateway trace [requestId]` requestId 级复盘入口
  - `gateway trace` 时间线阶段标注
  - 最近 session 自动回退，修复跨进程诊断证据断裂
  - 同 session 按 `requestId` 过滤语言摘要，修复多请求串扰
  - `aiGateway` 活动状态从模糊“处理中”改为动作化进度提示
  - `aiGateway.generate()` 从全局 hard wall-clock timeout 切换为网关级 activity-based idle watchdog
- 进行中:
  - `agentReadiness` 结构化汇总
  - 脏工作区保护
  - CLI 渲染层状态文本去模糊化
- 待执行:
  - `doctor` 直接附短 requestId 标签
  - `gateway trace --tail-events N`
  - 更多前置上下文阶段的 activity-based timeout 收敛

## 本次修复记录

### 1. 跨进程诊断证据断裂

- 问题:
  - `getLatestDeliveryRequestSummary()` 和 `getLatestLanguageConsistencySummary()` 之前优先依赖当前进程 `sessionId`
  - 当用户在另一个进程执行 `khy doctor` 或 `khy gateway status` 时，刚刚失败的请求证据可能直接丢失
- 修复:
  - 两个摘要接口统一改为先取当前 session，取不到再回退到最近持久化 session
- 结果:
  - `doctor` / `gateway status` 在新进程里也能看到最近一次交付链和语言一致性证据

### 2. requestId 级语言诊断串扰

- 问题:
  - 同一 session 中如果连续发起多个请求，`gateway trace <旧 requestId>` 可能会拿到更新请求的语言事件
- 修复:
  - 语言一致性摘要支持按 `requestId` 精确过滤
- 结果:
  - `khy gateway trace <requestId>` 可以稳定复盘目标请求，不再被后续请求污染

### 3. requestId 复盘可读性不足

- 问题:
  - 时间线之前只有原始事件名，用户需要自己推断处于哪个阶段
- 修复:
  - `gateway trace` 时间线增加阶段标注:
    - `model_request`
    - `tool_call`
    - `tool_result`
    - `model_response`
    - `delivery_final`
    - `language_first_chunk`
    - `language_final_response`
- 结果:
  - 用户可以更快定位交付断点，不再需要手动从原始事件名反推阶段

### 4. 活跃长任务被总时长误杀

- 问题:
  - `aiGateway.generate()` 之前有全局 `wall-clock` 硬超时
  - 即使请求仍在持续输出 chunk、状态或工具结果，只要总时长达到阈值，就会被直接终止
  - 这会造成“任务其实还在推进，但交付链被强行砍断”的假失败
- 修复:
  - 保留 `GATEWAY_WALL_CLOCK_TIMEOUT_MS` 配置名兼容
  - 但将其语义改为“网关级无活动超时”
  - 新逻辑:
    - 有内容 chunk / 状态 / 活动事件 -> 续命
    - 整条链路持续无推进 -> 才超时终止
- 结果:
  - 活跃长任务不会再被总时长误杀
  - 真正卡死时仍会按 idle watchdog 超时退出

### 5. 状态提示过于模糊

- 问题:
  - `aiGateway` 之前会输出 `处理中（Ns）` 这类模糊状态
- 修复:
  - 改为动作化状态，例如 `正在生成响应（已耗时 Ns）`
- 结果:
  - 用户能更清楚判断当前是在工作、等待还是卡住

## 受影响文件

- `backend/src/services/traceAuditService.js`
- `backend/src/services/gateway/aiGateway.js`
- `backend/src/cli/handlers/gateway.js`
- `backend/src/cli/handlers/init.js`
- `backend/src/cli/router.js`
- `backend/src/cli/commandSchema.js`
- `backend/src/services/diagnosticEvents.js`
- `backend/src/services/toolUseLoop.js`
- `backend/src/services/toolCalling.js`
- `backend/src/services/toolPipeline.js`

## 已验证

- 语法检查:
  - `node --check backend/src/services/traceAuditService.js`
  - `node --check backend/src/cli/handlers/gateway.js`
  - `node --check backend/src/services/gateway/aiGateway.js`
- 关键测试:
  - `npx jest backend/tests/services/traceAuditService.requestId.test.js --runInBand`
  - `npx jest backend/tests/gatewayTrace.test.js --runInBand`
  - `npx jest backend/tests/gatewayStatus.endpointVisibility.test.js --runInBand`
  - `npx jest backend/tests/initDoctor.codingAgentSmoke.test.js --runInBand`
  - `npx jest backend/tests/gateway/transportResilience.test.js --runInBand`
  - `npx jest backend/tests/gatewayAdapters.stability.test.js --runInBand`
  - `npx jest backend/tests/aiGateway.stability.regressions.test.js --runInBand`
- 规则检查:
  - `node scripts/check-agent-rules.js --changed`
  - 结果: `0 error(s)`，仅剩仓库既有 warning
