# PAC 设计哲学 — 跟 LLM 范式的同构对照

> PAC 不是常规 CRUD 系统,而是一个**系统级 autoregressive 推断引擎** —
> 把患者世界看作流式 token 序列,事实视为上下文窗口,
> 召回计划是"下一个 token"。

---

## 一张图

```mermaid
flowchart LR

%% ===== LLM 范式(上方,作为类比) =====
subgraph LLM["🧠 LLM Autoregressive 范式(类比)"]
  direction LR
  T1["Tokens<br/>(input stream)"] --> CTX1["KV Cache<br/>(累积上下文)"]
  CTX1 --> AT["Attention<br/>规则 + 权重"]
  AT --> NXT["Next Token<br/>(sampling + fallback)"]
  NXT -.->|"feeds back"| CTX1
end

%% ===== PAC 范式(下方) =====
subgraph PAC["🏥 PAC 系统级 Autoregressive"]
  direction LR

  subgraph Input["INPUT — 原子事件流"]
    direction TB
    TXN["patient_transactions<br/>━━━━━━━━━━━━━━<br/>= 'tokens'<br/>append-only 不可变<br/>source_event_id 幂等<br/>event_seq 单调序列号"]
  end

  subgraph Context["CONTEXT — 状态累积 + 压缩"]
    direction TB
    FACT["patient_facts<br/>━━━━━━━━━━━━━<br/>= 'context window'<br/>版本流 active 视图<br/>subject_id × version<br/>canonical 标准化"]
    PERSONA["persona<br/>━━━━━━━━━━━━<br/>= 'hidden state'<br/>fact 的特征摘要<br/>eventWatermark 水位<br/>13 个 feature key"]
    FACT -->|"提取 features"| PERSONA
  end

  subgraph Output["OUTPUT — 决策生成"]
    direction TB
    PLAN["followup_plans<br/>━━━━━━━━━━━━<br/>= 'next token prediction'<br/>规则打分 + scenario 选择<br/>版本化推断,可解释"]
    ASSETS["scripts / summaries<br/>━━━━━━━━━━━━━<br/>= '展开生成内容'<br/>LLM 本职(话术 / 叙述)<br/>失败降级 template"]
    EXEC["plan_executions<br/>━━━━━━━━━━━━━<br/>= '采样结果'<br/>客服执行回写"]
    PLAN --> ASSETS
    PLAN --> EXEC
  end

  TXN -->|"parser<br/>(规则化解析)"| FACT
  PERSONA -.->|"可选增强"| PLAN
  FACT -->|"主输入"| PLAN
  EXEC -.->|"反馈状态机<br/><b>不污染输入</b>"| PLAN
end

%% ===== 类比连线 =====
T1 -.->|"同构"| TXN
CTX1 -.->|"同构"| FACT
AT -.->|"同构"| PLAN
NXT -.->|"同构"| ASSETS

%% ===== 颜色 =====
style LLM fill:#fff8e1,stroke:#fbc02d,stroke-width:2px
style PAC fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px
style Input fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Context fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Output fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style T1 fill:#fff59d
style CTX1 fill:#fff59d
style AT fill:#fff59d
style NXT fill:#fff59d
style TXN fill:#bbdefb
style FACT fill:#ffe0b2
style PERSONA fill:#ffe0b2
style PLAN fill:#e1bee7
style ASSETS fill:#e1bee7
style EXEC fill:#e1bee7
```

---

## 同构对照表

| LLM 概念 | PAC 落地 | 共同的设计哲学 |
|---|---|---|
| **Token**(最小语义单元) | `patient_transactions`(原子事件) | 细粒度切分,信息无损,可重放 |
| **KV Cache / Context Window** | `patient_facts`(版本流 active 视图) | 累积有序状态,固定形态供下游消费 |
| **Hidden State**(压缩表示) | `persona` + `persona_features` | 把多 token 上下文压缩成可索引特征 |
| **Attention 机制** | Plan 引擎(scenario 规则 + 权重) | 关注哪些 fact / feature 影响输出 |
| **Next Token Sampling** | `followup_plans` 生成 | 综合上下文 → 决策输出 |
| **Beam Search / Logits** | `priorityScore` + `inclusionReason` | 候选打分排序,选 top-k |
| **Generation(展开成文)** | `plan_scripts` / `plan_summaries` | LLM 本职(自然语言),失败可降级 |
| **Autoregressive 循环** | `plan_executions` → Plan 状态机 | 输出影响下次推断,但不污染输入 |
| **Temperature / Top-p** | Plan 规则可调参数 | 确定性主路径 + 随机增强 |
| **System Prompt** | scenario 配置 | 任务定义 + 边界约束 |
| **Embedding** | `fact_content_json` canonical schema | 异构数据统一向量空间 |
| **Tokenization** | adapter parser(fieldMapping) | 宿主异构 → PAC 统一表示 |

