第九节 — 每个子系统的内部组件
这一节回答:Core Runtime 内部分哪些子系统?每个子系统的职责、接口、关键组件是什么?
6 个子系统概览
Core Runtime 内部分 6 个子系统:
| 子系统 | 核心职责 |
|---|---|
| Input/Output Pipeline | 多模态输入归一化(文本 / 文件 / URL / 语音 / 表单)+ 输出投影(按入口呈现)+ 边界保护 hook |
| Task Orchestration | LLM Function Calling 驱动的意图识别 + 任务路由 + TaskGroup 并发编排 + 事后任务类型标签 |
| Evidence + Synthesis | 工具调用执行 + 证据归一化 + 综合判断(产出认知要素)+ 高风险任务 self-consistency |
| State Management | Session / Watchlist / Judgment Record / Profile / 审计 trail + 候选到已确认两步写入 + 主动信号触发 |
| Capability Registry | Tool / Skill 注册 + 任务类型本体(事后审计用)+ 执行类工具注册拒收 |
| Provider Adapter | LLM / 数据 Provider 统一适配 + 用户配置 Provider 池 + 4 层降级(L1-L4)+ 凭证安全 |
子系统间通过明确的接口契约协作,详见各子系统下方的接口表。
9.1 Input/Output Pipeline 子系统
组件图
这张图表达什么:输入侧把多种模态归一化为统一表示后过边界保护 hook,再进入 Task Orchestration;输出侧从综合层接收结构化结果过出口边界保护后,按入口投影为不同呈现格式。
这张图特意不表达什么:Task Orchestration / Synthesis 等下游子系统的内部组件(在下面各小节展开)。
职责
把所有用户输入归一化为「主文本 + 结构化上下文片段 + 元数据」供下游使用;把综合结果投影为各入口需要的呈现格式。
输入端的边界保护 hook 是战略不变量的工程承接点:凭证类与执行类输入在这里被规则识别 + 拦截,不进入 Task Orchestration / LLM 调用链。输出端的边界保护 hook 扫描凭证样式内容(防大模型 hallucinate 出地址 / 密钥串),不进入审计或状态。
关键接口
| 接口 | 输入 | 输出 |
|---|---|---|
preprocess(raw_input) | 任意模态原始输入 + 入口元数据 | 归一化输入对象(主文本 + 结构化上下文 + 元数据) |
boundary_check_input(normalized) | 归一化输入 | 通过 / 拦截(含安全回应内容) |
project(result, entry_type) | 综合结果 + 入口类型 | 该入口的投影对象 |
boundary_check_output(result) | 综合结果 | 扫描后的结果(凭证样式内容标记 / 脱敏) |
失败模式与降级
| 失败 | 降级 |
|---|---|
| 文件解析失败 | 标记"文件未解析",给用户安全回应 + 重试建议 |
| URL 不可访问 / 内容类型未识别 | 同上 |
| ASR 失败 | 提示"语音未转写",引导用户改文本输入 |
| 边界保护识别凭证类输入 | 返回安全回应(不进入认知任务链)+ 提示"凭证类信息不要发给 FinBayes" |
| 边界保护识别执行类请求 | 转为认知任务(如"是否要 X 行动 → 走交易准备类任务认知材料") |
验收信号
- 归一化输出在不同输入模态下结构一致
- 边界保护拦截测试覆盖:私钥 / 助记词 / 交易所 API key / 银行账户号 / 信用卡号 / 自动交易请求 / 直接下单请求等 negative cases
- 输出投影在 5 个入口(CLI / TUI / Web / MCP / Channel)共享同一 StructuredCognitionResult,投影差异只在呈现层
9.2 Task Orchestration 子系统
组件图
这张图表达什么:输入归一化后,加载用户上下文与工具池 schema,喂给 LLM Function Calling 做意图识别与工具选择。LLM 决定调单工具 / 多工具组合 / clarify 工具中的某一种。任务执行完成后,事后回填任务类型标签到审计 trail。
这张图特意不表达什么:意图本体作为前置分类器(FinBayes 不采用此模式,详见架构决策记录 ADR-004)。
职责
驱动用户输入到结构化任务的转换。不预设意图分类管道——意图识别由 LLM Function Calling 完成,FinBayes 提供工具池 schema、用户上下文、对话状态作为输入。任务类型本体在这里作为事后标签用于审计,不作前置路由。
复合任务(一个用户输入命中多个任务)通过 TaskGroup 显式拆解为单工具任务串行 / 并发调用——这是 FinBayes 在意图层的工程责任,不依赖 LLM 原生处理多轮复合任务(业界研究确认 LLM 在多轮工具调用上不稳定)。
关键接口
| 接口 | 输入 | 输出 |
|---|---|---|
orchestrate(normalized_input) | 归一化输入 | TaskGroup(含一个或多个任务)或 ClarifyResponse |
dispatch_task_group(group) | TaskGroup 对象 | 部分结果流 + 最终归并结果 |
tag_task_type(task, llm_call) | 任务 + LLM 调用结果 | 任务类型标签(来自任务类型本体)写入审计 trail |
内部组件简述
- Context Loader:从 State Management 读取用户画像 / 对话状态 / Watchlist / 已声明持仓
- Tool Pool Assembler:从 Capability Registry 取工具 schemas,按用户上下文过滤可用工具
- LLM Function Caller:经 Provider Adapter 发起 Function Calling,处理 confidence / 重试
- TaskGroup Manager:多任务并发执行 / 失败隔离 / 部分结果流式输出 / 最终归并
- Clarify Handler:clarify 工具调用的特殊处理(强制串行阻塞,澄清后回到 orchestrate 起点)
- Task Type Labeler:事后从 LLM 工具调用反推任务类型标签(用于合规审计)
失败模式与降级
| 失败 | 降级 |
|---|---|
| LLM 不可用 | 由 Provider Adapter 触发 L2 / L3 / L4 降级(详见 Provider Adapter 子系统) |
| LLM 给低 confidence | 自动调 clarify 工具,回到 orchestrate 起点 |
| TaskGroup 某子任务失败 | 该子任务降级输出 + 不阻塞其他子任务,最终归并时明示降级 |
| 高风险任务(交易准备类 / 决策辅助类) | 强制 self-consistency N≥3 采样投票(由 Evidence + Synthesis 实施) |
验收信号
- 同一用户输入在重复运行中识别为相同任务组合(除非走 LLM 路径产生合理变化)
- 复合任务(如复盘 + 交易准备)显式拆解为多工具调用,不靠 LLM 单次输出
- 事后任务类型标签覆盖所有完成的 task,进入审计 trail
9.3 Evidence + Synthesis 子系统
组件图
这张图表达什么:从任务到结构化认知结果的转换。证据层生成 EvidencePlan、执行工具调用、归一化为 EvidencePacket DAG;综合层产出认知要素。高风险任务走 self-consistency。
职责
证据层:按任务声明的证据面调工具与数据源,归一化为 EvidencePacket(含 source / freshness / confidence / status / degraded_reason)。
综合层:基于证据 DAG 产出认知要素(结论 / 倾向 / 依据 / 多视角 / 反方证据 / 成立条件 / 失效条件 / 不确定性 / 信息缺口 / 来源时间戳 / 可继续追问项 / 历史判断链接)。画像信号只调整表达密度与术语深度,不进入证据筛选——反方证据 / 关键风险 / 失效条件按事实空间生成,不被裁剪(战略不变量)。
高风险任务(交易准备 / 交易决策辅助)触发 self-consistency:N≥3 次综合采样 + 一致性投票(业界研究确认 LLM verbalized confidence 不可信,自一致性是替代方案)。
关键接口
| 接口 | 输入 | 输出 |
|---|---|---|
plan_evidence(task) | 任务对象 | EvidencePlan(DAG 节点 / 依赖 / 预算 / fallback) |
execute_evidence(plan) | EvidencePlan | EvidencePacket DAG |
synthesize(task, evidence_dag, context) | 任务 / 证据 / 用户上下文 | StructuredCognitionResult |
synthesize_with_consistency(task, evidence_dag, context, n) | 同上 + 采样数 | 经一致性投票的 StructuredCognitionResult |
失败模式与降级
| 失败 | 降级 |
|---|---|
| 单证据节点失败 | 标记 degraded_reason,不阻塞依赖它的其他证据节点之外的任务 |
| 必需证据全部失败 | 综合层产出 degraded snapshot(明示信息缺口,不强行给方向性结论) |
| LLM 综合失败 | 走 Provider Adapter 降级链;若全部 LLM 不可用走 L3 缓存 / 规则路径 |
| Self-consistency N 次采样结果分歧大 | 输出"判断不收敛"信息 + 各分歧的依据,让用户判断 |
验收信号
- 证据 DAG 可序列化为 run result / fixture / 审计记录
- 高风险任务在测试中能被识别并触发 self-consistency
- 反方证据 / 关键风险 / 失效条件 在不同用户画像下的呈现一致(不被画像裁剪)
- 没有可靠数据时给信息缺口而非凑数
9.4 State Management 子系统
组件图
这张图表达什么:长期状态(Watchlist / Judgment Record / 动态画像)通过 candidate → confirmed 两步写入;用户对画像保有完整控制权(查看 / 修改 / 清空);动态画像也来自后台静默观察。审计 trail 独立记录所有任务执行。主动信号机制:已确认的 Judgment Record 的成立/失效条件被市场变化触及时自动触发新一轮认知。
职责
承载 FinBayes 持续认知的所有长期状态资产;保证战略不变量在状态层的硬约束:
- 凭证类信息一律不进入任何长期状态(凭证不变量)
- 画像由用户保有查看 / 修改 / 清空的完整控制权(用户主权不变量)
- 画像不进入证据筛选(与综合层协作约束,画像信号只在 Context Loader 注入综合层时调表达密度)
- 判断与状态写入需用户主动确认(candidate → confirmed 两步)
关键接口
| 接口 | 输入 | 输出 |
|---|---|---|
create_candidate(type, payload) | candidate 类型 + 内容 | StateCandidate(待用户确认) |
confirm_candidate(id, edit?) | candidate id + 可选编辑 | 已确认状态对象 |
reject_candidate(id) | candidate id | 标记拒绝 |
read_session_context(sess_id) | session id | Session + 当前 Context |
compact_session(sess_id) | session id | Context Snapshot(保留判断条件 / 信息缺口 / 来源时间点) |
view_profile(user_id) / modify_profile(...) / clear_profile(user_id) | 用户主权动作 | 画像查看 / 修改 / 清空结果(清空时给出"协作上下文已重置"明示) |
trigger_active_signal(market_change) | 市场变化事件 | 触及的 Judgment Record 列表 + 主动信号材料 |
append_audit(task, calls, ...) | 任务执行细节 | 审计记录 |
内部组件简述
- Candidate Buffer:未确认状态的暂存
- Confirmed Store:已确认的 Watchlist / Judgment Record / Profile(落地 SQLite)
- Session Manager:Session 创建 / 切换 / 归档 / 删除生命周期
- Context Compactor:长会话上下文压缩(保留金融语义锚点)
- Profile Manager:用户画像的静默构建 + 用户主权动作
- Active Signal Trigger:定期 / 事件驱动检查 Judgment Record 的成立/失效条件
- Audit Logger:所有任务 / Provider 调用 / 降级 的审计记录
失败模式与降级
| 失败 | 降级 |
|---|---|
| State Store(SQLite)不可用 | runtime 进入只读模式 + 提示用户存储问题 |
| Context Compactor 失败 | 长会话切断,新 Session 开始 + 引用历史 Judgment Record |
| 主动信号触发引擎宕机 | 不阻塞主动 query;主动信号补发不实时 |
| 用户清空画像后系统仍有缓存 | 立即同步清空 + 显式提示"协作上下文已重置" |
验收信号
- 凭证类信息 grep 测试:状态对象 / 审计 trail 中 0 命中
- candidate vs confirmed tests 覆盖确认 / 编辑 / 拒绝 / 清空
- 用户画像清空后所有引用都不可读
- 主动信号触发的复盘建议能链回对应 Judgment Record
9.5 Capability Registry 子系统
组件图
这张图表达什么:3 个注册表(工具池 / 技能 / 任务类型本体)+ 执行类工具的硬性拒收规则 + 能力匹配过滤。任务类型本体仅供事后审计标签使用,不参与前置路由。
职责
集中管理 FinBayes 内部的可调用能力。执行类工具的注册请求一律拒收——这是战略边界"FinBayes 不直接下单, 也不持有账户凭证"在能力注册层的硬性承接,不允许通过任何方式(包括 plugin / 用户自定义工具 / 等)绕过。
任务类型本体由产品定义文档定义(解释 / 分析 / 比较 / 复盘 / 风险识别 / 交易准备 / 交易决策辅助),第一阶段实现为有序枚举 + 元数据(描述 / 触发关键词 / 涉及证据面 / 等)。未来可扩展或细分,按注册表查找而非硬编码 if-else。
关键接口
| 接口 | 输入 | 输出 |
|---|---|---|
register_tool(tool_schema) | 工具 schema | 注册成功或拒收(含拒收理由) |
assemble_tool_pool(user_ctx, provider_caps) | 用户上下文 + Provider 能力 | 该次任务可用的工具 schema 列表 |
lookup_task_type(task_id) | task id | 任务类型本体节点(用于审计) |
关键约束
- 执行类工具拒收清单(注册接口必须拒收的工具特征):
- 任何含"下单 / order / trade / buy / sell"语义
- 任何含账户操作("transfer / withdraw / deposit / sign / approve")
- 任何含自动化触发("schedule / cron / auto")
- 任何含 shell / 系统命令执行
- 任务类型本体的演化策略:扩展任务类型需先在产品定义文档授权,再在工具池增加对应工具 schema + 在任务类型本体增加节点
失败模式
| 失败 | 处理 |
|---|---|
| 注册执行类工具的尝试 | 拒收 + 记录到审计 trail(含尝试者 / 工具内容 / 时间) |
| 任务类型本体内节点缺失 | runtime 失败式拒绝,强制先扩本体再继续(防止任务"漂"到未知类型) |
| Tool Pool 为空(如用户配置过严过滤) | 返回受限工具池 + 提示用户检查配置 |
验收信号
- negative cases 覆盖各类执行工具注册尝试,全部拒收
- 任务类型本体与产品定义文档清单完全一致(grep 比对)
- 工具池组装在不同 Provider(有的不支持 Function Calling)下能力匹配正确
9.6 Provider Adapter 子系统
组件图
这张图表达什么:Provider 选择走 4 层降级(L1 用户配置 → L1' 系统默认 → L2 本地嵌入 → L3 缓存+规则 → L4 受限菜单),每层有可用性 + 能力匹配检查。统一适配层屏蔽不同 Provider 的 API 差异。凭证由 Credential Store 提供(不与代码 / 配置混存)。
职责
抽象 LLM / 数据 Provider 接入,让 Task Orchestration / Evidence + Synthesis 通过统一接口调用,下层 Provider 可替换。
用户自配置作为 first-class 场景:用户可在本地配置喜欢的 Provider(云端 Claude / GPT-4 / DeepSeek API;本地 Ollama / vLLM / LM Studio;自定义 OpenAI-compatible endpoint)+ 偏好顺序。系统默认 routing 是兜底而非强制。
4 层降级保障 LLM 不可用时仍可用:业界默认"LLM 不可用 = 服务不可用",FinBayes 本地优先定位要求更高可用性,故设计 L1-L4 降级。
关键接口
| 接口 | 输入 | 输出 |
|---|---|---|
select_provider(task_type, user_ctx, capability_needed) | 任务类型 + 用户上下文 + 能力要求(function calling / vision / 等) | 选定 Provider 实例 + 当前降级层级 |
call_llm(messages, tools, options) | OpenAI-compatible 消息格式 | 响应(function call / 文本 / streaming) |
register_provider(provider_spec) | Provider 配置 | 加入用户 Provider 池 |
check_readiness() | — | 所有 Provider 的实时可用性 + 能力 |
get_audit(task_id) | 任务 id | 该任务用了哪个 Provider / 成本 / 是否走 fallback |
关键内部组件
- Provider Registry:内置 Provider 列表(OpenAI / Anthropic / DeepSeek / Qwen / Ollama / vLLM / LM Studio / Hugging Face TGI / 等)+ 用户自定义 Provider 注册位
- Routing Policy:两层路由(系统默认 + 用户覆盖),按任务 / 区域 / 成本 / 用户偏好选择
- Capability Matcher:检查 Provider 支持的能力(Function Calling / vision / streaming / 上下文长度)vs 任务需要
- Readiness Prober:runtime 启动 + 周期性 ping 各 Provider 端点
- Unified API Adapter:统一 OpenAI-compatible 接口(用 LiteLLM 或自实现),屏蔽各家 SDK 差异
- L2 Local LLM Manager:管理本地嵌入式 LLM(Ollama 集成),探测本地模型可用性
- L3 Cache + Rule Engine:精确缓存(Redis SHA256)+ 语义缓存(Redis Vector + bge embedding)+ 规则匹配(关键词词典 + BM25 兜底检索,不引入 ML 训练管道 — 本地优先定位约束)
- L4 Restricted Menu Provider:所有 LLM 不可用时的菜单驱动兜底
- Cost Tracker:每次调用的 token 数 / 价格 / 累计成本(用于用户审计)
失败模式与降级(4 层全展开)
| 层 | 触发条件 | 提供能力 | 牺牲 |
|---|---|---|---|
| L1 用户 Provider 池 | 用户配置的至少一个 Provider 可用 + 用户偏好顺序 | 完整能力 | 无 |
| L1' 系统默认 fallback | 用户没配置或配置全部不可用,回到系统默认(用户允许时) | 完整能力但可能要求用户补配置 | 用户偏好被旁路 |
| L2 本地嵌入式 LLM | 所有云端 / API 不可用,用户已部署本地小模型 | 接近 L1,质量稍低 | 部分高难度任务质量下降 |
| L3 缓存 + 规则 | 所有 LLM 都不可用 | 仅预设常见模式(行情 / 概念解释 / Watchlist 操作等) | 失去自然语言鲁棒性 + 复杂任务不可用 |
| L4 受限菜单 UI | L1-L3 都失败 | 用户从菜单选任务 + 受限查询 | 完全失去自然语言低门槛,仅"读功能" |
关键约束
- 同一 Tool Registry 跨所有层:LLM 是可替换变量,工具池不变
- L1 → L2 自动切换:runtime 探测云端可用性,无缝降级
- L2 → L3 半自动:本地 LLM 不可用时系统显示"已进入受限模式"
- L3 / L4 用户明示:用户必须看到"当前是受限模式,需要 X 才能恢复完整能力"
- 本地嵌入式 LLM 是可选安装:首次部署时引导,不强制
验收信号
- 用户在不同 region / 任务下能配置不同 Provider 偏好,runtime 按偏好选择
- Provider 凭证仅从 Credential Store 读取,不进入审计 / 日志 / 状态
- L1 主 Provider 失败时自动 fallback 到下一个用户偏好(无需用户介入)
- 所有 LLM 都不可用时,L3 缓存命中的查询(如"什么是 PE")仍能返回;L4 菜单可见
子系统间的数据流总览
| 流向 | 数据 |
|---|---|
| Input/Output Pipeline → Task Orchestration | 归一化输入(边界保护后) |
| Task Orchestration → Capability Registry | 工具池请求 + 用户上下文 |
| Task Orchestration → Provider Adapter | LLM Function Calling 调用 |
| Task Orchestration → Evidence + Synthesis | 选定任务 + 上下文 |
| Evidence + Synthesis → Provider Adapter | 工具执行 + 综合层 LLM 调用 |
| Evidence + Synthesis → State Management | 审计 trail / 候选写入 |
| Task Orchestration → State Management | 任务类型标签 / 审计记录 |
| State Management → Task Orchestration | 用户画像 / 对话状态 / Watchlist |
| Evidence + Synthesis → Input/Output Pipeline | StructuredCognitionResult |
| State Management → Task Orchestration | 主动信号触发的新任务 |
详细的时序流转(同步问答 / TaskGroup 并发 / Provider 降级 / 等场景)在关键场景的流转图章节展开。