Files
SuperBizAgent-java/mvp/issues/archived/ISS-012-executor-token-budget-and-context-growth.md
T

121 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ISS-012 Executor Token 预算与上下文膨胀
**状态**:已被 ISS-014 吸收并归档(2026-07-22)
**吸收结果**:单 Diagnosis Agent、Harness 集中预算、ACI Tool projection、exact Run audit 与安全 Fallback 已替代本 Issue 的旧 Executor 方案;最终 live 数据见 ISS-014 阶段 7 验收。
**严重程度**:高
**发现时间**:2026-07-20
**关联**:ISS-002、ISS-004、ISS-011
---
## 背景
ISS-011 完成 StateGraph 切换后,复杂 Chat 链路已经具备显式 Node、Gatekeeper、Verifier、Composer 和 Run 级 Trace。但最终 live E2E 暴露出 Executor 的 Token 成本和上下文增长问题:一次只返回安全 Fallback 的请求消耗了超过 11 万 Token。
## 现象
最终验收 Run:
- `runId`:`run-808ac38f-3ad0-4462-a6d0-ed50d8686473`
- 总耗时:`75964ms`
- 最终答案:109 字符,Run 为 `CHAT/SUCCESS`,`degraded=true`
- AgentStep:8 条,其中 Planner 1 次、Executor 7 次
- ToolInvocation:12 次
- Run `total_token_count`:`111802`
Executor 每次模型调用的 Token 逐步上升:
```text
6396 -> 11265 -> 12786 -> 16774 -> 17965 -> 19340 -> 24236
```
工具调用包括 4 次 `lookup_knowledge`、6 次 `query_logs`、1 次 `query_metrics` 和 1 次 `get_available_log_topics`。最终因模型输出缺少 `source_invocation_id`,Gatekeeper 将结果降为 `LOW_CONFID` 并进入安全 Fallback。
## 已确认事实
1. 数据库中 8 条 `agent_step` 均为不同记录,不存在重复插入;`111802` 等于各步骤 `token_count` 的求和。
2. `TokenTrackingChatModel` 当前只保存供应商返回的 `usage.totalTokens`,没有拆分输入、输出、缓存和推理 Token。
3. `ChatService.backfillRunMetrics` 直接累加每条 AgentStep 的 `token_count`。
4. `AgentLoggingHook` 只把模型输入截断为 500 字符写入审计表,无法从当前 Trace 还原模型实际发送的完整 Prompt。
5. Executor 当前没有独立的模型调用次数、工具调用次数或 Token 预算;Graph recursion limit 不能限制 ReactAgent 内部工具循环。
## 初步根因假设
- 每次 Executor 模型调用都会重新携带 Planner 结果、历史消息和之前的工具返回,导致输入上下文随工具循环增长。
- 工具返回内容包含较多日志、知识库结果和检索明细,完整结果被反复带入后续模型请求。
- 工具结果没有稳定返回 `source_invocation_id`,模型无法可靠生成精确证据引用,导致高成本检索后仍然进入 Fallback。
- 当前只能看到 `totalTokens`,尚未确认供应商 usage 中 input/output/cached/reasoning 的精确占比。
## 影响
- 单次诊断成本和延迟不可控,复杂问题可能继续超过模型上下文窗口。
- Token 消耗与最终答案质量不匹配,出现“高成本检索 + 安全降级”的低收益路径。
- 缺少 Token 分项指标,无法建立成本预算、P95 延迟和 degraded rate 门禁。
- Executor 可能重复查询相同或相近的知识域、日志主题和指标。
## 目标
1. 建立按 Run/AgentStep 的 input、output、cached、reasoning Token 可观测性。
2. 为 Executor 增加硬性模型轮数、工具调用和 Token 预算。
3. 将完整工具结果留在 Run Trace/数据库中,模型上下文只接收有界证据投影。
4. 让工具结果直接携带可引用的 `source_invocation_id` 和紧凑 `evidence_refs`。
5. 在预算耗尽时安全结束并明确记录原因,不绕过 Gatekeeper、Verifier 或 Run Trace。
## 建议方案
### 1. Token 统计拆分
- 从 ChatModel usage 中记录 `input_tokens`、`output_tokens`、`cached_tokens`、`reasoning_tokens`(供应商提供时)。
- 保留 `total_token_count` 作为汇总字段,但明确其计算口径。
- 在 `orchestration_trace` 中记录每个 Agent 的累计 Token 和预算命中情况。
### 2. Executor 硬预算
初版建议从以下上限开始,并通过固定 E2E 调整:
- Executor 模型调用最多 4 次。
- 工具调用最多 8 次。
- `lookup_knowledge` 最多 2 次。
- `query_logs` 默认最多返回 5 条日志,并限制单次输出长度。
- 达到预算后停止扩展检索,基于已验真证据输出,或进入带原因的安全 Fallback。
### 3. 有界证据上下文
- 工具完整原始结果继续写入 `tool_invocation`,不直接作为下一轮完整上下文。
- 返回模型的工具视图只保留 invocation ID、工具名、查询条件、有限 evidence refs、excerpt 和 no-evidence 状态。
- 同一工具数组项禁止重复绑定;相同知识域和日志主题不重复查询。
### 4. 证据引用闭环
- 每次 evidence tool 返回结果时直接包含 `source_invocation_id`。
- Executor 输出必须引用该 ID;Gatekeeper 不再依赖事后猜测或唯一候选补全。
- 由于引用失败进入 Fallback 时,Trace 必须记录具体缺失字段和预算消耗。
## 验收标准
- [ ] 每个 AgentStep 可查看 input/output/total Token,供应商支持时可查看 cached/reasoning Token。
- [ ] 固定 `payment-timeout` E2E 的 Token 上限、工具调用上限和最大延迟已定义并通过回归。
- [ ] 连续至少 10 次相同 fixture 运行,Token 和延迟 P95 不超过定义的预算。
- [ ] Executor 预算耗尽时只走安全 Fallback,不绕过 Gatekeeper、Verifier 或 Trace 持久化。
- [ ] 工具返回包含真实 `source_invocation_id`;正常证据链不再因缺少该字段而无谓降级。
- [ ] 12 个 diagnosis eval fixture、Graph workflow/node contract、Trace ownership 回归全部通过。
- [ ] E2E 日志和数据库能按 exact `sessionId + runId` 对齐 Token、工具调用、Fallback 原因和最终状态。
## 非目标
- 不删除 Gatekeeper、Verified Input 或 Verifier。
- 不以降低模型 `maxTokens` 代替上下文治理。
- 不恢复 Sequential/StateGraph 双轨或旧兼容协议。
- 不在本 Issue 中物理删除数据库中的历史 `diagnosis_session` 表。
## 相关文件
- `src/main/java/com/superbiz/agent/hook/TokenTrackingChatModel.java`
- `src/main/java/com/superbiz/agent/hook/AgentLoggingHook.java`
- `src/main/java/com/superbiz/agent/service/ChatService.java`
- `src/main/java/com/superbiz/agent/graph/diagnosis/ReactAgentDiagnosisInvoker.java`
- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java`
- `src/main/resources/prompts/chat-executor-prompt.md`
- `mvp/architecture/stategraph-runtime-architecture.md`
- `devflow/projects/2026-07-17-chat-diagnosis-stategraph-cleanup-docs/evidence.md`