Captain 配置控制面的工程设计

jonathan
2026-06-30 / 0 评论

Captain 配置控制面的工程设计

在 AI 客服、知识库和终端助手同时存在的系统里,“选择一个模型”从来不只是下拉框操作。不同能力需要的模型接口不同,故障时的降级策略不同,是否允许执行设备动作的风险也不同。若把这些规则散落在 Prompt、环境变量和业务服务中,系统会很快变得不可解释,也无法被运营团队安全地调整。

Captain 的设置页把这些决定集中为一个账号级控制面。页面上看到的是模型、路由、开关和阈值;运行时接收到的则是一套经过验证、带版本、可追踪的决策配置。这篇文章从这张页面出发,解释它背后的设计,以及配置如何进入实际请求路径。screencapture-localhost-3000-app-accounts-1-settings-captain-2026-08-15-09_15_29

设置页不是“模型选择器”,而是运行时控制面

Captain 设置由四类账号级配置组成,保存在 Account.settings 中:

配置 解决的问题 运行时作用
captain_models 为传统功能保留简单的默认模型选择 作为未配置 Feature Route 时的模型回退
captain_features 控制功能是否对账号启用 开关标签建议、帮助中心搜索、语音转写等能力
llm_feature_routes 为每项能力指定 Provider、Model 和降级链 让不同能力使用匹配的模型接口和可用性策略
captain_routing 定义消息在对话、知识库、Skill 和澄清之间如何决策 约束 Agent 是否检索、是否执行、何时转人工

这四类配置的边界刻意分开。功能开关回答“这项能力是否可用”;Feature Route 回答“它要使用哪条模型链”;路由配置回答“当前请求应该走哪类能力”。一个模型可以支持多个能力,但不能因此让同一份配置承担所有决策。

flowchart LR
  A["Captain 设置页"] --> B["账号 settings"]
  B --> C["配置校验与版本化"]
  C --> D["FeatureRouter\n解析模型路由链"]
  C --> E["EffectiveConfigResolver\n解析路由策略"]
  D --> F["Provider / Model 请求上下文"]
  E --> G["对话 / 知识 / Skill / 澄清"]
  F --> H["模型、Embedding、Rerank、转写"]
  G --> H

两层模型配置:兼容旧入口,也支持能力级路由

页面上方的“模型配置”保留了 Editor、Assistant 和 Copilot 的默认模型选择。这是面向现有功能的兼容层:当某项能力没有显式 Feature Route 时,运行时仍能使用原有的模型选择逻辑。

真正决定多 Provider 行为的是“LLM Feature Routes”。每一项 Feature Route 可以配置:

  • 一个主路由,由 Provider 配置和模型配置组成;
  • 最多三个有序的降级路由;
  • 与该能力匹配的模型能力要求。

例如,Assistant 路由需要 chatjson_outputtools;帮助中心和 Skill 检索需要 embedding;知识库和 Skill 重排需要 rerank;语音转写需要 audio_transcription,且模型元数据必须完整。页面只显示已经启用且满足这些要求的模型,后端会再次验证,不能依赖前端筛选保证正确性。

这种拆分避免了一个常见错误:将“聊天模型能用”误认为“它能承担全部 AI 工作”。Embedding、重排、函数调用和语音转写的协议与成本模型都不同,运行时应按能力选择模型,而不是按页面上最显眼的一个模型做全局复用。

路由链的优先级:本账号优先,系统配置兜底

Llm::FeatureRouter 解析某项 Feature 时按下面的顺序寻找可用路由:

  1. 账号配置的该 Feature Route;
  2. 可兼容 Feature 的账号配置。目前 captain.skill_retrieval 可以复用 help_center_search 的 Embedding 路由;
  3. 系统级 Feature Route;
  4. 可兼容 Feature 的系统级路由;
  5. Provider 中可用且兼容的模型;
  6. 传统模型配置给出的回退模型。

