一汽智能座舱 AI Agent(AIOS) —— 一份面向研发与分享的全应用系统架构文档
版本:当前阶段(2026-10,基于实读代码) | 形态:内部技术分享,经脱敏可对外发布 参照基线:
../AIOS_终态目标.md(终态目标设计,本文 §0 与其对齐) 配套深读:../端云双栈LLM架构设计/(端云 LLM 接入专项)
本文描述的是当前一期实读代码已经落地的架构;
AIOS_终态目标.md描述的是终态应当达到的目标。两者有偏差,下表逐条对齐,让汇报口径统一。 状态标注:✅ 已落地/⚠️ 半实现(简化/降级)/❌ 未实现(终态规划)。
| # | 维度 | 终态目标写法 | 当前一期实代码状态 | 关键证据 |
|---|---|---|---|---|
| 1 | 分层架构 | Clean 分层 + 五层技术栈 | ✅ 完全一致:domain 纯 Kotlin 契约层 / data 适配层 / presentation UI / di Koin / vehicle 跨进程契约,依赖单向朝下 | di/AppModule.kt、domain/repository/* 接口银行、data/* 实现 |
| 2 | 端云双栈 LLM | 三档路由(0.5B / 1.5B / 云端) | ⚠️ 双栈已落(云端 + 本地 Ollama),三档自动路由未编 | LlmRouter 三层优先级路由;KoogLlmFactory 建 cloud/local/npu 三 client;LLM_BACKEND 编译期开关已落地;AUTO 按 TaskClassifier 分流;运行时动态三档策略未编 |
| 3 | MCP 引擎 | 4 引擎骨架(Registry/Filter/Workflow/Policy) | ✅ 完全落地 | CapabilityRegistryImpl / RuntimeFilterChainImpl / WorkflowEngineImpl / PolicyEngineImpl + InteractiveTimeoutGuardImpl |
| 4 | MCP 传输 | 5 类 Transport(AIDL/gRPC/WS/MQTT/HTTPS) | ⚠️ 仅 AIDL 一类落地 | transport/AidlMcpTransport.kt;McpServerConfig 暂无 transport 字段;gRPC/WS/MQTT 为终态规划 |
| 5 | Planner 规划器 | GOAP + LLM Planner(Phase 2/3) | ⚠️ LLM Planner 已自研落地,GOAP 降级 FUNCTIONAL | data/planner/LlmPlannerAdapter + PlanAssessmentRouter + RoutingUseCase(规则路由,0 次额外 LLM);GOAP 走 Koog strategy 未接入,命中后降级 |
| 6 | 业务子 Agent | 9+ 域(DVR/AVM/Parking/DMS/...) | ⚠️ 仅 mcp-server-demo 1 个跨 App Server 跑通(5 demo 工具) | McpConnectionManagerImpl.configs 声明 dvr/parking/avm/dms/comfort 5 个,全部走优雅降级 |
| 7 | 运行时过滤 | 6 维 | ✅ 6 个策略类已实现(2 维生效 + 4 维 pass-through) | data/mcp/filter/ + VehicleStateFilterStrategy |
| 8 | 会话记忆 | 短期 + 长期 + 摘要 + 快照 | ✅ 短期/长期/摘要已落地,快照未启动 | RoomChatHistoryProvider / SqliteVectorStorageBackend / SummarizingPreProcessor;agents-features-snapshot 未启用 |
| 9 | RAG 向量库 | sqlite-vec + ONNX 端侧嵌入 | ✅ 自建 SQLite BLOB 后端 + 百炼云端 embedding | SqliteVectorStorageBackend(非 sqlite-vec);DashScopeEmbedder(text-embedding-v3) |
| 10 | 多模态输入 | 5+ 模态 | ⚠️ 文本 + 阿里 NUI 在线语音 | voice-input/SpeechRecognizer 联网 ASR;HMI/地图/图片/场景触发未实现 |
| 11 | 持久化存储 | Room + DataStore | ✅ SQLiteOpenHelper 取代 Room | ChatDbHelper(5 张表);KSP 离线仓库缺 → 手写 SQL,等价 |
| 12 | UI 呈现 | 场景卡片/浮层/任务页 | ⚠️ 文本流 + 工具调用卡片 + 会话列表 + 摘要卡 + HMI 确认浮层 | ChatScreen / SessionListScreen / ChatSummaryCard / PolicyConfirmationRequest |
| 13 | 车规安全 | IsolatedProcess + SELinux | ⚠️ Policy HMI 确认 + RuntimeFilter 双保险 + 120s 超时已落地;进程隔离加固未做 | PolicyEngine / VehicleStateFilterStrategy / WorkflowEngine |
对齐结论:当前架构 = Clean 分层 + 端云双栈 + MCP 四引擎 + LLM Planner + SQLite 持久化 + 车规三保险的"骨架最小可用版";与终态目标的差异集中在业务子 Agent 接入数量、5 类传输、GOAP、多模态、IsolatedProcess 加固等终态规划项——这些在 §8 列出。
"以 AIOS 为中枢的智能座舱操作系统" —— 多模态意图统一接入,端云协同推理,能力注册 + 运行时过滤 + 工作流编排 + 策略闸门,业务子 Agent 按域隔离自治,安全合规。
一汽智能座舱里跑着十几个业务 App:DVR(行车记录)、泊车、AVM(全景环视)、DMS(驾驶员监测)、空调舒适面板……它们各自独立,用户要操作得挨个进菜单。AIOS 的目标是把它们统一收口到一个自然语言入口——"帮我打开 AVM 视图并关掉空调"一句话,由 AIOS 拆意图、调对工具、回结果。
座舱场景两个硬约束:
这决定了 AIOS 不是"套个 LLM API"那么简单,而是一套端云协同 + 工具编排 + 安全约束的系统。
| 目标 | 含义 | 落地点(当前代码) |
|---|---|---|
| 端云协同 | 云端强模型为主,端侧本地模型兜底 | LlmRouter 三层路由 |
| 隐私可控 | 隐私内容强制本地,用户可一键"全程本地" | PrivacyDetector + 设置开关 |
| 安全编排 | 危险动作(泊车/录像)需 HMI 确认,行车态隐藏 | PolicyEngine + RuntimeFilterChain |
| 可扩展 | 接入新业务 App 只加一条配置 | McpServerConfig 表 |
| 离线可用 | 断网时本地模型接管聊天 | 本地 Ollama / LiteRT-NPU |
| 可观测 | 每轮调用全链路 trace,UI 实时显示 | WorkflowTrace + TraceEvent |
下图采用"终态目标"同款分层框图样式,但描述的是当前已落地的实际架构(与 §0 对齐表一致)。自顶向下:用户 → 输入 → UI → 契约层 → 适配层(五大子包)→ 装配 → 跨进程 → 外部业务 App;车规安全三件套横切工具链路。
┌──────────────────────────────────────────────────────────────────────────┐
│ 用户层 │
│ 用户(驾驶者/乘客) │
└─────────────────────────────┬────────────────────────────────────────────┘
│
┌─────────────────────────────▼────────────────────────────────────────────┐
│ 多模态输入层 │
│ 文本输入 语音输入(阿里 NUI 在线 ASR) HMI 触控(终态规划) │
│ (EditText) (voice-input/SpeechRecognizer) (Compose 事件) │
└─────────────────────────────┬────────────────────────────────────────────┘
│
┌─────────────────────────────▼────────────────────────────────────────────┐
│ presentation 层(Jetpack Compose + ViewModel) │
│ · MainActivity(Compose 壳) │
│ · ChatViewModel(唯一胶水层:14 依赖 → 1 个 StateFlow<ChatUiState>) │
│ · ChatScreen / SessionListScreen / SettingsScreen / HMI 确认浮层 │
│ · ChatEvent(sealed):UI 派发事件,编译器穷举 │
└─────────────────────────────┬────────────────────────────────────────────┘
│ 依赖倒置:只认接口
┌─────────────────────────────▼────────────────────────────────────────────┐
│ domain 层(纯 Kotlin,零框架依赖,"契约银行") │
│ · usecase/ Send/Stream/RunMcpAgent(薄用例,Dispatchers.IO 跑 agent) │
│ · repository/ 10+ 接口:ChatRepository / McpConnectionManager / │
│ PolicyEngine / WorkflowEngine / RuntimeFilterChain / │
│ CapabilityRegistry / Planner / VehicleStateProvider / ... │
│ · model/ ChatMessage / RunRecord / TraceEvent / mcp/* │
└─────────────────────────────┬────────────────────────────────────────────┘
│ 实现倒置:data 包揽"框架味"
┌─────────────────────────────▼────────────────────────────────────────────┐
│ data 层(适配层,五大子包) │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ data/llm —— 端云双栈 LLM 路由(大脑开关) │ │
│ │ LlmRouter · KoogLlmFactory · PrivacyDetector · HealthChecker · │ │
│ │ TaskClassifier · Models(模型+系统提示词单一收敛点) │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ data/mcp —— MCP 工具生态(座舱 AI 灵魂)+ 四引擎 │ │
│ │ McpConnectionManagerImpl(多连接编排) │ │
│ │ ├─ 引擎一 CapabilityRegistry(工具打平 + 动态刷新) │ │
│ │ ├─ 引擎二 RuntimeFilterChain(车况/权限双保险) │ │
│ │ ├─ 引擎三 WorkflowEngine(意图→工具→结果 四阶段 + 超时) │ │
│ │ └─ 引擎四 PolicyEngine(危险动作 HMI 确认闸门) │ │
│ │ McpAgentFactory · McpClientRepositoryImpl · AidlMcpTransport │ │
│ │ filter/VehicleStateFilterStrategy · InteractiveTimeoutGuard │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ data/planner —— 规划器(多步指令) │ │
│ │ LlmPlannerAdapter(自研, 绕开 Koog Planner SDK) · PlanAssessmentRouter│ │
│ │ RoutingUseCase(规则路由: FUNCTIONAL/LLM_PLANNER/GOAP) · SimpleStep │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ data/chat —— 持久化与长期记忆(LTM / RAG) │ │
│ │ ChatDbHelper(SQLiteOpenHelper, 5 张表) · RoomChatHistoryProvider │ │
│ │ SummarizingPreProcessor · SqliteVectorStorageBackend(1024维 BLOB) │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ data/vehicle —— 车况仓储 │ │
│ │ VehicleStateRepository(跨进程 bind :vehicle) · VehicleState(契约) │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────┬────────────────────────────────────────────┘
│ Koin 装配
┌─────────────────────────────▼────────────────────────────────────────────┐
│ di 层(Koin DI,全图缝接) │
│ AppModule.kt:LLM_BACKEND 编译期开关选 cloud/local/npu;single 生命周期 │
└─────────────────────────────┬────────────────────────────────────────────┘
│ 跨进程 AIDL Binder(<1ms)
┌─────────────────────────────▼────────────────────────────────────────────┐
│ 跨进程通信层(MCP over AIDL,当前一类 Transport) │
│ AidlMcpTransport(CLIENT/SERVER 共用,McpJson 序列化) │
└─────────────────────────────┬────────────────────────────────────────────┘
│ bind 各业务 App 的 MCP Server
┌─────────────────────────────▼────────────────────────────────────────────┐
│ 外部业务 App 层(各自独立进程) │
│ mcp-server-demo(✅ 5 工具)· com.fawcar.dvr · com.fawcar.parking · │
│ com.faw.zhuque(AVM) · com.fawcar.dmsservice · com.fawcar.system.comfortpanel│
│ (后 5 个当前未装,走优雅降级,工具集为空不 crash) │
└──────────────────────────────────────────────────────────────────────────┘
↑
VehicleStateProvider(档位/车速/驻车态)—— 被所有层订阅
┌──────────────────────────────────────────────────────────────────────────┐
│ 横切:SQLite aios_chat.db(session/chat_run/tool_call/memory_summary/ │
│ ltm_vector)· 车规安全三件套(Registry→Filter→Policy)· 全链路 Trace │
└──────────────────────────────────────────────────────────────────────────┘
配合上方架构图,每个组件/层都说明"做什么、解决什么问题"。
| # | 组件 / 层 | 模块简介(做什么) | 解决什么问题 |
|---|---|---|---|
| 1 | 用户层 | 驾驶者/乘客 | 服务的最终对象 |
| 2 | 多模态输入层 | 把文本、语音、HMI 触控统一接入(当前:文本 + 阿里 NUI 在线语音) | 用户不可能只用一种方式交互;每种模态独立采集 |
| 3 | presentation 层 | Compose UI + ChatViewModel(14 个依赖桥接成 1 个 StateFlow),所有交互建模为 ChatEvent(sealed) | 让 UI 只 collect 一个流、ViewModel 永远不碰 Context/权限,保持架构边界清晰 |
| 4 | domain 契约层 | 纯 Kotlin、零框架依赖;usecase(薄用例)+ repository(10+ 接口"银行")+ model(业务实体) | 依赖倒置核心:换 LLM/换协议/换存储只动 data,ViewModel 一行不动 |
| 5 | data/llm 子包 | 端云双栈 LLM 路由:LlmRouter 三层优先级(隐私极 > 用户偏好 > AUTO)+ 三 client 工厂 + 隐私/健康/分类器 | 解决"这次请求用哪个后端";隐私不可被误配覆盖、断网不中断 |
| 6 | data/mcp 子包 | MCP 工具生态 + 四引擎:CapabilityRegistry(工具打平) / RuntimeFilterChain(可见性) / WorkflowEngine(编排+超时) / PolicyEngine(确认闸门) + 多连接管理 + AIDL 传输 | 解决"车内独立 App 如何被 LLM 跨进程调度";安全治理三件套让 LLM 不可信也安全 |
| 7 | data/planner 子包 | 多步规划:RoutingUseCase 规则路由(0 次额外 LLM)+ LlmPlannerAdapter 自研 LLM 规划 + PlanAssessmentRouter Replan | 解决"一句话含多个意图/多步任务"的拆解;GOAP 当前降级 FUNCTIONAL |
| 8 | data/chat 子包 | 持久化与长期记忆:ChatDbHelper(SQLite 5 表)+ RoomChatHistoryProvider/SummarizingPreProcessor(短期+摘要)+ SqliteVectorStorageBackend(长期 RAG 向量) | 解决"对话不丢、跨会话有记忆、断网可降级";自建 BLOB 后端省 native 依赖 |
| 9 | data/vehicle 子包 | 车况仓储:VehicleStateRepository 跨进程 bind :vehicle 进程,VehicleState(Parcelable 契约) | 解决"各 App 各自判断车况不一致";Runtime Filter 车况维唯一真相源 |
| 10 | di 装配层 | Koin AppModule.kt:编译期 LLM_BACKEND 选后端;所有 single 生命周期 | 替换 LLM 后端只改这一处;运行时路由再在 LlmRouter 动态选 |
| 11 | 跨进程通信层 | AidlMcpTransport:MCP 的 JSON-RPC 信封过 AIDL 桥,CLIENT/SERVER 共用一个类 | 解决"AIOS 主进程 ↔ 各业务 App 进程"通信;当前仅 AIDL 一类,终态扩展 gRPC/WS/MQTT |
| 12 | 外部业务 App 层 | 各自独立进程的 MCP Server(DVR/泊车/AVM/DMS/空调 + demo);未装走优雅降级 | 解决"AIOS 不是孤岛";业务 App 动态注册工具,主 Agent 自动可见 |
| 13 | 横切:SQLite / 安全 / Trace | aios_chat.db(5 表)· 安全三件套(Registry→Filter→Policy)· WorkflowTrace 全链路事件流 | 业务/AI 数据分层;车规红线不可绕过;每轮调用可观测回溯 |
关键设计要点:
CapabilityRegistry 决定"有什么" → RuntimeFilterChain 决定"现在能用哪些" → PolicyEngine 决定"用之前要不要确认",三者共同构成车规安全不可绕过的闸门。LlmRouter 负责"选后端、跑 LLM";WorkflowEngine 负责"把 LLM 决策翻译成工具调用 + 编排 + 超时兜底"。单 Agent 串行场景无需 Planner(第 7 子包),多意图/多步才走 Planner。McpTransportFactory 模式已预留——新增 gRPC/WS/MQTT 只需加实现类,不动 Repository/Workflow/Policy。data 出现,domain 只用自研轻量数据类(如 RunRecord/TraceEvent),保证换 Agent 框架不污染业务契约。ChatViewModel 是唯一的 UI-业务胶水层。它持有十几个依赖,但对外只暴露一个 state: StateFlow<ChatUiState>。所有 UI 交互被建模成 ChatEvent(sealed,编译器穷举),UI 派发事件、ViewModel 更新状态。
ChatUiState 关键字段(一期已落地):
data class ChatUiState(
val runs: List<RunRecord>, // 完整 run 历史(USER→trace→ASSISTANT 三段)
val busy: Boolean, // 是否正在跑
val vehicle: VehicleState, // 当前车况快照
val mcpStatuses: Map<String, McpConnectionStatus>, // 各 MCP 连接状态
val capabilities: List<CapabilityEntry>, // 全部可用能力
val runtimeVisibleCapabilities: List<CapabilityEntry>,// 经 Runtime Filter 后的可见能力
val workflowTrace: WorkflowTrace?, // 最近一次工作流四阶段链路
val policyConfirm: PolicyConfirmationRequest?, // 待确认的安全操作
val currentLlmMode: LlmMode, // 云端/本地/AUTO
val privacyModeEnabled: Boolean, // "全程本地"开关
)
MainActivity 只做一件事:搭 Compose 壳,挂 ChatScreen。语音权限申请下沉到 Composable 层,ViewModel 永远不碰 Context 和权限系统——这是刻意的架构边界。
domain/ 纯 Kotlin、零框架依赖,三个子包:
model/:业务实体。ChatMessage(USER/SYSTEM/ASSISTANT 角色)、RunRecord(一次请求的 USER→trace→ASSISTANT 三段轨迹)、TraceEvent(运行进度,不进 LLM 上下文)、mcp/*(工具信息、连接状态、能力类别、运行时过滤上下文、工作流阶段等)。repository/:所有跨层接口"银行"。关键接口:| 接口 | 职责 | 实现在 data |
|---|---|---|
ChatRepository | 与某个 LLM 后端对话(send / stream) | KoogChatRepository |
McpConnectionManager | 多连接编排 + 工具聚合 + 跑 agent | McpConnectionManagerImpl |
McpClientRepository | 连单个 MCP Server(bind/list/call) | McpClientRepositoryImpl |
CapabilityRegistry | 能力注册表(引擎一) | CapabilityRegistryImpl |
RuntimeFilterChain | 运行时可见性过滤(引擎二) | RuntimeFilterChainImpl |
PolicyEngine | 危险动作 HMI 确认(引擎四) | PolicyEngineImpl |
WorkflowEngine | 链式编排 + 超时兜底(引擎三) | WorkflowEngineImpl |
Planner | 多步规划(LLM Planner / GOAP) | LlmPlannerAdapter |
VehicleStateProvider | 车况快照(档位/车速/驻车态) | VehicleStateRepository |
InteractiveTimeoutGuard | 可暂停的整体超时 | InteractiveTimeoutGuardImpl |
usecase/:薄用例。SendChatMessageUseCase / StreamChatMessageUseCase 只负责拼 SYSTEM + history + USER;RunMcpAgentUseCase 把"跑 MCP agent"薄封装一层,并在 Dispatchers.IO 跑,避免主线程挂死触发 ANR。data/llm 子包(端云双栈路由,详见 §4.1)LlmRouter / LlmRouterImpl:统一 LLMClient 抽象,三层路由。KoogLlmFactory:创建云端(DashScope)、本地(Ollama)、NPU(LiteRT)三种 client。LiteRTLLMClient:App 内进程的 LiteRT + QNN NPU 推理(D.II 阶段)。PrivacyDetector / PrivacyLevel:隐私判定。HealthChecker / BackendHealth:云端健康探测 + 30s 缓存。TaskClassifier:AUTO 模式按 query 复杂度分流。Models:模型与系统提示词的单一收敛点。data/mcp 子包(MCP 工具生态,详见 §4.2)最复杂、最能体现"座舱 AI"特色:四引擎 + 多连接管理 + 跨进程传输 + Planner 适配。
data/planner 子包(规划器,详见 §4.3)RoutingUseCase:规则判定走 FUNCTIONAL / LLM_PLANNER / GOAP(0 次额外 LLM)。LlmPlannerAdapter:自己用 LLMClient.execute() 调 LLM 生成/评估 Plan,绕开 Koog Planner SDK。PlanAssessmentRouter:Replan 循环上限 3 次,超出强制 NoPlan。SimpleStep / SimplePlanAssessment:不依赖 Koog 的轻量 Plan 数据类。data/chat 子包(持久化与记忆,详见 §4.4)ChatDbHelper:SQLiteOpenHelper(aios_chat.db,5 张表)。RoomChatHistoryProvider:把 Koog ChatMemory 历史读写落 SQLite。SummarizingPreProcessor:消息超窗口用 LLM 压成摘要。SqliteVectorStorageBackend:长期记忆向量持久化(1024 维 BLOB)。data/vehicle 子包(车况仓储)VehicleStateRepository 跨进程 bind 车况源(:vehicle 进程),通过 VehicleStateProvider.state 这个 StateFlow 把档位/车速/驻车态推给上层。VehicleState 是 Parcelable DTO 契约。
di/AppModule.kt 用纯 Kotlin DSL 把全图缝起来。替换 LLM 后端只改这一处:LLM_BACKEND 编译期变量决定注入 cloud / local / local_npu;运行时路由再在 LlmRouter 动态选。
| 类型 | 实现 | 生命周期 | 关键依赖 |
|---|---|---|---|
LLMClient(含 named cloud/local/litert) | KoogLlmFactory.create* | single | Ktor 引擎共享,杜绝每请求新建泄漏 |
LlmRouter | LlmRouterImpl | single | cloud/local/npu client + 隐私/健康/分类器 |
McpConnectionManager | McpConnectionManagerImpl | single | policy + agentFactory + planner + router |
WorkflowEngine | WorkflowEngineImpl | single | manager + runtimeFilter + vehicleProvider |
ChatRepository | KoogChatRepository | single | LlmRouter |
ChatViewModel | — | viewModel | 14 个依赖,含 LlmRouter、ChatDbHelper |
ChatDbHelper | SQLiteOpenHelper 单例 | single | applicationContext |
LongTermMemory.Config | Koog Config | single | RAG 关闭时为空 Config(无害) |
把"这次请求用哪个后端"的决策收敛到 LlmRouter.choose(),遵循三层优先级:
用户 query → PrivacyDetector{隐私极?}
├─ 命中 → 强制本地(红线,不可被用户偏好覆盖)
└─ 未命中 → LlmMode{用户偏好}
├─ LOCAL_ONLY → 本地
├─ CLOUD_ONLY → 云端
└─ AUTO → TaskClassifier{复杂度}
├─ 简单/隐私相关 → 本地
└─ 复杂 → 云端
三层优先级(从高到低):
PrivacyDetector 命中敏感内容 → 无条件本地。不可被用户偏好覆盖的"红线"。TaskClassifier 分流(简单/隐私相关走本地,复杂走云端)。各后端工程现实:
qwen3.8-flash,带 Tools。生产主力。关闭 thinking 模式(OkHttp interceptor 注入 enable_thinking=false),首字延迟从 ~3s 压到 ~1.5s。qwen2.5:1.5b-t4,跑在车机 chroot。num_thread=4(默认 = nproc 会让推理性能崩塌 30 倍)、contextLength=4096(必须对齐 Modelfile)。能力验证性质——1.5B 函数调用稳定性远不如云端,量产以云端为主、本地兜底。D.II 阶段):App 内进程推理,复用 /vendor/lib64 的 QNN 后端。受 OEM 是否烧入 QNN 后端库约束,当前"可用则优先"。韧性:30s 健康缓存 + cooldown 震荡抑制;本地连续失败计数超阈值回落云端;断网时本地模型接管聊天。
为什么用 MCP?车内 DVR/泊车/AVM/空调是各自独立 App,AIOS 不能直接调内部方法,只能跨进程调度。MCP 天然适合"LLM ↔ 工具"标准化协议,本工程进一步落地成跨 App AIDL 传输。
MCP 子系统按"四引擎"骨架组织,是数据流经主干:
McpConnectionManager(多连接编排)
├─ 引擎一:CapabilityRegistry (多连接工具打平成一份注册表)
├─ 引擎二:RuntimeFilterChain (按车况/权限过滤可见工具)
├─ 引擎三:WorkflowEngine (意图→工具→结果 四阶段 + 超时)
└─ 引擎四:PolicyEngine (危险动作 HMI 确认闸门)
引擎一 · CapabilityRegistry(能力注册表):监听 McpConnectionManager 的 tools()/statuses() 流,把"已连接" Server 的工具打平成带来源的 CapabilityEntry 列表,随 tools/list_changed 动态刷新。snapshot 是 StateFlow,UI 和 Koog 工具选择层都能订阅。
引擎二 · RuntimeFilterChain(运行时过滤,双保险之一):用 AND 语义组合多个 ToolFilterStrategy:权限维 → 车况维 → 4 个预留空槽(车型/配置/音源/网络,当前 pass-through)。核心车况维 VehicleStateFilterStrategy:
// 行车态(非驻车):隐藏全部"泊车类"工具——按能力类别判定,不是按名字前缀
if (!vs.isParked && ToolCategoryResolver.isCategory(name, PARKING)) return false
早期用 startsWith("parking_") 只能挡本地工具,跨 App 的 demo_parking_start 会漏判;改 ToolCategoryResolver(按"包含 parking/dvr/climate"解析类别)后,无论哪个 App、什么命名,泊车类一律隐藏。与服务端行车态不注册泊车工具形成双保险。
引擎三 · WorkflowEngine(链式编排 + 超时兜底):run() 把一轮请求显式建模为四阶段,套一层可暂停整体超时(默认 120s):
INTENT_PARSE(构造运行时上下文) → TOOL_SELECT(过 Runtime Filter) → TOOL_EXECUTE(Koog 决策+跨进程 MCP) → RESULT_SUMMARY(第二轮 LLM 汇总)
"可暂停"指 InteractiveTimeoutGuard:链路走到 Policy HMI 确认(用户思考)时,由 Policy 闸门 pause() 冻结预算计时,确认完 resume(),确保"工具结果 → 第二轮汇总"仍在预算内。超时返回降级话术,绝不把异常抛给 UI。
引擎四 · PolicyEngine(安全确认闸门):PolicyEngineImpl 用 CompletableDeferred + StateFlow 把"工具执行协程里的挂起等待"和"车机 HMI 弹窗"桥接。PolicyGuardedMcpTool 包在受保护工具外层:未命中白名单透传;命中(泊车类工具)则挂起等用户确认,5s 超时自动视为取消。
override fun isProtected(toolName: String): Boolean =
toolName in PROTECTED_WHITELIST ||
ToolCategoryResolver.resolve(toolName) == ToolCategory.PARKING
多连接管理(bind / 降级 / 重连 / 冲突裁决):McpConnectionManagerImpl 持有多个 McpClientRepositoryImpl(每个对应一份 McpServerConfig)。配置精髓是 priority 机制:
McpServerConfig(id="dvr", packageName="com.fawcar.dvr", priority=100)
McpServerConfig(id="parking", packageName="com.fawcar.parking", priority=100)
McpServerConfig(id="avm", packageName="com.faw.zhuque", priority=100)
McpServerConfig(id="dms", packageName="com.fawcar.dmsservice", priority=100)
McpServerConfig(id="comfort", packageName="com.fawcar.system.comfortpanel", priority=100)
McpServerConfig(id="mcp-server-demo", packageName="com.fawcar.mcpserverdemo", priority=0) // 演示
跨进程传输 · AidlMcpTransport:把 MCP 的 JSON-RPC 信封序列化后过 AIDL 桥,实现 aios-agent 主进程 ↔ 各业务 App 的 MCP Server 通信。两端共用同一个类(CLIENT/SERVER 模式),序列化用 SDK 自带 McpJson,无需自己写 schema。
对于"自动泊车的同时打开空调"这类多意图指令,RoutingUseCase 用规则(0 次额外 LLM)判定是否走 LLM_PLANNER:LlmPlannerAdapter 自己调 LLM 生成 Plan、PlanAssessmentRouter 处理 Replan(上限 3 次)。
FUNCTIONAL(单意图直接 Koog 迭代)/ LLM_PLANNER(多意图拆解)/ GOAP(强状态机,终态规划,本期降级 FUNCTIONAL)。SimpleLLMWithCriticPlanner.buildPlan/assessPlan 是 protected,必须配合 AIAgentBuilder.strategy(),API 风险高;自研 LlmPlannerAdapter ~200 行可控,Koog 升级不影响。SimpleStep / SimplePlanAssessment(Continue/Replan/NoPlan),不依赖 Koog 类型,保持 domain 干净。ChatDbHelper 管 5 张表(SQLite,非 Room):
| 表 | 用途 |
|---|---|
session | 会话元数据 |
chat_run | 聊天记录(1 轮对话 = 1 行) |
tool_call | 工具调用明细 |
memory_summary | LLM 摘要缓存 |
ltm_vector | 长期记忆向量(1024 维,float32 BLOB) |
记忆两层:
RoomChatHistoryProvider 落 SQLite;SummarizingPreProcessor 在消息超 20 条时用 LLM 压成摘要。ltm_vector,下次用用户问题查 top-K 注入 prompt。为什么不接 sqlite-vec? Koog 的
EmbeddingStorage检索本就是"全量拉回 + 内存算余弦",与向量库等价;自研SqliteVectorStorageBackend省掉 native .so / JNI / KSP 依赖,断网时 embed 降级零向量、RAG 静默关闭但对话不中断。N5 坑(已固化注释纪律):Koog
AIAgentBuilder.install(Feature)内部永远用feature.createInitialConfig()创建全新空 Config,Koin 注入的 Config 完全被忽略。必须在 lambda 里手动把 Koin 配的 settings 拷到 Koog 内部 Config——ChatMemory 同理。
| 约束 | 机制 | 落点 |
|---|---|---|
| 行车态泊车工具不可见 | 服务端不注册 + 客户端 RuntimeFilter 双保险 | VehicleStateFilterStrategy |
| 危险动作需确认 | HMI 确认浮层,5s 超时取消 | PolicyEngine / PolicyGuardedMcpTool |
| 整体不挂死 | 120s 可暂停超时 + 单工具 5s + 确认 5s,三级兜底 | WorkflowEngine / InteractiveTimeoutGuard |
| 跨 App 绑定安全 | signature 级自定义权限 | McpServerConfig.permission |
| 主线程不 ANR | agent 调用在 Dispatchers.IO | RunMcpAgentUseCase |
把全文所有核心模块浓缩成一句话,方便分享时快速索引。
| 模块 | 一句话简介 |
|---|---|
ChatViewModel | 14 依赖桥接成 1 个 StateFlow 的唯一胶水层 |
ChatEvent | sealed 类建模所有 UI 交互,编译器穷举保证不漏分支 |
ChatRepository | 与某个 LLM 后端对话的接口(实现 KoogChatRepository) |
LlmRouter | 端云双栈路由核心,三层优先级(隐私极 > 偏好 > AUTO) |
KoogLlmFactory | 建云端/本地/NPU 三 client 的工厂,Ktor 引擎共享 |
PrivacyDetector | 隐私内容命中 → 无条件强制本地(红线) |
HealthChecker | 云端健康探测 + 30s 缓存,断网时触发降级 |
TaskClassifier | AUTO 模式按 query 复杂度分流本地/云端 |
McpConnectionManager | 多连接编排 + 工具聚合 + 跑 agent 的总入口 |
CapabilityRegistry | 把多连接工具打平成一份带源注册表,动态刷新 |
RuntimeFilterChain | 按车况/权限过滤可见工具,行车态藏泊车双保险 |
WorkflowEngine | 意图→工具→结果 四阶段 + 120s 可暂停超时兜底 |
PolicyEngine | 危险动作 HMI 确认闸门,不可绕过 |
AidlMcpTransport | MCP JSON-RPC 过 AIDL 桥,CLIENT/SERVER 共用 |
LlmPlannerAdapter | 自研 LLM 规划器,绕开 Koog Planner SDK(GOAP 降级) |
ChatDbHelper | SQLiteOpenHelper 管 5 张表(非 Room) |
SqliteVectorStorageBackend | 长期记忆 1024 维向量持久化(自建 BLOB,非 sqlite-vec) |
VehicleStateProvider | 档位/车速/驻车态唯一真相源,被所有层订阅 |
AppModule | Koin 全图装配,LLM_BACKEND 编译期切后端 |
下面用 6 个场景串起全链路(输入 → 各层流转 → 输出)。
示例 1:普通聊天(云端)
输入:"今天天气怎么样?"
① ChatViewModel.doRunMcp → llmRouter.recordCurrentQuery(...)
② RunMcpAgentUseCase → WorkflowEngine.run
③ 阶段1/2:RuntimeFilter 算出可见工具名
④ 阶段3:Router 选 CLOUD(AUTO,无隐私命中)→ Koog AIAgent 决策:无需工具 → 直接回复
⑤ 阶段4:整理成自然语言
输出:"我暂时无法获取实时天气,建议……"
示例 2:隐私强制本地
输入:"我家的地址是 xxx 路 xxx 号,记一下"
① PrivacyDetector 命中隐私极 → Router 强制 LOCAL
② 本地 Ollama 1.5B 推理,数据不出车机
③ UI 显示 🔒 图标(privacyReason 非空)
输出:本地模型回复确认已记录(不调任何云 API)
示例 3:断网降级
前提:云端不可达,本地可用
① HealthChecker 标记云端不健康(30s 缓存)或本地失败计数触发回落
② Router 选 LOCAL,Ollama 接管
输出:对话不中断,仅降级为本地能力(无工具调用闭环)
示例 4:MCP 多工具调度(核心卖点)
输入:"打开 AVM 视图,再关掉空调"
① WorkflowEngine 阶段2:RuntimeFilter 算出可见工具 {avm_open, ac_power_off, ...}
② 阶段3:McpConnectionManager 合并多连接 ToolRegistry → Koog AIAgent
③ LLM 决策:调 avm_open(AIDL→AVM App)→ 调 ac_power_off(AIDL→空调 App)
④ 阶段4:LLM 汇总"已打开 AVM 视图,空调已关闭"
UI:🤖 交给 LLM… → 🛠 调用 MCP avm_open… → 🛠 调用 MCP ac_power_off… → ✅ 完成
示例 5:行车态泊车被过滤
前提:车速 > 0(非驻车)
输入:"帮我自动泊车"
① VehicleStateFilterStrategy:!isParked && PARKING 类 → 过滤 parking_start 等
② RuntimeFilter 输出可见工具集为空(只剩非泊车工具)
③ runWithTools 返回降级话术
输出:"当前正在行驶,泊车功能不可用,请停车后再试。"
示例 6:Planner 路径(多步)
输入:"准备出门:关空调、降车窗、导航回家"
① RoutingUseCase 命中"准备"关键词 + 工具数 > 5 → LLM_PLANNER
② LlmPlannerAdapter.buildPlan → [关空调, 降车窗, 导航回家]
③ PlanAssessmentRouter.assessPlan → Continue
④ executePlanSteps:把 Plan 作为严格指令塞进 prompt,工具白名单缩到这 3 个
输出:按序调 3 个工具并逐个说明结果;UI 显示 📋 Planner 触发
SimpleLLMWithCriticPlanner 的 API 是 protected + 须配 strategy(),风险高;自研 200 行可控,升级不影响。McpJson。已落地(一期):
Deferred(与终态目标对齐的差距,不写满):
mcp-server-demo 1 个;DVR/泊车/AVM/DMS/空调 5 个已声明未装,走优雅降级。| 术语 | 含义 |
|---|---|
| AIOS | 一汽智能座舱 AI Agent,本文主角应用 |
| MCP | Model Context Protocol,LLM↔工具标准协议,本工程用于跨 App 调度 |
| Clean Architecture | 依赖单向、domain 为核心的架构风格 |
| Koin | Kotlin 轻量依赖注入框架 |
| LlmRouter | 端云双栈 LLM 路由核心 |
| 四引擎 | CapabilityRegistry / RuntimeFilterChain / WorkflowEngine / PolicyEngine |
| LTM | Long-Term Memory,跨会话长期记忆 + RAG |
| Ollama / LiteRT | 端侧推理引擎(CPU / NPU) |
| RAG | Retrieval-Augmented Generation,检索增强生成 |
domain/
usecase/ Send/Stream/RunMcpAgentUseCase.kt
repository/ 10+ 接口(ChatRepository, Mcp*, Policy*, Workflow*, Planner, Vehicle*, 等)
model/ ChatMessage, RunRecord, TraceEvent, mcp/*(工具/状态/能力/过滤上下文/工作流)
data/
llm/ LlmRouter, KoogLlmFactory, LiteRTLLMClient, PrivacyDetector, HealthChecker, TaskClassifier, Models
mcp/ McpConnectionManagerImpl, McpAgentFactory, CapabilityRegistryImpl, RuntimeFilterChainImpl,
PolicyEngineImpl, WorkflowEngineImpl, McpClientRepositoryImpl,
transport/AidlMcpTransport, filter/*, planner/RoutingUseCase
planner/ LlmPlannerAdapter, PlanAssessmentRouter, SimpleStep, SimplePlanAssessment
chat/ ChatDbHelper, RoomChatHistoryProvider, SummarizingPreProcessor, SqliteVectorStorageBackend
vehicle/ VehicleStateRepository, VehicleStateService
di/ AppModule.kt(Koin 全图装配)
presentation/
viewmodel/ ChatViewModel.kt
ui/ ChatScreen, SessionListScreen, SettingsScreen, ChatSummaryCard, PrivacyBadge
ui/ MainActivity.kt(Compose 壳)
vehicle/ VehicleState.kt(跨进程 DTO 契约)
本文档基于 AiosAgent 工程逐文件代码审查整理,结构样式参照 AIOS_终态目标.md(终态目标设计基线);设备序列号、API Key、内网地址、分支名等敏感信息已脱敏,可直接用于技术分享与对外发布。当前架构与终态目标的逐条差异见 §0 对齐表。