Files
SuperBizAgent-java/interview/architecture-evolution-deep-dive.md
zhuyongxin de5a5b09d9 docs(interview): refresh materials for single-agent harness narrative
Archive pre-refactor interview notes and add current deep-dives on
architecture evolution, issue-derived stories, and evidence gates.
2026-07-24 18:14:49 +08:00

1371 lines
50 KiB
Markdown
Raw Permalink 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.
# SuperBizAgent 架构演进深读
**用途**:巩固知识 + 面试准备 + 举一反三
**不是**:逐字讲稿、纯知识点清单、当前 API 手册
**材料日期**:2026-07-24
**依据**:`mvp/architecture/*` 现行文档、`archive/2026-07-05-legacy`、`archive/2026-07-22-legacy`、ISS-014 / ISS-015
---
## 0. 怎么用这份材料
| 目标 | 用法 |
|---|---|
| 巩固 | 按「决策环」读:目标 → 设计 → 失效模式 → 修复 → 留下的原则 |
| 面试 | 每个决策都能答三句:为什么、出过什么问题、和业界差在哪 |
| 举一反三 | 每节末尾的「迁移问题」用来练:换场景你会怎么选 |
**一条总主线(先背这句)**
> 这个项目一直在解同一个题:**概率系统(LLM)如何在故障诊断里给出可审计、可约束、可回放的结论。**
> 演进不是换框架追热点,而是不断重划边界:**什么交给模型推理,什么必须由确定性系统强制。**
**读的时候盯住四个轴**
1. **谁推理**:单 Agent / 多角色 / Graph
2. **谁约束**:Prompt 约定 / 代码门禁 / Harness
3. **证据如何成立**:隐式检索 / 显式 Tool / 引用验真 / 语义审查
4. **如何证明系统可信**:Trace、Eval、Release、Feedback
**图目录(面试白板优先练带 ★ 的)**
| 图 | 位置 | 白板优先级 |
|---|---|---|
| 核心矛盾:推理放大 / 越界阉割 | §1.2 | ★★ |
| 四阶段演进 | §2 | ★★★ |
| Phase0 医院会诊愿景 | §3.1 | ★ |
| Phase1 三角色 + 双入口 | §4.1 | ★★ |
| Phase2 五段证据流水线 | §5.1 | ★★★ |
| 证据绑定外键模型 | §5.1 | ★★★ |
| Phase2→3 职责迁移 | §6.2 | ★★★ |
| 当前系统总览 | §6.2 | ★★★ |
| Diagnosis 时序 | §6.2 | ★★ |
| 数据三层 | §6.3-C | ★★★ |
| 业界定位 | §6.5 | ★★ |
| Trace / Run 模型 | §7.2 | ★★ |
| 白板 60 秒速画 | §15 | ★★★ |
---
## 1. 问题域:为什么不是「套一个 Chatbot」
### 1.1 故障诊断对系统的真实要求
| 要求 | 普通 Chatbot | 诊断 Agent |
|---|---|---|
| 答案形态 | 通顺、有帮助即可 | 结论必须能指向证据 |
| 错误成本 | 用户再问一次 | 误导排障、误操作风险 |
| 可解释 | 可选 | 必须能回放「查了什么、为何这样说」 |
| 工具 | 可有可无 | 日志/指标/知识库是事实来源 |
| 失败 | 道歉重试 | 要区分:没查到 / 查到了推不出 / 系统故障 |
所以早期文档就把定位写成:**面向故障诊断的可追踪 Agent 工程,不是通用对话机器人。**
### 1.2 核心矛盾(后面所有设计都围着它转)
```text
LLM 擅长:规划路径、归纳症状、组织语言、在不确定下提出假设
LLM 不擅长:保证引用真实、遵守预算、不越权、不在失败时编造
因此:
推理能力要放大
越界能力要阉割
```
```mermaid
flowchart LR
subgraph Prob["概率侧 · 交给模型"]
P1["规划排查路径"]
P2["选择下一个 Tool"]
P3["归纳症状与假设"]
P4["组织诊断表达"]
end
subgraph Det["确定性侧 · 交给系统"]
D1["只读 / Schema / 预算"]
D2["引用是否真实存在"]
D3["是否属于本 Run"]
D4["能否对用户发布"]
end
User["用户问题"] --> Prob
Prob -->|"Draft / tool_call"| Det
Det -->|"放行或 Fallback"| Out["公开通道 SSE"]
Det -.->|"拒绝越界"| Prob
```
**面试一句话**
> 我们不是在提高模型智商,而是在给模型装护栏,并让每次越界都可观测。
**举一反三**
- 客服退款 Agent:同样要把「查订单」与「执行退款」拆成不同权限边界。
- 代码修改 Agent:同样要把「提议 diff」与「落地 apply/merge」拆开。
- 任何 Tool-using Agent:先问「模型输出里哪些字段必须能被系统复验」。
---
## 2. 演进总图:四个阶段在解决什么
```text
Phase 0 愿景:医院会诊式多角色协作
解决「复杂诊断需要分工」的组织问题(设计层)
Phase 1 MVP:Planner / Executor / Verifier + 显式 Tool + Trace
解决「先跑通可追踪闭环」的落地问题
Phase 2 证据工程化:Gatekeeper + Composer + evidence_v2 + 双入口 + Skill
解决「幻觉与证据不可核验」的质量问题
Phase 3 重构:单 Diagnosis ReAct Agent + 确定性 Harness
解决「把 ReAct 拆成多 LLM 角色后的编排税与成本失控」
Phase 4 收敛:ISS-015 停止策略 / Repair / Reasoning 治理 / 信息化 Fallback
解决「架构对了但运行质量与审计治理未完成」
```
```mermaid
flowchart TB
P0["Phase 0 愿景<br/>医院会诊 Multi-Agent"]
P1["Phase 1 MVP<br/>Planner → Executor → Verifier"]
P2["Phase 2 证据工程化<br/>+ Gatekeeper + Composer"]
P3["Phase 3 重构 ★当前<br/>单 ReAct Agent + Harness"]
P4["Phase 4 收敛<br/>ISS-015 运行质量"]
P0 -->|"复杂度前置,先收敛"| P1
P1 -->|"幻觉:引用不可核验"| P2
P2 -->|"编排税 / Token / 重复 ReAct"| P3
P3 -->|"架构冻结后的策略债"| P4
P0 -.- N0["组织问题"]
P1 -.- N1["闭环问题"]
P2 -.- N2["正确性问题"]
P3 -.- N3["运行时问题"]
P4 -.- N4["治理与体验"]
```
```mermaid
flowchart LR
subgraph Add["Phase 0→2:做加法"]
A1["加角色"]
A2["加证据契约"]
A3["加代码验真"]
A4["加双入口 / Skill"]
end
subgraph Move["Phase 3:做迁移,不是做减法能力"]
M1["推理 → 回到单 Agent"]
M2["约束 → 上收 Harness"]
M3["验真语义 → Evidence/Semantic/Release"]
end
Add -->|"负债:编排重复实现 ReAct"| Move
```
**重要心智模型**
- Phase 0→2 是在加能力、加约束。
- Phase 3 不是否定证据工程,而是**把证据工程从「角色流水线」搬进「执行边界」**。
- 面试时最容易说错的是:「我们从复杂架构简化成单 Agent,所以更粗糙」。
正确说法是:「推理合并回 Agent,约束上收到 Harness,证据门禁更硬而不是更软。」
---
## 3. Phase 0:为什么一开始会想到「多 Agent 医院会诊」
### 3.1 为什么这么设计
早期完整架构用医院隐喻:
| 角色 | 隐喻 | 意图 |
|---|---|---|
| Supervisor | 院长 | 调度谁来干、何时停 |
| Planner | 分诊 | 判类型、拆步骤、选专科 |
| SubAgent | 专科医生 | API/DB/Cache 各有工具与 Prompt |
| Verifier | 质检 | 防误诊 |
```mermaid
flowchart TB
U["用户输入"] --> Sup["Supervisor<br/>院长:谁来干 / 何时停"]
Sup --> Pl["Planner<br/>分诊:fault_category + 步骤"]
Pl --> SA["SubAgent 层"]
SA --> API["ExternalApi"]
SA --> DB["Database"]
SA --> Cache["Cache ..."]
API --> V["Verifier 质检"]
DB --> V
Cache --> V
V -->|PASS| R["诊断报告"]
V -->|REVISE| Pl
```
这在**组织设计**上合理:真实 SRE 排障也是「先分流、再专科、再交叉验证」。
同时规划了 Skill、进程隔离、MCP、进化引擎——那是生产级愿景,不是第一周实现清单。
### 3.2 会出现什么问题(如果直接实现)
1. **复杂度前置**:还没证明通用 Executor 不够用,就先拆专科,评测和 Prompt 成本指数上升。
2. **边界模糊**:Planner 既分诊又写报告、SubAgent 既查证又下结论时,出了幻觉不知道该改谁。
3. **没有触发条件的演进**:为“架构完整”而拆,而不是为“可测量的失败模式”而拆。
### 3.3 如何解决(当时的正确收敛)
演进路线文档明确:
- 当前文档只写已可运行的能力。
- SubAgent / MCP / 隔离都要有触发条件(Executor 过载、工具权限差异、评测能量化收益)。
- **没有 baseline 前,不自动优化 Prompt,不拆进程。**
### 3.4 和业界主流的关系
| 方向 | 业界常见 | 本项目早期 | 评论 |
|---|---|---|---|
| Multi-Agent 分工 | CrewAI / AutoGen / 手写角色群 | 医院会诊模型 | 叙事强,落地成本高 |
| 先单 Agent 再拆 | Anthropic 等实践更常从单循环长出来 | 先愿景后收敛 MVP | 本项目最终也回到「先单后拆」 |
| 专科路由 | 大厂内部常按域拆服务/Agent | 作为 P2 演进项 | 触发条件写清楚是加分项 |
**迁移问题**
> 如果你负责一个「销售 + 售后 + 财务」客服,你会第一天就拆三个 Agent 吗?
> 什么指标出现后你才拆?
---
## 4. Phase 1:MVP 为什么是「Planner → Executor → Verifier」
### 4.1 为什么这么设计
目标从“完整医院”收敛为“可演示、可追踪的诊断闭环”:
```text
用户问题
→(意图:只有诊断才走全链路)
→ Planner:定排查方向
→ Executor:调 lookup_knowledge / logs / metrics
→ Verifier:质量门禁
→ session / step / tool_invocation 可回放
```
```mermaid
flowchart TB
subgraph Entries["双入口"]
ChatIn["POST /api/chat"]
AiOpsIn["POST /api/ai_ops"]
end
ChatIn --> CS["ChatService"]
AiOpsIn --> AS["AiOpsService"]
CS --> Intent{"意图"}
Intent -->|闲聊/文档| Light["轻量路径"]
Intent -->|诊断| P["Planner"]
P --> E["Executor"]
E --> T["Tools<br/>knowledge / logs / metrics"]
T --> E
E --> V["Verifier LLM"]
V --> Ans["答案 + self_evaluation"]
AS --> Sup["Supervisor"]
Sup --> P2["Planner"]
Sup --> E2["Executor"]
E2 --> T2["Prometheus / logs / knowledge"]
T2 --> Rule["Rule Evaluation"]
Ans --> Trace["session / step / tool_invocation"]
Rule --> Trace
```
并行还有 AIOps 入口:告警驱动,Supervisor 调度 Planner/Executor,先用**规则评估**做轻量聚焦检查。
**设计动机拆解**
| 决策 | 动机 |
|---|---|
| 意图识别前置 | 闲聊/文档问答不该付全链路 Token |
| Planner 与 Executor 分离 | 避免「边想边查」时计划被工具噪声带偏(当时的假设) |
| Verifier 独立 | 写答案的人不该同时当唯一质检 |
| 工具显式 | 决策可见,才能进 Trace |
| Chat 与 AIOps 双入口 | 交互诊断 vs 告警诊断触发方式不同 |
### 4.2 出现的问题
1. **Verifier 是模型**:能抓“说不通”,难抓“引用根本不存在”。
2. **Executor 输出形态不稳**:有时直接写用户答案,有时罗列工具结果,后续难自动验。
3. **RAG 早期 L0 可跳过 L1**:关键词唯一命中被当成高置信,语义上可能完全不相关。
4. **AIOps 与 Chat 验证强度不一致**:一边规则、一边 LLM,故事难统一。
### 4.3 如何解决(通向 Phase 2)
- 坚持 `lookup_knowledge` 是 Tool,不用隐式 Chat Advisor 吞掉检索。
- L0 从“可终局召回”降为 hint(domain/entity + filter 信号)。
- 开始要求更结构化的证据输出,并引入代码级验真(下一阶段 Gatekeeper)。
### 4.4 和业界主流的区别
| 主题 | 业界常见做法 | Phase 1 选择 | 差异本质 |
|---|---|---|---|
| RAG 接入 | Spring AI Advisor / 中间件静默注入上下文 | 显式 `lookup_knowledge` Tool | **可观测的 Agent 决策** vs 隐式增强 |
| 质量 | 输出后再人工抽检,或单一 LLM-as-Judge | 链路内 Verifier | 已有门禁意识,但还偏“模型审模型” |
| 编排 | 直接单 ReAct | 先拆 Planner/Executor/Verifier | 用角色表达生命周期,后续证明这是重复实现 |
| 告警场景 | 独立 SOAR/runbook 系统 | 同进程 AIOps Agent + rule eval | MVP 一体,但入口语义分叉 |
**面试深挖答法**
> 问:为什么 RAG 不走 Advisor?
> 答:Advisor 适合“聊天时附带资料”。诊断系统要回答的是「第几步为什么查库、查到了什么、结论绑哪条证据」。
> 隐式检索会让 Trace 里只剩最终答案,丢了决策过程。这是可审计性要求,不是接口偏好。
**迁移问题**
> 法律问答系统能否用隐式 RAG?若答案必须附法条编号,你的检索还敢静默注入吗?
---
## 5. Phase 2:证据工程化——本项目最「重」也最有辨识度的阶段
### 5.1 为什么这么设计
到这个阶段,团队已经看清:**诊断 Agent 的第一敌人不是文笔,是证据幻觉。**
于是 Chat 复杂链路变成:
```text
Planner
→ Executor(只产微观事实,不产最终用户答案)
→ Gatekeeper(代码验引用:invocation / raw_path / excerpt)
→ Verifier(只判断:已验真 excerpt 能否推出 claim)
→ Composer(只表达被允许的内容)
```
```mermaid
flowchart LR
PL["Planner<br/>plan / skill"]
EX["Executor<br/>只产微观事实"]
GK["Gatekeeper<br/>0 LLM 引用验真"]
VF["Verifier<br/>能否推出 claim"]
CM["Composer<br/>只表达允许内容"]
OUT["用户答案"]
PL --> EX
EX --> Tools["Tools"]
Tools --> EX
EX -->|"executor_evidence_v2"| GK
GK -->|"verified bindings"| VF
VF -->|"PASS / LOW / REJECT"| CM
CM --> OUT
Tools -.->|"tool_invocation<br/>+ evidence_refs"| GK
```
并固化契约 `executor_evidence_v2`:
```text
每条 claim 必须带 evidence_bindings:
tool_name
+ source_invocation_id
+ raw_path e.g. $.alerts[0] / $.no_evidence
+ evidence_excerpt 必须能在工具返回中找到的原文片段
```
```mermaid
flowchart TB
Claim["claim<br/>CPU=92% 告警 firing"]
Bind["evidence_binding"]
Inv["tool_invocation id=517"]
Raw["raw_response JSON"]
Path["raw_path: $.alerts[0]"]
Ex["evidence_excerpt 原文片段"]
Claim --> Bind
Bind --> Inv
Bind --> Path
Bind --> Ex
Inv --> Raw
Path -->|"必须能定位"| Raw
Ex -->|"必须是子串/抽取"| Raw
GK["Gatekeeper = 外键 + 路径 + 原文检查"]
Bind --- GK
Raw --- GK
```
**这是在学数据库的什么?**
> 有点像「外键约束」:claim 不能指向不存在的 invocation,也不能指向对不上的路径。
> Gatekeeper 就是约束检查器;Verifier 才是业务规则引擎。
### 5.2 分层门禁在解决哪类错误
| 错误类型 | 例子 | 谁抓 |
|---|---|---|
| 伪造调用 | 编造 invocation id | Gatekeeper |
| 路径漂移 | id 对但 raw_path 指到别的字段/条目 | Gatekeeper |
| excerpt 编造 | 引用了工具没返回的句子 | Gatekeeper |
| 推不过去 | excerpt 真实,但推不出 root cause | Verifier |
| 表达越权 | 把 no-evidence 说成“已排除根因” | Composer / 规则 |
| 告警跑偏 | payload 是 A,报告大谈 B 告警 | AIOps rule evaluation |
**负向证据(negative_observation)为什么重要**
排障里「查了但没有」也是信息。
若不建模 `$.no_evidence`,模型要么沉默,要么把“没查到”说成“不存在问题”。
### 5.3 这个阶段实际暴露/放大的问题
ISS-014 后来总结得很准——**设计在质量上前进了,在运行结构上负债了**:
#### 问题 A:ReAct 被外层重复实现
```text
完整 ReAct 生命周期:
想 → 动 → 观察 → 再想 → 最终答
被拆成多个 LLM 角色后:
Planner ≈ 想
Executor ≈ 动/观察循环
Verifier ≈ 自检
Composer ≈ 最终答
```
```mermaid
flowchart TB
subgraph Native["框架已具备的 ReAct"]
direction LR
T["Thought"] --> A["Action"] --> O["Observation"] --> T
O --> F["Final"]
end
subgraph Outer["Phase2 外层又演一遍"]
direction LR
PL["Planner≈Thought"] --> EX["Executor≈Act/Obs"]
EX --> VF["Verifier≈自检"]
VF --> CM["Composer≈Final"]
end
Native -.->|"重复实现 + JSON 接力税"| Outer
```
于是你要额外维护:多 Prompt、多 Schema、角色间 JSON 搬运、多套重试、ThreadLocal 隐式状态、失败×低置信×补证据的分支组合。
#### 问题 B:Tool 返回面向开发者,不面向 Agent(违反 ACI)
一次检索结果里混着:
- Agent 真正需要的证据
- rerank/debug 字段
- 重复正文与打包上下文
- 不一致的空结果/错误语义
后果:上下文膨胀、模型抓错字段、Token 预算被噪声吃掉(ISS-012)。
#### 问题 C:确定性约束与业务编排耦合
Gatekeeper 本质是**纯函数式校验**,却以流水线“角色/步骤”的姿态嵌在业务编排里,导致:
- 生命周期和业务步骤缠在一起
- 失败语义要和 LLM 节点失败一起解释
- 后续想做预算/取消/投影时,没有统一执行边界
#### 问题 D:双入口与多验证器让产品语义分叉
Chat 与 AIOps 两套服务、两套验证强度、两套叙事,Demo 很全,但“系统到底是什么”变难讲,实现分叉成本高。
### 5.4 当时为什么仍值得做(面试一定要会辩护)
即使后来重构掉多角色,Phase 2 不是弯路,而是**必要的认知阶段**:
1. 证明了「引用必须可机器复验」。
2. 证明了「写证据的人 / 验证引用的人 / 判断推导的人 / 对外表达的人」关注点不同。
3. 沉淀了 eval fixture、trace 检查清单、bad case(幻觉、窄范围越权、负向证据等)。
4. 为 Phase 3 提供了**可迁移的门禁语义**(不是推倒重来,是换装载位置)。
**面试金句**
> Phase 2 解决的是正确性模型;Phase 3 解决的是运行时模型。
> 没有 Phase 2,单 Agent 只会更快地产生不可验的漂亮废话。
### 5.5 和业界主流的区别
| 能力 | 常见开源 Agent 示例 | Phase 2 | 你的辨识度 |
|---|---|---|---|
| 工具调用 | ReAct / OpenAI tool calls | 有 | 常规 |
| 引用标注 | 让模型自己说 sources | **强制 binding + 代码核验** | 强 |
| 输出分层 | 直接 final answer | evidence 草稿与用户答案分离 | 强 |
| 验证 | 单次 LLM judge | 确定性 Gatekeeper + 语义 Verifier | 强 |
| 编排 | 一个 loop 或一个 graph 节点集 | 固定 Sequential 五段 | 偏重,后成负债 |
| RAG | 中间件注入或单次 retrieve | Tool 化 + L0 hint + VectorStore/fallback | 工程化中等偏上 |
对比常见口号:
- **RAGAS / LLM-as-Judge**:偏离线或事后评估;本项目把一部分检查**前移到请求路径**。
- **LangGraph hitl / interrupt**:偏人工确认;本项目 Phase 2 偏自动门禁。
- **Guardrails 类库**:常做 schema/topic/toxicity;本项目护栏围绕**证据所有权与可推导性**。
**迁移问题**
> 若你做「根据内部 Wiki 答合规问题」,最小可行的 Gatekeeper 要校验哪些字段?
> (文档 id、chunk id、原文 offset、quote 是否子串匹配……)
---
## 6. Phase 3:为什么重构为「单 ReAct Agent + Harness」
### 6.1 重构触发条件(不是审美驱动)
ISS-014 的判定可以翻译成四个可对外讲的信号:
1. **结构重复**:外层编排 ≈ 框架已提供的 ReAct。
2. **成本症状**:上下文重复搬运、Token 易爆、多角色固定税。
3. **失败语义组合爆炸**:每个角色的 FAIL/LOW_CONFID/RETRY 交叉。
4. **安全能力放错层**:该确定性的事还在业务流水线里“扮演角色”。
### 6.2 目标结构
```text
POST /api/chat (唯一执行入口, SSE)
→ ChatApplicationUseCase
→ Intent Router
SYSTEM_CHAT | KNOWLEDGE_QUERY | DIAGNOSIS
DIAGNOSIS:
Diagnosis ReAct Agent
规划 / 选 Tool / 观察 / 写 DiagnosisDraft
→ EvidenceGuard (0 LLM, 结构+引用+Run ownership)
→ SemanticGuard (隔离单轮 LLM, 无 Tool/无记忆)
→ Release Policy (SUPPORTED 才公开, 否则 SAFE_FALLBACK / stable failure)
```
```mermaid
flowchart TB
Browser["Browser / API Client"] --> Chat["POST /api/chat<br/>named SSE"]
Chat --> App["ChatApplicationUseCase"]
App --> Router{"Intent Router"}
Router --> Sys["SYSTEM_CHAT<br/>无 Tool"]
Router --> Know["KNOWLEDGE_QUERY<br/>单次 lookup + 引用校验"]
Router --> Diag["DIAGNOSIS"]
Diag --> Agent["Diagnosis ReAct Agent"]
Agent --> TB["Harness ToolBoundary"]
TB --> Redis["Redis canonical"]
TB --> Agent
Agent --> Draft["DiagnosisDraft"]
Draft --> EG["EvidenceGuard<br/>0 LLM"]
EG --> SG["SemanticGuard<br/>隔离单轮"]
SG --> RP["Release Policy"]
RP -->|SUPPORTED| SSE["公开 content"]
RP -->|否则| FB["SAFE_FALLBACK / failure"]
App --> Run["diagnosis_run"]
Agent --> Step["agent_step metadata"]
TB --> Inv["tool_invocation metadata"]
App --> TL["diagnosis_trace_event"]
Agent --> RA["agent_reasoning_audit"]
```
**职责迁移图(面试最常画)**
```mermaid
flowchart LR
subgraph Old["Phase 2 角色"]
O1["Planner"]
O2["Executor"]
O3["Gatekeeper"]
O4["Verifier"]
O5["Composer"]
end
subgraph New["Phase 3 归属"]
N1["Diagnosis Agent 内部"]
N2["Agent + ToolBoundary"]
N3["EvidenceGuard"]
N4["SemanticGuard"]
N5["Draft + Release Policy"]
end
O1 --> N1
O2 --> N2
O3 --> N3
O4 --> N4
O5 --> N5
```
```mermaid
sequenceDiagram
participant C as Client
participant App as UseCase
participant A as Diagnosis Agent
participant TB as ToolBoundary
participant R as Redis
participant EG as EvidenceGuard
participant SG as SemanticGuard
participant RP as Release
C->>App: POST /api/chat
App->>C: metadata(session_id, run_id)
App->>A: query + safe previous_turn
loop ReAct
A->>TB: tool + tool_call_id + args
TB->>R: canonical raw + projection
TB-->>A: bounded agent_result
end
A-->>App: DiagnosisDraft
App->>EG: Draft + current Run invocations
EG-->>App: verified snapshot / fail
App->>SG: query + Draft + snapshot
SG-->>App: SUPPORTED / UNSUPPORTED
App->>RP: decide
RP-->>C: content | fallback
RP-->>C: done(SUCCESS|FALLBACK|FAILED)
```
**职责重划一览**
| 旧角色 | 新归属 | 说明 |
|---|---|---|
| Planner | Diagnosis Agent 内部 | 不再单独付一次“只规划”的链路税 |
| Executor Tool loop | Diagnosis Agent + ToolBoundary | 循环回到 Agent;边界在 Harness |
| Gatekeeper | EvidenceGuard | 仍 0 LLM,更明确是执行约束 |
| Verifier | SemanticGuard | 保留“独立上下文审查”,去掉工具与记忆 |
| Composer | Agent Draft + Release Policy | 表达权在 Agent,**发布权**在 Harness |
| ChatService 大流程状态机 | UseCase + RunControl | 生命周期 first-terminal-wins |
| AIOps 独立入口 | (收敛到统一 Chat 叙事) | 减少产品分叉(以现行文档为准) |
### 6.3 关键设计为什么“长这样”
#### A. 单 Agent:把推理完整性还给一次上下文
**为什么**
- 诊断需要根据观察动态改计划;硬切成 Planner 产出静态 plan 再交给 Executor,容易在信息到齐前定死路线,或为修正路线再开重试环。
- 同一 Run 内共享连贯工作记忆,比 JSON 接力更符合 ReAct。
**不是什么**
- 不是取消规划,而是取消“规划必须是另一个 Agent 节点”。
- 不是取消验证,而是验证不再以“业务协作角色”存在。
#### B. Harness:确定性控制面
Harness 管的是:
- Run/deadline/cancel/预算
- Tool schema/只读/次数
- canonical invocation(Redis)与 Agent projection
- Evidence / Semantic / Release
- metadata Trace 与 reasoning 审计隔离
**一句话**
> Agent 是员工;Harness 是门禁、报销制度、权限系统和发布流程。
#### C. 数据三层(ACI 的核心落地)
```text
Redis canonical invocation
完整 request / raw_response / agent_result
短 TTL,Harness only
Agent projection
有界、聚合、可继续推理的观察
唯一允许回流 Agent 的视图
Durable audit (MySQL)
长期 metadata:谁、何时、哪个 tool、状态、字节数…
不存 Prompt 全文、不存 raw、不存 Thought 当事实
```
```mermaid
flowchart TB
ToolExec["Tool 真实执行"] --> Raw["raw_response 可能很大"]
Raw --> Canon["Redis canonical<br/>Harness only · TTL · 完整"]
Canon --> Proj["ToolResultProjector"]
Proj --> AgentView["agent_result 有界投影"]
AgentView --> Agent["Diagnosis Agent 继续推理"]
Canon --> EG["EvidenceGuard 验真"]
AgentView --> EG
ToolExec --> Meta["MySQL tool_invocation<br/>metadata-only 长期审计"]
Agent -.->|"禁止直连"| Canon
Agent -.->|"禁止见 raw"| Raw
```
```mermaid
flowchart TB
Q["同一 Tool 调用,三份不同视图"]
Q --> C["① canonical raw<br/>验真用 · 短 TTL · Harness only"]
Q --> P["② projection<br/>推理用 · 有界 · 回 Agent"]
Q --> M["③ metadata audit<br/>长期用 · MySQL · 无正文 raw"]
```
这直接回应 Phase 2 的上下文膨胀:
**验真需要完整事实,推理只需要有界观察,审计需要长期元数据——三者不是同一份 JSON。**
#### D. EvidenceGuard vs SemanticGuard 为什么拆开
| | EvidenceGuard | SemanticGuard |
|---|---|---|
| 要不要模型 | 否 | 是(隔离单轮) |
| 问什么 | 引用是否真实、是否属于本 Run、结构是否合法 | 整份报告是否被证据支持、是否越界表达 |
| 失败含义 | 数据/契约问题 | 语义/推理问题 |
| 类比 | 类型检查 / 外键 | 代码 review / 逻辑审查 |
```mermaid
flowchart TB
Draft["DiagnosisDraft"] --> EG{"EvidenceGuard<br/>物理/结构/归属"}
EG -->|fail| FB1["不可发布<br/>契约/引用问题"]
EG -->|verified snapshot| SG{"SemanticGuard<br/>整份语义是否越证"}
SG -->|UNSUPPORTED| FB2["SAFE_FALLBACK"]
SG -->|SUPPORTED| RP["Release<br/>公开 typed report"]
EG -.- E1["0 LLM"]
SG -.- E2["隔离 · 无 Tool · 无记忆"]
```
混成一个“超级 Verifier”会重新出现:模型既要装法官又要装扫描仪,且失败原因不可分。
#### E. Release Policy 为什么必须存在
即使 Draft 写得漂亮:
- Evidence 失败 → 不能当成功答案出去
- Semantic UNSUPPORTED → 只能 SAFE_FALLBACK
- cancel/timeout → 禁止 late content
```mermaid
flowchart LR
Internal["内部 Draft<br/>staging 制品"] --> Gate{"Release Policy"}
Gate -->|SUPPORTED| Pub["公开 SSE<br/>production"]
Gate -->|UNSUPPORTED / evidence fail| Safe["SAFE_FALLBACK<br/>有界说明"]
Gate -->|tech fail| Fail["stable failure"]
Gate -->|cancel/timeout| Stop["终态 · 禁 late content"]
```
**公开通道与内部草稿必须切断。**
这对应安全发布思想:staging 制品不能直接当 production。
#### F. Reasoning 分表
Provider 若返回 `reasoning_content` 等字段:
- 可进 `agent_reasoning_audit`(截断、计字节)
- 不进普通 Trace / SSE / Evidence / 业务判断
- Provider 没返回时记 unavailable,**禁止伪造**
这是在学:
**思维链若存在,它是敏感审计数据,不是可引用事实,更不是产品功能输出。**
### 6.4 重构时明确放弃/降级的东西
| 放弃 | 原因 |
|---|---|
| 业务层 StateGraph/多角色 Sequential | 与框架 ReAct 重复,编排税高 |
| 以 DB `tool_invocation.id` 为引用主键的重协议 | 改为框架 `tool_call_id` + 当前 Run ownership,贴合运行时 |
| 完整历史进下一轮 | PreviousTurn 仅最近一次成功发布的有界字段 |
| 把 self_evaluation 多种 LLM 评估缠在主叙事 | 收敛到 Guard + Release + Timeline |
| 推倒证据思想 | **保留**“先物理验真、再语义审查、再发布” |
### 6.5 和业界主流架构的对照(面试高频)
#### 6.5.1 总表
| 架构族 | 代表形态 | 优点 | 风险 | 与本项目 |
|---|---|---|---|---|
| 单 ReAct + Tools | 多数 Demo / 助手 | 简单、动态 | 易幻觉、难审计 | **骨架相同**,本项目多了硬 Harness |
| Multi-Agent 协作 | Crew / 手写角色群 | 分工清晰 | 重复上下文、权责漂移 | Phase 2 接近;Phase 3 退出主路径 |
| Graph 编排 | LangGraph 等 | 可控分支、打断、持久状态 | 易把业务状态机写重 | **业务层不用 Graph**;框架内部实现无关 |
| Router + Experts | 意图路由到专科 | 域深 | 需分类准、评测全 | Intent Router 轻量存在;专科专家未拆 |
| Agent + Guardrail 管道 | 输入/输出护栏产品 | 合规快 | 常缺“证据所有权” | 本项目护栏更偏 **tool evidence** |
| SOAR / Runbook | 固定剧本自动化 | 稳定可预期 | 难覆盖长尾自然语言 | Playbook 是演进项,不是当前主路径 |
#### 6.5.2 你要能讲清的「三个不一样」
**1)和“纯 ReAct Demo”不一样**
```text
纯 ReAct: model ↔ tools ↔ final text
本项目: model ↔ (ToolBoundary/projection) ↔ draft
↔ EvidenceGuard ↔ SemanticGuard ↔ Release ↔ public SSE
+ Run budget/cancel + Timeline + reasoning audit
```
```mermaid
flowchart TB
subgraph Demo["纯 ReAct Demo"]
M1["Model"] <--> T1["Tools"]
M1 --> F1["final text 直接出门"]
end
subgraph Ours["本项目"]
M2["Model"] <--> TB["ToolBoundary + projection"]
M2 --> D["Draft 仅内部"]
D --> G1["EvidenceGuard"]
G1 --> G2["SemanticGuard"]
G2 --> R["Release"]
R --> PUB["public SSE"]
H["Harness: budget / cancel / timeline / reasoning audit"]
H -.-> M2
H -.-> TB
H -.-> R
end
```
**2)和“Multi-Agent 很强”叙事不一样**
> 多 Agent 的正确动机是:权限不同、知识不同、失败域不同、需要并行。
> 错误动机是:用角色名重新描述一遍 ReAct 步骤。
> 我们踩过后面这种坑,所以合并。
```mermaid
flowchart TB
subgraph Wrong["错误动机:给 ReAct 步骤起名"]
W1["Planner"] --> W2["Executor"] --> W3["Verifier"] --> W4["Composer"]
end
subgraph Right["合法动机:真正的失败域/权限不同"]
R1["只读诊断 Agent"]
R2["变更执行 Agent<br/>需审批"]
R3["财务退款 Agent<br/>强权限"]
end
Wrong -.->|"本项目 Phase2 偏这类"| X["合并回单 Agent"]
Right -.->|"才值得 Multi-Agent"| Y["保持拆分"]
```
**3)和“上 LangGraph 就企业级”不一样**
> Graph 解决的是状态与边;企业级还依赖:预算、取消、发布、数据分层、评测、审计隔离。
> 没有这些,Graph 只是更复杂的 if-else。
```mermaid
flowchart TB
subgraph Axes["横轴:编排复杂度 →  纵轴:控制面完整度 ↑"]
direction TB
Q2["② 目标区<br/>编排克制 + 控制面强<br/>★ 本项目当前"]
Q1["① 重 Graph 且有护栏<br/>企业工作流 + 审批/预算"]
Q3["③ Demo 常见区<br/>纯 ReAct · 控制面弱"]
Q4["④ 重编排轻护栏<br/>裸 Graph / 角色流水线过重"]
end
Q2 ~~~ Q1
Q3 ~~~ Q4
P2["Phase2 五段"] -.->|"偏右上但仍角色税高"| Q4
Now["Phase3 Agent+Harness"] --> Q2
Demo["纯 ReAct Demo"] --> Q3
```
白板口述版(不必画象限,画两点对比即可):
```text
控制面强
^
| ★ 本项目(单 Agent + Harness)
| · 企业 Graph+护栏
|
| Phase2 五段(能力强,编排税高)
|
| 纯 ReAct Demo 裸 Graph 无护栏
+-------------------------------------> 编排复杂
```
#### 6.5.3 和 OpenAI/Anthropic 工具调用范式
| 点 | 主流 API 范式 | 本项目 |
|---|---|---|
| tool_call_id | 协议层已有 | **直接作为证据引用主键之一**,不另造平行 ID 体系 |
| tool result | 多原样回灌 | **必须经 projector**,raw 进 Redis canonical |
| 并行 tools | 常见 | 受预算与只读边界约束 |
| 输出 | 自由文本或 JSON mode | 结构化 `DiagnosisDraft` + 分析项绑定 tool_call_id |
#### 6.5.4 和 RAG 主流(Modular RAG / Agentive RAG)
| 点 | 主流 | 本项目 |
|---|---|---|
| Query rewrite / rerank | 管线模块可选 | 可作为检索内部能力,但**对 Agent 应投影掉调试细节** |
| 引用 | 答案角标 | 运行时绑定 tool_call + Guard |
| 知识问答 vs 诊断 | 常混一个 bot | Intent 拆 SYSTEM / KNOWLEDGE / DIAGNOSIS |
| 评测 | 离线黄金集 | 有 diagnosis eval;RAG 有历史闭环设计 |
### 6.6 重构后仍未结束的问题(诚实加分)
ISS-015 说明架构冻结后的运行质量债:
- 重复检索直到预算耗尽
- Evidence Repair 的 schema/parse 问题
- Reasoning 真实 Provider 与访问治理未完
- Fallback 信息量不足(用户不知道已经看到了什么)
**面试怎么讲**
> 重构完成不等于产品完成。我们把架构风险从“结构错误”推进到了“策略与治理”,并用独立 Issue 跟踪,而不是偷偷在主链打补丁改变架构。
**迁移问题**
> 你在什么情况下会把已经合并的单 Agent 再拆开?请给出 3 个可量化触发条件。
> (参考本项目旧路线:Executor prompt 膨胀、工具权限显著分叉、分类评测证明拆分收益。)
---
## 7. 横切演进:五条独立故事线
面试官不一定按时间问,可能横切打穿。下面每条都按「为什么 → 问题 → 解决 → 业界」压缩。
### 7.1 RAG
| 阶段 | 策略 | 失效 | 收敛 |
|---|---|---|---|
| 早期 | L0 唯一命中可跳过 L1 | 关键词≠语义 | L0 降级为 hint |
| 中期 | VectorStore 主路径 + SDK fallback | 迁移期 schema/score 语义变 | auto 模式保主链 |
| 全程 | 显式 Tool | 隐式 Advisor 丢决策 | 坚持 Tool 化 |
| 当前 | projector 后的有界 evidence | 原始检索大包撑爆上下文 | canonical/projection 分离 |
```mermaid
flowchart TB
subgraph Early["早期 L0 可终局"]
E0["L0 关键词"] -->|唯一命中| Skip["跳过 L1 · 当答案"]
E0 -->|0/多命中| L1a["L1 向量"]
end
subgraph Now["当前"]
A["Agent 显式 lookup_knowledge"] --> L0["L0 hint<br/>domain/entity/filter"]
L0 --> L1["L1 VectorStore"]
L1 -->|fail| FB["Milvus SDK fallback"]
L1 --> Proj["projector 有界 evidence"]
FB --> Proj
Proj --> AgentObs["Agent 观察"]
Proj --> Canon["canonical 供 Guard 验真"]
end
Early -.->|"关键词≠语义"| Now
```
**业界差在**:很多系统优化召回率;本项目同等强调**召回结果如何成为可引用证据**。
### 7.2 Trace 与数据模型
```text
早期: session + step + tool_invocation
→ 中期: + diagnosis_run 精确一次运行
→ 当前: run 为真理源
+ 统一 diagnosis_trace_event Timeline
+ agent_step / tool_invocation metadata-only
+ agent_reasoning_audit 独立
```
```mermaid
flowchart TB
CS["chat_session<br/>sessionId 多轮目录"]
CS --> R1["diagnosis_run runId=1"]
CS --> R2["diagnosis_run runId=2"]
R1 --> S1["agent_step metadata"]
R1 --> I1["tool_invocation metadata"]
R1 --> T1["diagnosis_trace_event Timeline"]
R1 --> A1["agent_reasoning_audit 受限"]
API1["GET .../trace?runId="] --> T1
API1 --> S1
API1 --> I1
API2["GET .../trace/reasoning?runId="] --> A1
API1 -.->|"不返回 reasoning 原文"| X["普通审计面"]
API2 -.->|"敏感审计面"| Y["独立治理 ISS-015"]
```
原则:
- 禁止“取最新一条”代替 exact `runId`
- Trace 写失败可观测,但不应改变业务结果
- 普通 Trace API 不返回 reasoning 原文
**业界差在**:很多 Demo 只有 LangSmith 外部 tracing;本项目把**业务可读 Timeline** 当作产品能力(并对敏感 reasoning 另通道)。
### 7.3 入口与会话
```text
双入口 Chat/AIOps
→ 统一 Chat + Intent
PreviousTurn: 全历史 / 失败上下文
→ 仅最近 SUCCESS published 有界字段
```
原则:多轮要的是**安全状态接力**,不是把噪声和未验证草稿接着喂给下一轮。
### 7.4 质量体系
```text
人工看 Demo
→ Gatekeeper/Verifier 在线门禁
→ diagnosis eval fixtures + baseline
→ Trace inspection checklist
→ 重构后 E2E + ISS-015 运行质量
```
原则:架构变更必须能指出**哪类 case 从红变绿/从绿变红**。
### 7.5 安全发布
```text
模型直接吐最终答案
→ Verifier 后再答
→ Draft 永不为公开,除非 Release 点头
```
类比持续交付:构建产物 ≠ 生产流量。
---
## 8. 决策环模板(用来巩固任意设计点)
对任何一个设计点,用同一模板自问自答:
```text
1. 威胁模型:若没有它,最可能出现什么坏结果?
2. 责任人:这件事该由模型判断,还是系统强制?
3. 数据面:完整事实 / 模型可见 / 长期审计 是否分层?
4. 失败语义:失败时用户看到什么?内部能诊断什么?
5. 可证伪:用什么 eval/trace 证明它有效?
6. 演进触发:什么指标会让我们改掉它?
```
### 练习:套到「SemanticGuard 无 Tool」
1. 威胁:Guard 自己再查库 → 主 Agent 与 Guard 证据集不一致,审查失去基线。
2. 责任:语义是否成立交给模型;能否再取证不交给它。
3. 数据:只给 query + full draft + verified snapshot。
4. 失败:技术失败有限重试后降级,不把内部异常吐给用户。
5. 可证伪:unsupported-claim、fabricated-invocation 等 fixture。
6. 触发:若误杀率过高,优先生证据投影与 Draft schema,而不是给 Guard 加 Tool。
---
## 9. 面试题库(按深度)
### 9.1 2 分钟:你的系统是什么
**结构建议**
1. 领域:故障诊断,不是通用聊天。
2. 当前形态:单 Diagnosis Agent + Harness 门禁 + 唯一 Chat 入口。
3. 演进一句:多角色证据流水线教会我们验真,再重构掉重复的 ReAct 编排。
4. 差异化:证据所有权、发布策略、Run 级回放。
### 9.2 为什么题(必练)
| 问题 | 得分要点 |
|---|---|
| 为什么最终单 Agent? | 多角色重复 ReAct;合并推理,上收约束 |
| 为什么还要 SemanticGuard? | 物理真不等于语义成立;且必须隔离上下文 |
| 为什么 EvidenceGuard 不用模型? | 引用归属是确定性的;用模型会引入不可复现误判 |
| 为什么 Redis 存 raw、MySQL 不存? | 验真要完整、长期存要控敏控体积、Agent 不能见 raw |
| 为什么 reasoning 单独 API? | 敏感、非事实、防污染普通审计与产品通道 |
| 为什么 PreviousTurn 极简? | 防把失败/fallback/raw 污染下一 Run |
| 为什么不业务层上 Graph? | 要的是边界清晰不是边更多;框架内部实现另算 |
### 9.3 对抗题(高级)
**Q:多 Agent 不是更清晰吗?你们是不是退步了?**
A:清晰应体现在**边界**(谁能写生产、谁能看 raw、谁能发布),不是体现在**角色数量**。
我们把 Gatekeeper/Verifier/Composer 的**语义**保留为 Guard/Release,把重复的 LLM 角色去掉。
角色变少,强制约束变多——这是进展。
**Q:和 LangGraph 生产案例比,你们会不会太简陋?**
A:Graph 擅长长流程状态、人机回环、复杂分支。
我们当前主路径是短周期诊断 ReAct,瓶颈在证据与发布,不在多图分支。
若以后出现:多日工单、人工批准变更、跨系统编排,再评估 Graph/工作流引擎——那是触发条件,不是名片。
**Q:SemanticGuard 不还是 LLM-as-Judge 吗?靠谱吗?**
A:是,所以它被降权:
- 只能看已验真快照;
- 无 Tool 不能“补证据自圆其说”;
- 不能单独发布,必须过 Release;
- 技术失败有降级路径。
它不是唯一真理,而是**最后一道语义保险丝**。
**Q:你们如何证明重构没有丢掉 Phase 2 的防幻觉能力?**
A:映射门禁 + 回归夹具 + E2E trace:
伪造引用、无证据负向观察、unsupported claim、narrow scope 等 case;
并看 release_outcome 与 timeline 事件是否仍能解释失败阶段。
### 9.4 让你“现场设计”的题(举一反三)
1. 给「SQL 查询 Agent」设计 EvidenceGuard:如何防止 `DROP`、如何防止编造查询结果?
2. 给「改代码 Agent」设计 Release Policy:什么情况下允许自动 PR?什么必须 human approval?
3. 工具从 3 个变成 30 个时,你先上 MCP 还是先上 Tool Registry + 权限组?为什么?
4. 若产品要“展示思考过程”,你如何在不污染事实证据的前提下做 UI?
每题都试着用第 8 节模板答。
---
## 10. 一张总对照表(背这张就够串场)
| 维度 | Phase 1 | Phase 2 | Phase 3(当前) |
|---|---|---|---|
| 主问题 | 跑通闭环 | 证据可核验 | 去掉重复编排、收敛控制面 |
| 推理结构 | 三角色 | 五段流水线 | 单 ReAct Agent |
| 确定性验真 | 弱/无 | Gatekeeper | EvidenceGuard |
| 语义审查 | Verifier | Verifier | SemanticGuard(隔离) |
| 对外表达 | 多在 Executor/Verifier 后直接 | Composer | Draft + Release |
| 工具结果 | 较原始 | 进 DB 细节多 | canonical / projection / audit 三层 |
| 入口 | Chat + AIOps | 同左 + Skill | 统一 Chat + Intent |
| 回放 | step/tool | + run + self_eval | Timeline + 独立 reasoning |
| 主要负债 | 幻觉 | 编排税/Token | 运行策略与治理(ISS-015) |
| 业界近似 | 初级 Tool Agent | 重型 multi-agent 流水线 | ReAct + 强 Guardrail/Harness |
```mermaid
flowchart LR
P1["Phase1<br/>P→E→V"] --> P2["Phase2<br/>+GK +Composer"]
P2 --> P3["Phase3<br/>Agent + Harness"]
P1 -.- L1["能跑"]
P2 -.- L2["能验"]
P3 -.- L3["能控"]
```
**一图串三阶段(面试收口用)**
```mermaid
flowchart TB
subgraph P1["Phase1 闭环"]
direction LR
A1["Plan"] --> A2["Act"] --> A3["Verify"]
end
subgraph P2["Phase2 正确性"]
direction LR
B1["Plan"] --> B2["Act"] --> B3["Gate 0LLM"] --> B4["Verify"] --> B5["Compose"]
end
subgraph P3["Phase3 运行时"]
direction LR
C1["单 Agent ReAct"] --> C2["Evidence"] --> C3["Semantic"] --> C4["Release"]
end
P1 -->|"引用不可核验"| P2
P2 -->|"外层重复 ReAct"| P3
```
---
## 11. 可复用的原则清单(收口)
1. **先威胁模型,后角色图**
2. **能确定性检查的,不要交给模型装公正**
3. **模型可见数据必须有界(ACI)**
4. **完整事实、推理视图、长期审计三者分离**
5. **公开通道与内部草稿切断(Release)**
6. **Run 级身份贯穿:禁止“最新一条”**
7. **显式 Tool 决策优于隐式中间件魔法**(在可审计领域)
8. **多 Agent 的合法理由是权限/知识/失败域,不是给 ReAct 步骤起名**
9. **演进要有触发条件与评测,反自动炫技**
10. **重构保留语义,迁移装载位置,不把历史能力一笔勾销**
---
## 12. 建议复习路径(3 天)
### Day 1 巩固
- 读现行 4 篇架构:`current-mvp-architecture` / `agent-orchestration` / `harness-quality-gates` / `session-trace-lifecycle`
- 用第 8 节模板重写:ToolBoundary、EvidenceGuard、Release
- **默画 §15 图 A + 图 D**(当前主链、数据三层)
- 输出:一页「当前系统边界图」(手绘即可)
### Day 2 演进与辩护
- 读 `executor-evidence-pipeline-refactor` + ISS-014 摘要
- 练习:为 Phase 2 辩护 2 分钟,再为 Phase 3 重构辩护 2 分钟
- **默画 §15 图 B + 图 C**(五段流水线、职责迁移)
- 输出:10 行「旧角色 → 新组件」映射表(不看文档默写)
### Day 3 业界与迁移
- 用第 6.5 节表格,挑 2 个外部架构(如 LangGraph multi-agent、纯 ReAct SaaS 助手)做优缺点
- **默画 §15 图 E + 图 F**,并按 §15.7 组合练 3 个开场
- 做第 9.4 两道现场设计题
- 读 ISS-015:准备一段“未完成但可控”的诚实收尾
---
## 13. 附录:关键文件索引
| 主题 | 路径 |
|---|---|
| 当前架构入口 | `mvp/architecture/README.md` |
| 单 Agent 重构总因 | `mvp/issues/archived/ISS-014-single-react-agent-harness-aci-ptk-refactor.md` |
| 运行质量后续 | `mvp/issues/active/ISS-015-diagnosis-runtime-quality-and-reasoning-audit.md` |
| 旧五段编排 | `mvp/architecture/archive/2026-07-22-legacy/agent-orchestration.md` |
| 旧证据契约 | `mvp/architecture/archive/2026-07-22-legacy/executor-evidence-pipeline-refactor.md` |
| 旧演进路线 | `mvp/architecture/archive/2026-07-22-legacy/evolution-roadmap.md` |
| 早期愿景 | `mvp/architecture/archive/2026-07-05-legacy/agent-architecture.md` |
| 早期 MVP | `mvp/architecture/archive/2026-07-05-legacy/agent-architecture-mvp.md` |
---
## 14. 最后一道自测(不看文档回答)
1. 用一句话说清:Phase 2 与 Phase 3 各自解决的**不同类问题**是什么?
2. 为什么说 Gatekeeper 和 EvidenceGuard “神似”但“层不同”?
3. 若去掉 SemanticGuard,只留 EvidenceGuard,系统会怎样坏?
4. 若去掉 EvidenceGuard,只留 SemanticGuard,系统会怎样坏?
5. 举一个**不该**再拆多 Agent 的场景,和一个**该**拆的场景。
6. 你的系统与“LangChain + 向量库问答机器人”的本质三点差异?
7. ISS-015 若只准做一件事,你先做哪个?为什么?(停止策略 / Repair / Reasoning 治理 / Fallback 信息量)
能流畅答完 1–6,面试架构部分通常已经稳;第 7 题用来展示判断力而非背诵。
**加试:默画**
8. 60 秒画出「当前 Diagnosis 主链」(入口 → Agent → 三道门 → SSE)。
9. 90 秒画出「Phase2 五段」并标注哪一段是 0 LLM。
10. 60 秒画出「数据三层」并标出 Agent 能看见哪一层。
---
## 15. 白板默画清单(面试实战)
> 目标:不是画得好看,而是**边画边讲决策**。
> 建议每天抽 1 张限时默画,画完对照本节「必须出现的框」。
### 15.1 图 A · 60 秒:当前主链(必考)
```text
Client
│ POST /api/chat (SSE)
▼
UseCase ── Intent ──┬─ SYSTEM
├─ KNOWLEDGE
└─ DIAGNOSIS
│
▼
Diagnosis Agent ◄── projection
│ tool_call_id
▼
ToolBoundary ──► Redis canonical
│
▼
DiagnosisDraft
│
┌────────────┼────────────┐
▼ ▼ ▼
EvidenceGuard SemanticGuard Release
(0 LLM) (隔离LLM) (发布权)
│ │ │
└────────────┴────► SSE content / fallback
```
**边画边说的三句**
1. 唯一入口,意图分流,诊断才进 Agent。
2. Agent 只见投影,raw 只在 Harness。
3. Draft 默认不公开,Release 点头才出门。
**必须出现的框**:Intent、Agent、ToolBoundary/Redis、Evidence、Semantic、Release、SSE。
### 15.2 图 B · 90 秒:Phase2 五段 + 证据外键
```text
Planner → Executor ⇄ Tools
│
▼ executor_evidence_v2
Gatekeeper (0 LLM)
│ check id / path / excerpt
▼
Verifier (LLM)
▼
Composer → Answer
```
证据外键小图:
```text
claim ──binding──► invocation_id
├──► raw_path
└──► excerpt ⊆ raw_response
```
**边画边说**
> 这段解决的是正确性:先代码验引用,再模型验推导,最后控表达。
### 15.3 图 C · 60 秒:职责迁移(回答“是不是退步”)
```text
Planner ─────────────► Agent 内部
Executor loop ────────► Agent + ToolBoundary
Gatekeeper ───────────► EvidenceGuard
Verifier ─────────────► SemanticGuard
Composer ─────────────► Draft + Release
```
**金句**:角色变少,强制约束变多;语义保留,装载位置变了。
### 15.4 图 D · 60 秒:数据三层(ACI)
```text
Tool 执行
│
├──────────────► MySQL metadata(长期、无 raw)
│
▼
Redis canonical(完整 raw,短 TTL,Harness only)
│
▼ projector
agent_result 投影 ──────────► 只回 Agent
│
└─────────────────────► EvidenceGuard 也可读 canonical
```
**必须标**:Agent 禁止直连 Redis / 禁止见 raw。
### 15.5 图 E · 45 秒:业界定位两点对比
```text
纯 ReAct: Model ↔ Tools → 文本直接出门
本项目: Model ↔ Boundary → Draft
→ Guard → Guard → Release → 出门
+ budget/cancel/timeline
```
### 15.6 图 F · 45 秒:演进箭头(开场用)
```text
愿景 Multi-Agent
→ MVP P/E/V(能跑)
→ +Gate/Composer(能验)
→ 单 Agent + Harness(能控)
→ ISS-015(治运行)
```
### 15.7 现场组合策略
| 面试官问题类型 | 先画哪张 | 再补哪张 |
|---|---|---|
| 介绍项目 | F 演进 | A 当前主链 |
| 如何防幻觉 | B 或 A 的 Guard | D 数据三层 |
| 为什么重构 | C 迁移 | B→A 对比 |
| 和 LangGraph/多 Agent 比 | E 定位 | C 合法拆分动机 |
| 数据怎么存 / 怎么审计 | D 三层 | Trace session/run 树 |
### 15.8 默画评分(自评)
| 分数 | 标准 |
|---|---|
| 5 | 限时内画完 + 边讲决策 + 主动说取舍 |
| 4 | 画完且框齐全,讲解连贯 |
| 3 | 框基本全,但讲成组件清单 |
| 2 | 漏 Release / 数据分层 / 0LLM 门禁 |
| 1 | 只画了 Model↔Tools |
**红线(扣分项)**
- 把 SemanticGuard 画成带 Tool 的第二 Agent
- 让 raw_response 直接回到 Agent
- Draft 不经 Release 就连到用户
- 说“我们简化成单 Agent 所以不做验证了”