每一条候选路由都会校验 Provider 是否启用、模型是否启用,以及模型是否满足能力要求。因此,管理员禁用模型或移除 Provider 后,失效配置不会被静默继续使用。

降级链也不是“所有失败都自动切模型”。Llm::FallbackExecutor 只会在请求被标记为幂等、错误可重试且存在下一条路由时切换。Embedding、重排等纯计算能力可以使用这个策略;带 Tool 的 Agent 循环可能已经产生业务副作用,运行时会以非幂等方式执行,不能因 Provider 异常自动重放到另一家模型服务。

这使高可用与业务安全能够同时成立:可安全重试的计算请求尽量恢复,可能调用外部系统的动作则保留明确的业务幂等和人工可见的状态。

路由策略:把“模型判断”变成可治理的产品决策

模型路由解决“由谁推理”,Agent 路由解决“此刻该做什么”。页面的“Agent routing”区将这一层显式暴露为账号默认策略,覆盖通用对话、知识优先级、Skill 执行和语义路由。

三种预设不是风格切换,而是风险配置

EffectiveConfigResolver 内置三种预设:

预设 执行意图要求 Skill 语义阈值 适合场景
保守 必须明确请求动作 0.82,中 0.64,最小差值 0.08 面向生产客服与知识问答
平衡 高置信 Skill 可放宽为偏好明确动作 0.78,中 0.62,最小差值 0.06 已评估过的内部助手
行动优先 可选明确动作 0.74,中 0.58,最小差值 0.04 专用、受控的运营终端

预设会给出一组相互匹配的默认值,而不是简单地改一个开关。管理员单独调整任意字段后,配置会被标记为 custom,避免界面把“部分修改过的预设”误称为某个标准策略。

每次更新还会递增 config_version,写入 updated_by_idupdated_at。这使运行记录可以关联到当时的路由版本,排查“为什么这条消息昨天走知识库、今天执行 Skill”时不必依赖日志猜测。

知识优先:先区分“咨询”与“执行”

默认策略将产品说明、操作指导和排障类问题优先导向知识库。IntentClassifier 对常见的问候、感谢、身份询问和能力询问走本地通用对话;对“如何设置”“连接失败怎么处理”这类知识意图,DecisionArbitrator 会在用户没有明确要求执行动作时优先返回 search_knowledge

这一点对终端支持尤其重要。用户问“打印机断开后怎么重新连接”时,系统应先找文档证据,而不是将其理解为“立即操作打印机”。只有用户明确提出“帮我检查某台打印机状态”,并且后续 Skill、权限与风险校验都成立时,才允许进入执行链。

页面中的几个选项对应这一策略:

  • “优先知识”:知识类咨询优先走检索;
  • “高置信知识覆盖中等置信 Skill”:避免中等把握的操作候选压过可靠文档;
  • “知识无结果时”:可选择先澄清再转人工、直接转人工或使用固定兜底;
  • “未分类对话”:选择继续检索知识或要求用户澄清。

系统的 knowledge_only 约束保持启用,路由配置不能把无证据的业务回答重新开放给模型自由生成。

Skill 执行:自然语言不是权限

页面允许分别配置自然语言触发、显式执行意图和 Quick Action。它们控制的是“是否进入候选与规划”,不是“绕过安全直接执行”。

执行前仍会经历以下边界:

  1. Skill 必须属于当前 Assistant、当前账号和当前客户端范围;
  2. Capability 必须处于可用状态,且与客户端系统和类型匹配;
  3. Operation 的风险等级必须覆盖目标 Capability;
  4. L3 动作需要确认,L4 在当前阶段被阻止;
  5. Skill 计划和 Tool 输入输出都要通过 JSON Schema 校验。

所以“行动优先”只意味着更容易识别为执行意图,绝不意味着放松 Capability、权限或确认。设置页的安全提示正是为了让运营人员理解这个边界。

语义路由的灰度开关:先观测,再接管