---

## 7 条核心设计哲学

### 1️⃣ 细粒度原子化(像 token 一样切分)

**信念**:任何决策必须基于**不可再分的最小事实单元**,粒度过粗会丢失推断空间。

- transaction:每个动作单独记录(不合并 / 不汇总)
- fact:每个 subject 独立版本(不展平 / 不平均)
- 对比反例:把"一周的治疗"汇总成一行 — 丢失了"哪天哪个医生" 的推断维度

### 2️⃣ 不可变事件 + 版本化推断

**信念**:**事件可加不可改,推断可推不可改**。改了真理就丢了。

- transaction: append-only,错了只能补修正 transaction
- fact / persona / plan:版本流,新版 supersede 旧版,旧版保留
- 对比反例:用 update 覆盖 — 历史推断为什么这样得出,永远说不清

### 3️⃣ 单向数据流(像 forward pass)

**信念**:**输入 → 上下文 → 输出 永远单向**,反向写入污染因果链。

- facts → persona → plan 单向
- plan_execution 反馈到 Plan 状态机,**不回写 facts**
- AI 输出归 agent_invocations,**不回写 facts**
- 对比反例:LLM 把自己输出塞回 context — 立刻出现 hallucination 放大

### 4️⃣ 上下文压缩(像 hidden state)

**信念**:**raw context 不直接用于决策**,要压缩成可索引特征。

- facts = raw context window
- persona = 压缩后的 hidden state(value / risk / chain status 等 features)
- Plan 引擎读 persona feature 而不是扫所有 fact
- 对比反例:每个 scenario 各自扫全量 fact — 平方级膨胀

### 5️⃣ 证据链 + 可解释(对比 LLM 黑盒优势)

**信念**:**任何输出都能反查"为什么这么定"** — 这是 PAC 的差异化护城河。

- PersonaFeature.evidence:`{factIds, ruleIds, agentInvocationIds}`
- FollowupPlan.evidence:同上 + `personaVersion`
- PatientFact.transactionIds:衍生证据
- AgentInvocation:每次 AI 调用全留底
- 对比 LLM:输出黑盒,只能事后给"看起来合理的解释"

### 6️⃣ 规则为骨,Agent 为肉(harness 工程观)

**信念**:**主路径必须确定性,AI 是工具不是大脑**。

| 路径 | 用途 | 失败行为 |
|---|---|---|
| 规则(确定性代码) | 数值 / 决策 / 状态机 / 时间 | 不允许失败 |
| Agent(LLM 调用) | 自然语言 / 跨文本归纳 | **失败必须降级**到 template_fallback |

**所有 agent 都走 AI Gateway(透传 Dify)**,失败重试 + 退避 + 兜底链路完整。

对比反例:LLM 直接决策业务流 → 不稳定 + 不可控 + 难合规

### 7️⃣ 流式推进 + 水位幂等(像 autoregressive decoding)

**信念**:**事件驱动 + 单调水位**,不阻塞、不重复、可断点续传。

- `event_seq` BigInt:Postgres 序列单调水位
- `eventWatermark`:消费方记录"已响应到哪"
- BullMQ jobName = patient_id:同 patient 串行,跨 patient 并行
- 重算前 watermark 比对 → 已响应过的 no-op
- 对比反例:全量重算 → O(N²) 浪费 + 永远追不上事件流

---

## PAC vs 普通 SaaS 的本质区别

| 维度 | 普通 SaaS | PAC(autoregressive 范式) |
|---|---|---|
| 数据模型 | CRUD 表 | 流式 token + 累积 context |
| 状态 | 当前态 | 当前态 + 历史版本 |
| 输出 | 数据库行 | 推断结论 + 证据链 |
| 算法 | 业务规则 | 规则 + LLM agent + 兜底 |
| 演进 | 加字段 / 加表 | 加 transaction_type / fact_type / agentKind(不改 schema) |
| 故障容忍 | 重试或报错 | 降级 + 隔离 + 水位续传 |
| 合规可追溯 | 时间戳 | 证据链 + 版本 + replay |

---

## 一句话归纳

**PAC 把患者世界当成一个 LLM 的上下文 — token(事件)源源不断进来,context(事实)持续累积,
hidden state(画像)压缩成可索引特征,next-token prediction(召回计划)综合一切得出,
generated text(话术/摘要)展开成可读叙述,output 通过 autoregressive 反馈但不污染 input。**

不同的是:**PAC 全程有证据链,不是黑盒**;而且**主路径确定性,LLM 只在生成自然语言时出场**。
