BodySense Diagnosis Agent Architecture
BodySense Diagnosis 生产级 Agent 的统一心智模型,并作为 L1 终点连接 L2 Treatment 的 action/temporal/outcome 增量与 L3 Consultation 的 streaming/runtime 增量。
[!info] related notes
- 所属 MOC: bodysense-moc、agent-moc
- 后续学习: bodysense-treatment-vertical-slice、bodysense-consultation-streaming-architecture
- 相关概念:
- 易混淆概念:
- 相关资源:
BodySense Diagnosis Agent Architecture
这篇笔记是什么
这是 BodySense Diagnosis 这一阶段学习的统一组合页。
前面的原子笔记分别回答 Evidence、Policy、Replay、Domain Model 等问题;这篇只负责把它们放回同一个 production-shaped Agent 系统里,形成一张以后可以迁移到 Treatment、Assessment 和其他 Agent 产品的心智地图。
[!abstract] 一句话定义 BodySense Diagnosis 是一个以 durable BodyState 为事实输入,以 LLM 为语义推理组件,以受控 Evidence Acquisition 为信息获取机制,以 deterministic policy 为决策权限边界,以 immutable DiagnosisAnalysis / DecisionTrace 为历史事实载体,并通过 Eval / Replay / Promotion 持续演化的 longitudinal decision system。
1. 不要把 Diagnosis 等同于一个 PydanticAI Agent
狭义的 Agent 可以指:
Python / PydanticAI
→ semantic reasoning
→ structured output
→ tool calling
但生产意义上的 BodySense Diagnosis Agent 是整套系统:
BodySense Diagnosis
├─ Go Domain / Control Plane
├─ Python Semantic Reasoning Plane
├─ Evidence Acquisition Runtime
├─ LiteLLM Model Gateway
├─ SafetyEnvelope / DecisionAuthority
├─ Durable Persistence / DecisionTrace
├─ Replay / Comparison
└─ Eval / Promotion Governance
真正的可靠性来自这些层之间的 ownership,而不是某个框架本身。
2. 最重要的 Ownership Map
| 层 | 主要回答的问题 | 不应该拥有的东西 |
|---|---|---|
| Go Domain / Control Plane | 用户 durable truth 是什么?本轮 pin 哪个 revision/config?最终允许什么? | LLM semantic reasoning |
| Python / PydanticAI | 可能是什么?缺什么信息?证据语义上说明什么? | durable business IDs、最终 AUTO authority |
| Evidence Runtime | 哪个 Gap 允许怎么取证?实际调用了什么?预算剩多少? | 自由扩大 Safety policy |
| LiteLLM Gateway | 实际 provider/model/retry/fallback 怎么执行? | BodyState、Candidate、SafetyEnvelope 业务语义 |
| DecisionAuthority | 在已验证 facts 下允许什么动作? | 重新做疾病语义推理 |
| Persistence | 当时事实、配置、执行、决策如何成为历史? | 改写旧 Analysis 适应今天的新事实 |
| Eval/Governance | 新 Configuration 是否有资格上线? | 单次 runtime 临场改规则 |
可以压缩为一句:
BodySense owns Policy
PydanticAI owns semantic execution
LiteLLM owns infrastructure mechanism
3. 权力链:Proposal → Fact → Authority → Durable State
整个阶段最值得记住的不是某个类名,而是:
LLM Proposal
↓
Runtime Verification
↓
Structured Facts
↓
Domain Policy / DecisionAuthority
↓
Authorized Business Transition
↓
Durable State
LLM 可以提出:
Candidate = C6 radiculopathy
confidence = HIGH
Gap G8 = “是否存在进行性肌力下降?”
但它不能仅凭一句话把这些变成 system truth。
Runtime 才能确认:
A7 真的执行了
E21@v3 真的被返回了
budget 真的耗尽了
G8 仍然 unresolved
最终由 DecisionAuthority 决定:
critical gap unresolved
→ ABSTAIN
[!important] 三个角色
LLM = proposer / reasoner
Runtime = recorder / verifier
Policy = authority
4. 三类 Truth:不要把“模型说了”混进事实
Domain Truth
BodySense 当前接受的业务事实,例如:
BodyState R53
right_thumb_numbness = true
Execution Truth
这一轮真正发生的运行事实,例如:
EvidenceAttempt A7 executed
E21@v3 retrieved
provider fallback occurred
G8 remained unresolved
Decision Truth
在当时 facts + policy 下真正授权的业务动作:
policy-v1
→ ABSTAIN
而:
LLM: “我认为……”
属于 Reasoning Proposal,不自动属于以上任何一类 truth。
5. 一次完整 Diagnosis Run
假设:
BodyState = R52
Configuration = C12
Step 1 · Go pin 世界
Pinned BodyState R52
Pinned AgentConfiguration C12
一旦本轮开始,就不能中途偷偷切 R53 或 C13。
Step 2 · Python 做 Semantic Reasoning
Agent 提出:
Candidate Proposal
→ possible C6 radiculopathy
G1
→ external_knowledge
G2
→ user_information
→ critical
这里的 Candidate 仍是 proposal;durable ID 由 Go/Domain 持有。
Step 3 · Evidence Acquisition Runtime
G1:
external_knowledge
→ policy allows targeted retrieval
→ A1
→ E31@v4
→ admissible
→ G1 RESOLVED
G2:
user_information
→ generic RAG forbidden
→ measurement unavailable
→ G2 UNRESOLVED
这部分对应:
Step 4 · Runtime Facts
Go/Runtime 把复杂输出压成可判定 facts:
activeSafetyReview = false
newRedFlag = false
governanceVerdict = accepted
status = completed
candidateCount = 1
criticalGapCount = 1
Step 5 · SafetyEnvelope
当前 case 是否仍位于被批准的 normal AUTO 运行域?
因为:
criticalGapCount = 1
所以:
outside normal SafetyEnvelope
Step 6 · DecisionAuthority
diagnosis-decision-policy-v1
critical gap unresolved
→ ABSTAIN
即使:
confidence = HIGH / 0.98
也没有覆盖 hard policy 的 authority。
Step 7 · Apply Authorized Result
Model proposal:
Candidate C6
真正业务结果:
status = insufficient_information
candidates = []
所以:
Reasoning Result
≠
Authorized Business Result
Step 8 · Durable Persistence
生成 immutable:
DiagnosisAnalysis D210
├─ BodyState R52
├─ Configuration C12
├─ reasoning artifacts
├─ EvidenceGap / EvidenceAttempt
├─ DecisionTrace
├─ Configuration Provenance
└─ Execution Provenance
详见 bodysense-diagnosis-durable-domain-model。
6. Evidence:搜到、可用、解决 Gap 是三件事
最容易被忽略的层次:
retrieved
≠
admissible
≠
resolved
例如:
A2 retrieves E8
LLM says E8 is relevant
但 E8 source/version 不在 C12 的批准 evidence policy 中:
E8 retrieved = true
E8 admissible = false
G3 remains unresolved
E8 不能被删除,因为“曾经搜到但被拒绝”本身也是 Execution Truth,应留在 DecisionTrace 中。
7. SafetyEnvelope 与 DecisionAuthority 不要混
SafetyEnvelope
= boundary / eligibility
= 还在不在 normal AUTO 的批准区域?
DecisionAuthority
= action selection
= 超出后到底 ABSTAIN、ESCALATE、BLOCK 还是 ALLOW_DEGRADED?
因此一个 case 可以:
outside normal envelope
→ ABSTAIN
也可能:
outside normal envelope because new red flag
→ ESCALATE
8. Deterministic 到底要稳定什么
生产 Agent 不需要:
same input
→ every token identical
真正需要的是 Behavioral Contract。
Hard invariants:必须 deterministic
same policy facts
+
same policy revision
→ same authority
例如:
criticalGapCount = 1
policy-v1
→ 不得 ALLOW_NORMAL
Bounded semantic behavior:允许波动
Candidate wording
confidence HIGH / MEDIUM
ranking
retrieval result ordering
只要:
- 不编造 user fact;
- 不越 evidence/tool policy;
- 不突破 SafetyEnvelope;
- provenance / identity 正确。
Presentation:高度自由
自然语言 summary 的同义表达通常不需要一致。
[!tip] 最简心智模型 nondeterministic reasoning inside deterministic boundaries。
9. Durable Domain:历史不能被今天的新知识重写
假设:
R42
→ D100
→ G8 unresolved
→ ESCALATE
第二天:
R43
→ 获得“没有进行性肌力下降”
不能:
D100.G8 = resolved
应该:
R43
→ new Diagnosis D101
因为:
Past knowledge ≠ current knowledge
Historical truth ≠ current applicability
Candidate 与 Hypothesis
DiagnosisCandidate
= what one immutable analysis proposed
BodyStateHypothesis
= longitudinal explanatory entity that can strengthen/weaken over revisions
两者不要因为“都像一个诊断可能性”就合并生命周期。
10. DiagnosisAnalysis 的更精确公式
早期可以写:
D211 = R53 × C12
更精确是:
DiagnosisAnalysis
=
Pinned Domain Input
×
Immutable AgentConfiguration
×
Observed Execution
所以:
D211 = R53 × C12 × Exec-A
D212 = R53 × C15 × Exec-B
BodyState 相同、Configuration 不同,可以有两个 immutable Analysis。
甚至:
D220 = R53 × C15 × Exec-C
D221 = R53 × C15 × Exec-D
R/C 都相同,但实际 evidence/provider observations 不同,也可以产生不同结果。
结果不同不自动等于 Bug;先检查 Behavioral Contract。
11. Configuration Provenance 与 Execution Provenance
这次批准的是哪套行为?
model group
prompt revision
schema
tool policy
evidence policy
decision policy
Execution Provenance 回答:
这一轮实际上发生了什么?
actual model revision
provider
fallback
actual evidence IDs / versions
actual tool attempts
usage / runtime observations
因此:
Configuration = intended / approved
Execution = observed / actually happened
12. DecisionTrace:普通 Trace 不够
Observability Trace 回答:
HTTP / model / tool 调了什么?
耗时多少?
DecisionTrace 回答:
为什么最终允许/拒绝这个业务动作?
一个完整的业务因果链可以是:
BodyState R52
↓
Configuration C12
↓
Candidate proposal
↓
G2 critical unresolved
↓
EvidenceAttempt stopped
↓
Runtime Fact criticalGapCount=1
↓
Policy v1
↓
ABSTAIN
↓
Authorized candidates=[]
DecisionTrace 不需要保存模型私有 Chain-of-Thought;它保存系统可审计的输入、Evidence、规则、状态与结果。
13. Replay:三个概念要分开
Historical Replay
问:
尽量恢复 D100 当时的世界,会发生什么?
要尽量使用:
R42
C9
当时 evidence version/snapshot
当时 policy
当时 actual observations
如果原 Evidence 无法恢复,应明确标记 replay fidelity 不完整,而不是偷偷用最新版本。
Counterfactual Replay
问:
同一个历史 case 如果换 C15 会怎么样?
R42 × C15
用于配置比较、regression 和新 policy 离线验证。
Current Re-analysis
R55 × current production config
→ new DiagnosisAnalysis
这是今天的新分析,不是 replay。
14. Eval:不是只测“疾病名称猜对了吗”
一个 production Agent case 更适合定义:
Run Input
Expected Invariants
Forbidden Behaviors
Trace Expectations
Quality Rubric
例如最终疾病名猜对,但 Agent 用一般医学知识伪造了用户本人症状,依然应该 FAIL。
Evaluator 优先级:
Deterministic Rule
↓
Structured Semantic Validator
↓
LLM-as-a-Judge
能用 deterministic invariant 表达的,不要交给 Judge。
15. Configuration 是真正的 Qualification / Promotion Unit
上线资格不是:
“GPT-X 很强,所以可以上线”
而是完整 immutable bundle:
Configuration
├─ Model / logical model
├─ Prompt
├─ Schema
├─ Tool Policy
├─ Evidence Policy
├─ Governance Policy
├─ Decision Policy
└─ behavior-significant settings
任何行为相关修改都可能产生新 identity。
典型 release loop:
Offline Eval
→ Qualification
→ Non-Inferiority
→ Shadow
→ Canary
→ Promotion
→ Rollback if needed
16. LiteLLM:Mechanism,不是 BodySense Authority
LiteLLM 负责:
logical model
→ provider/model deployment
→ retry
→ fallback
→ cooldown / load balance
→ cost/latency telemetry
它不应该知道:
BodyState
EvidenceGap criticality
SafetyEnvelope
AUTO eligibility
也要区分两种 fallback:
Infrastructure fallback
→ provider A timeout → provider B
Business fallback / degradation
→ AUTO 不允许 → 走更保守的已批准路径
两者不属于同一层。
17. 四个 Loop:忘记细节时只记这四条
Loop A · Reasoning / Evidence
Reason
→ Gap
→ Acquire
→ Evidence
→ Reason
回答:还需要知道什么?
Loop B · Authority
Runtime Facts
→ SafetyEnvelope
→ DecisionPolicy
→ Authorized Action
回答:现在被允许做什么?
Loop C · Longitudinal
BodyState R1 → Analysis
BodyState R2 → New Analysis
回答:用户世界变化以后怎么办?
Loop D · Governance
Production
→ Trace / Incident
→ Replay
→ Eval
→ New Configuration
→ Qualification
→ Promotion
回答:Agent 自己怎样安全进化?
18. Failure Attribution:别再把所有问题都叫“模型错了”
Agent Failure Attribution 将故障拆成:
F1 Input / Context
F2 Semantic Reasoning
F3 Evidence Acquisition
F4 Runtime Fact
F5 DecisionAuthority
F6 Persistence
F7 Delivery / UI
排障原则:
从上游向下找第一个违反 Behavioral Contract 的 transition。
例如:
newRedFlag = true ✅
Decision = ESCALATE ✅
Authorized candidates=[] ✅
DB candidates=[] ✅
UI still shows candidate ❌
这时优先调查 read model / API / frontend delivery,而不是换模型。
19. 当前 BodySense 实现状态
Diagnosis Agent Platform 的 North-Star 重构已在 2026-08-20 完成并归档。当前实现已经包含:
- immutable AgentConfiguration + Go-owned selection;
- Pydantic Evals qualification、critical slices、paired non-inferiority;
- typed EvidenceGap / EvidenceBudget / EvidenceAttempt;
- deterministic Go DecisionAuthority / SafetyEnvelope;
- durable DecisionTrace 与 configuration/execution/evidence provenance;
- Historical / Counterfactual Replay 与 regression export;
- Shadow / stable canary / promotion / rollback;
- repository-wide LiteLLM logical-model routing;
- legacy application-owned ModelRouter/provider/fallback stack 已物理退休。
因此这套笔记描述的已经不是“未来设计草案”,而是当前项目 North-Star 架构及其背后的通用原理。
20. 最终检查清单:以后设计任何 Production Agent 都问这 13 个问题
- 什么是 durable domain truth?
- LLM 只负责提出什么?
- Runtime 必须独立验证什么?
- Tool / Evidence 的 permission boundary 是什么?
- 哪些 facts 进入 deterministic policy?
- 谁拥有最终 DecisionAuthority?
- 什么需要 immutable persistence?
- 怎样回答“为什么当时这样决定”?
- 能否 historical / counterfactual replay?
- Behavioral Contract 是什么?
- Eval 怎样证明新 configuration 有资格?
- 怎么 Shadow / Canary / Rollback?
- 出错后怎样定位第一个 contract violation?
如果这 13 个问题都有稳定答案,这个 Agent 才真正从 Demo 走向 production-shaped system。
21. 从 L1 Diagnosis 继续到 L2 / L3:只学习 Knowledge Delta
Diagnosis 已经把生产 Agent 的通用底座学完。后续课程不应该重新讲一遍 Configuration、EvidenceGap、DecisionTrace、Replay、Eval,而是直接学习新场景带来的新增不变量。
L2 · Treatment:从“解释世界”进入“改变世界”
入口:BodySense Treatment Vertical Slice。
L2 只新增五块:
1. Proposal / Acceptance / Execution Authority
2. Temporal Validity / Reauthorization
3. Mutable Treatment Aggregate + Immutable Revisions
4. Intervention → Outcome → BodyState Feedback Loop
5. Association ≠ Causation
详细页:
- Treatment 的 Proposal、Acceptance 与 Execution Authority
- Treatment 的 Temporal Validity 与 Reauthorization
- BodySense Treatment Aggregate 与 Immutable Revisions
- Intervention → Outcome → BodyState Feedback Loop
- Intervention Outcome 中的 Association vs Causation
Diagnosis 的:
Proposal → Facts → Authority → Durable History
在 Treatment 中扩展成:
Proposal
→ Generation Authority
→ proposed Revision
→ [time passes / world may change]
→ Acceptance Authority
→ accepted Revision
→ executable Intervention
→ Outcome
→ BodyState revision
→ ongoing review / reauthorization
[!important] L2 最核心的升级 对世界的判断可以成为历史;对世界采取的动作必须持续拥有“现在仍然允许”的资格。
L3 · Consultation Streaming:从“单次决策”进入“长期运行中的可恢复控制流”
入口:BodySense Consultation Streaming Architecture。
L3 复用已有的 SSE、Web Streams、TypeScript、Reducer、Context、TanStack Query 基础,只深挖四个系统级增量:
- BodySense StreamEvent Trust Boundary
- BodySense Active Turn State Machine
- Durable SSE Recovery with after_seq
- Agent Interrupt / Resume Lifecycle
核心链:
Network bytes
→ unknown
→ runtime validation
→ trusted StreamEvent
→ pure ActiveTurnReducer
→ current streaming projection
网络断开后:
SSE transport lost
≠
Agent run failed
last maxSeq
→ GET durable runtime events after_seq=maxSeq
→ same handlers/reducer
→ projection catches up
遇到 ask_user:
running
→ interaction.required
→ interrupted
→ answer persisted
→ run.resumed
→ continue same run
[!warning] L3 的两个当前真实实现缺口
StreamEvent静态 union 已经存在,但 live SSE 与 durable event API 入口当前仍有as StreamEvent,真正的 runtime validation boundary 尚未闭合。- Roadmap 要求理解 cancellation,但当前 Consultation feature 尚未发现完整的 explicit user cancel-run path;
AbortController只能解释 transport cancellation,不能被误当成 durable run cancellation。
L1 → L2 → L3 的能力升级
L1 Diagnosis
How can a stochastic Agent make an auditable decision?
↓
L2 Treatment
How can an Agent propose and govern actions that remain valid over time?
↓
L3 Consultation
How can a long-running interactive Agent expose state through streaming,
survive transport failure, and pause/resume for human input?
所以后续学习不是“换业务模块重新学一次 Agent”,而是在同一个基础架构上逐层增加:
Decision Governance
→ Action Governance
→ Interactive Runtime Governance
总结
BodySense Diagnosis 最终不是“一次 LLM 调用”,而是一套拥有:
事实边界
+ 推理边界
+ 工具/证据权限边界
+ 决策权限
+ immutable 历史身份
+ replay 能力
+ qualification / promotion 治理
+ fault localization
的纵向决策系统。
它同时成为后续学习的底座:Treatment 在其上增加动作生命周期与现实反馈,Consultation 在其上增加流式投影、持久恢复和 interrupt/resume 控制流。
最值得带走的一句话仍然是:
让 nondeterministic reasoning 运行在 deterministic business boundaries 里面;当 Agent 开始采取动作或长期运行时,再继续给这些边界增加时间、执行和恢复语义。