复杂 Skill 选择不应完全依赖一次模型规划。Captain 提供语义检索和高/中置信区间,用于从已授权的 Skill 索引中找候选。页面将这套能力拆成四个可操作的控制项:

  • 启用语义路由:在原有 Planner 前检索可用的 Skill 候选;
  • 启用快速路径:高置信的已配置 Skill 可以跳过复杂 Planner;
  • Shadow mode:并行评估语义决策,但仍以既有 Planner 作为实际执行路径;
  • 灰度比例:按稳定的客户端会话控制允许快速路径的流量比例。

阈值不只包含高分和中分,还包含候选之间的最小分差,以及中等置信时是否要求词法证据。它们共同回答一个问题:系统是否真的“足够确定”用户想要这个 Skill,而不是只找到了最相近的名字。

Shadow mode 与灰度比例提供了一个可逆的上线顺序:先收集路由差异和候选证据,再扩大真正使用快速路径的会话比例。对于可能调用设备、订单或支付能力的 Agent,这比直接全量切换更适合生产环境。

配置写入:前端只提交意图,后端负责合并与验证

设置页通过 /api/v1/accounts/:account_id/captain/preferences 获取和更新配置。前端提交的是局部变更,例如某个 Feature Route、一个路由阈值或一个功能开关;控制器在服务端完成合并,而不是让浏览器提交整份未经处理的账号设置。

写入流程如下:

sequenceDiagram
  participant UI as 设置页
  participant API as PreferencesController
  participant R as EffectiveConfigResolver
  participant V as Validators
  participant A as Account.settings

  UI->>API: 提交局部配置
  API->>R: 合并默认值、预设与更新值
  R-->>API: 新版本的路由配置
  API->>V: 校验模型、能力、路由链与字段范围
  V-->>API: 通过或返回明确错误
  API->>A: 保存账号配置
  API-->>UI: 返回完整生效配置

校验分为三层:

  • Feature Route 校验限制每个能力最多三个降级路由,禁止重复 Provider/Model 组合,并要求模型能力匹配;
  • 路由配置校验限制允许的字段、枚举和数值范围,例如灰度比例必须在 0..100,中等置信不能高于高置信;
  • Account 模型和功能配置校验阻止未知模型或不合法功能值写入。

如果某个原有路由因 Provider 或模型被禁用而变得不合法,后端会在后续更新过程中清理无效条目。配置的目标是保存“可执行的意图”,而不是保存一份会在运行时才爆炸的历史表单数据。

路由测试:验证决策,不制造副作用

设置页提供“测试路由”入口。它会展示最终路由、候选证据、知识状态和安全检查结果,但不会创建 Operation、SkillRun、ToolCall、MCP 请求或 Client Bridge 请求。

这个设计让管理员可以在调整阈值、预设或模型路由后,使用代表性的咨询和执行语句比较结果:

  • “如何选择商品规格”是否稳定走知识库;
  • “检查 dine_in 打印机状态”是否识别为受控的执行请求;
  • 模糊的“检查一下”是否要求补充对象,而不是猜测执行;
  • 特定客户端或角色不具备权限时,安全检查是否阻止后续动作。

对 Agent 配置而言,测试入口不是演示功能,而是变更前的最小验证环境。它把最难解释的路由问题提前暴露在没有外部副作用的阶段。

结语:让模型选择和业务风险分层治理

Captain 设置页的价值不在于提供更多下拉框,而在于将多模型系统的关键决策拆分为明确、可验证的层次:能力决定模型要求,Feature Route 决定 Provider 链,路由策略决定请求意图,Capability 与确认机制决定能否实际执行。

当这些层次都以账号级配置、版本和干运行测试承载时,运营团队可以逐步调整体验,工程团队也能稳定地追踪运行时行为。模型会更换、Provider 会波动、Skill 会增加,但“先验证配置、再执行决策、最后产生副作用”的控制面原则不应该改变。

评论

博主关闭了当前页面的评论