From 32d3329d1b65ee795980c2db087210e3cf8b15f5 Mon Sep 17 00:00:00 2001 From: Rogee Date: Sun, 12 Jul 2026 22:16:56 +0800 Subject: [PATCH] docs(copilot): define global configuration --- docs/README.md | 13 +- .../plans/2026-07-12-copilot-configuration.md | 356 ++++++++++++++++++ docs/product/08-ai-roadmap.md | 80 ++-- 3 files changed, 390 insertions(+), 59 deletions(-) create mode 100644 docs/plans/2026-07-12-copilot-configuration.md diff --git a/docs/README.md b/docs/README.md index 1de027b9..eb2433c8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # GoChat 文档索引 -> 最后更新: 2026-07-09 +> 最后更新: 2026-07-12 > 项目状态: main 分支 @ 805402f GoChat 是 Chatwoot v4.14.0 的 Go 语言 1:1 重写。本目录包含项目的设计文档、需求规格、 @@ -88,12 +88,13 @@ M01-M12 模块的 Chatwoot 功能梳理文档,基于 Chatwoot 源码深度阅 ### 4. 实现计划(plans/) -已执行完毕的大型实现计划,保留作为实现历史参考。 +大型功能的待实施计划与已执行历史计划。 -| 文档 | 说明 | -|------|------| -| [plans/2026-05-24-agent-agentbot-assignment-policy.md](plans/2026-05-24-agent-agentbot-assignment-policy.md) | Agent + AgentBot + AssignmentPolicy 实现计划 | -| [plans/2026-05-24-companies-campaign-helpcenter.md](plans/2026-05-24-companies-campaign-helpcenter.md) | Companies + Campaign + HelpCenter + Notes + Labels + Attachments 实现计划 | +| 文档 | 说明 | 状态 | +|------|------|------| +| [plans/2026-07-12-copilot-configuration.md](plans/2026-07-12-copilot-configuration.md) | Copilot 配置中心:平台 Provider、账户策略、密钥掩码、运行时热切换 | 待实施 | +| [plans/2026-05-24-agent-agentbot-assignment-policy.md](plans/2026-05-24-agent-agentbot-assignment-policy.md) | Agent + AgentBot + AssignmentPolicy 实现计划 | 历史 | +| [plans/2026-05-24-companies-campaign-helpcenter.md](plans/2026-05-24-companies-campaign-helpcenter.md) | Companies + Campaign + HelpCenter + Notes + Labels + Attachments 实现计划 | 历史 | ### 5. Parity 对齐工具与报告(parity/) diff --git a/docs/plans/2026-07-12-copilot-configuration.md b/docs/plans/2026-07-12-copilot-configuration.md new file mode 100644 index 00000000..041da4d8 --- /dev/null +++ b/docs/plans/2026-07-12-copilot-configuration.md @@ -0,0 +1,356 @@ +# Copilot 配置中心实施计划 + +> 日期:2026-07-12 +> 状态:待实施 +> 菜单名称:`Copilot 配置` +> 目标:为 GoChat 自托管部署提供可安全管理、可测试、可运行时生效的 Copilot/LLM 配置入口,并让页面选择的模型真正作用于 LLM 请求。 + +--- + +## 1. 已确认的产品决策 + +1. 设置菜单统一命名为 **Copilot 配置**,不在用户界面继续使用“Captain AI 配置”作为供应商配置名称。 +2. `Captain` 仍保留为 AI 助手、知识库、场景、工具等业务模块的内部领域名称,不做全仓重命名。 +3. LLM Provider、Base URL、API Key 属于**平台级配置**,对整套 GoChat 安装生效。 +4. 功能开关、功能模型、回复风格属于**账户级配置**,只影响当前 Account。 +5. Assistant 的提示词、Guardrails、Response Guidelines、知识文档和 Inbox 绑定继续在 Assistant 页面管理,不塞入 Copilot 配置页。 +6. API Key 明文落库,不增加应用层加密;接口只返回掩码、日志禁止记录,页面不提供查看明文能力。 +7. Copilot 在系统中全局永久启用,不提供总开关,也不允许通过环境变量、配置文件或页面关闭。 +8. Copilot Provider 参数只从数据库读取,不定义任何 Copilot/Captain 环境变量。 +9. 除 Embedding 维度变化外,配置保存后应运行时生效,不要求重启服务。 + +--- + +## 2. 当前实现缺口 + +当前仓库已经有 Captain/Copilot 页面、API 和 LLM Provider,但还不是一个可用的配置闭环: + +- 设置侧栏中的 Captain AI 入口被注释。 +- 旧设置页仅允许 Cloud/Enterprise 安装类型访问,自托管 Community 配置为不可访问。 +- 旧设置页只能保存 `captain_models` 和 `captain_features`,没有 Provider、Base URL、API Key。 +- Provider 在 `bootstrap.go` 启动时一次性创建,页面配置无法替换运行中的 Provider。 +- `NewProviderFromConfig` 接收 `provider` 参数,但当前实际固定创建 OpenAI-compatible Eino ChatModel。 +- 多个 Service 仍使用硬编码模型或 Provider 默认模型,账户保存的模型选择没有完整进入请求链路。 +- `installation_configs` 已有平台级 CRUD,但目前是无类型字符串存储,不能直接安全暴露 LLM 密钥。 + +因此本任务不能只解开旧菜单;需要同时补齐配置存储、权限、运行时 Provider 和模型解析。 + +--- + +## 3. 页面入口与权限 + +### 3.1 菜单与路由 + +- 菜单位置:`设置 → Copilot 配置` +- 页面路由:`/app/accounts/:accountId/settings/copilot` +- 前端路由名:`copilot_settings_index` +- 移除旧路由的 Cloud/Enterprise 安装类型限制。 +- 不使用 `captain_integration` Feature Flag 或其他开关控制配置页和 Copilot 总体可用性。 +- Provider 尚未配置时页面展示“配置不完整”,而不是“未启用”。 + +### 3.2 权限分层 + +| 用户角色 | 平台 Provider 配置 | 账户功能配置 | 连接测试 | API Key 状态 | +|---|---:|---:|---:|---:| +| SuperAdmin | 可读写 | 可读写 | 可执行 | 仅显示是否已配置和掩码 | +| Account Administrator | 只读状态 | 可读写 | 不可执行平台密钥测试 | 仅显示“已配置/未配置” | +| Agent | 不可访问 | 不可访问 | 不可访问 | 不可访问 | + +平台配置的写接口必须使用 SuperAdmin 中间件保护,不能仅依赖前端隐藏。 + +--- + +## 4. 页面信息架构 + +页面分为五个区块: + +1. **运行状态**:当前 Provider、连接状态和配置完整性。Copilot 始终启用,不提供总开关。 +2. **对话模型**:Provider、Base URL、API Key、默认 Chat Model。 +3. **Embedding 模型**:Embedding Provider、Key、Endpoint、Model、Dimensions。 +4. **生成与可靠性**:Temperature、Max Tokens、Timeout、Retry。 +5. **当前账户功能**:Editor、Copilot、Assistant、标签建议、知识库语义搜索的开关和模型。 + +“保存配置”和“测试连接”必须是两个独立动作:测试候选参数不落库;保存前后端均需再次校验。 + +--- + +## 5. 平台级参数规划 + +### 5.1 基础状态 + +| 字段 | 配置键 | 类型/默认值 | 页面规则 | 生效方式 | +|---|---|---|---|---| +| 配置状态 | `configured` | derived boolean | 根据页面保存的 Provider、Model、Base URL 与 API Key 判断 | 只读 | + +不定义 `enabled` 字段。Copilot 路由、菜单和服务始终注册;账户级功能开关只控制具体能力,不等价于关闭系统 Copilot。 + +### 5.2 对话模型 + +| 字段 | 配置键 | 类型/默认值 | 校验与交互 | +|---|---|---|---| +| Provider | `chat.provider` | enum:`openai` / `anthropic` / `openai_compatible`;默认 `openai` | 必填;决定请求协议,不再把所有 Provider 当 OpenAI 协议处理 | +| Base URL | `chat.base_url` | URL | `openai`/`anthropic` 自动提供官方默认值;`openai_compatible` 必填;禁止非 HTTP(S) URL | +| API Key | `chat.api_key` | secret | 写入时允许空值表示“不修改”;清除必须单独确认;GET 永不返回明文 | +| 默认模型 | `chat.model` | string,默认 `gpt-4o-mini` | 必填;支持手工输入,不能只依赖前端静态模型列表 | + +Provider 预设只负责填充默认 Endpoint,不锁死模型: + +| Provider | 默认 Base URL | 协议实现 | +|---|---|---| +| OpenAI | `https://api.openai.com/v1` | Eino OpenAI | +| Anthropic | `https://api.anthropic.com` | Anthropic Messages API | +| OpenAI Compatible | 用户填写 | Eino OpenAI;适用于 DeepSeek、通义千问、豆包及自建网关 | + +首期不单独增加 DeepSeek/Qwen/Doubao 枚举,避免把供应商宣传名称与真实协议实现绑死。 + +### 5.3 Embedding 模型 + +| 字段 | 配置键 | 类型/默认值 | 校验与交互 | +|---|---|---|---| +| Embedding 模式 | `embedding.mode` | enum:`reuse_chat_credentials` / `separate`;默认 `reuse_chat_credentials` | Chat Provider 为 Anthropic 时必须使用 `separate` | +| Provider | `embedding.provider` | enum:`openai` / `openai_compatible` | 仅在 separate 模式展示 | +| Base URL | `embedding.base_url` | URL | 自定义兼容 Provider 必填 | +| API Key | `embedding.api_key` | secret | 与 Chat Key 分开存储;允许复用但不能在响应中回显 | +| 模型 | `embedding.model` | string,默认 `text-embedding-3-small` | 必填;连接测试必须实际调用 embeddings API | +| 向量维度 | `embedding.dimensions` | integer,默认 `1536` | 范围 1-4096;修改后要求重新索引,不直接热切换现有向量数据 | + +Embedding 配置不能隐式依赖 Anthropic,因为 Anthropic 当前没有 Embeddings API。 + +### 5.4 生成与可靠性 + +| 字段 | 配置键 | 类型/默认值 | 校验 | 生效方式 | +|---|---|---|---|---| +| Temperature | `generation.temperature` | number,默认 `0.7` | 0-2 | 热生效 | +| 最大输出 Tokens | `generation.max_tokens` | integer,默认 `1024` | 64-32768 | 热生效 | +| 请求超时 | `request.timeout_seconds` | integer,默认 `60` | 5-300 秒 | 热生效 | +| 最大重试次数 | `request.max_retries` | integer,默认 `3` | 0-5;只重试网络错误、429 和 5xx | 热生效 | + +首期不开放以下高风险或不稳定参数:关闭 TLS 校验、任意代理地址、任意请求 Header、完整请求/响应日志。 + +--- + +## 6. 账户级参数规划 + +账户配置继续存入 Account 的 `captain_models`、`captain_features` 和 `captain_preferences`,但 UI 名称统一为 Copilot。 + +### 6.1 功能开关和模型 + +| 功能 | Feature Key | Model Key | 默认状态 | 说明 | +|---|---|---|---:|---| +| 编辑器改写 | `editor` | `editor` | 开启 | 润色、改写、语气调整 | +| Copilot 对话 | `copilot` | `copilot` | 开启 | 客服侧边栏问答与回复建议 | +| AI Assistant | `assistant` | `assistant` | 关闭 | Assistant Playground、自动辅助能力 | +| 标签建议 | `label_suggestion` | `label_suggestion` | 关闭 | 仅建议;自动应用由账户策略决定 | +| 知识库语义搜索 | `help_center_search` | 使用平台 Embedding 模型 | 关闭 | 开启前必须通过 Embedding 测试并完成索引 | + +首期暂不在页面开放 `audio_transcription`,直到后端具有独立的语音转写 Provider 和真实调用链。 + +模型下拉选项应由后端根据当前 Provider 返回,且始终提供“手工填写模型 ID”。不可再返回无法由当前 Provider 调用的静态模型列表。 + +### 6.2 回复行为 + +| 字段 | 现有字段 | 默认值 | 说明 | +|---|---|---|---| +| 回复语气 | `tone` | `professional` | professional / friendly / casual / formal | +| 回复语言 | `language` | `auto` | `auto` 表示跟随客户消息;同时允许明确语言代码 | +| 最大回复长度 | `max_response_length` | `500` | 范围 50-5000 字符 | +| 附加指令 | `custom_prompt_suffix` | 空 | 最大 1000 字;页面提示其作用范围 | +| 自动应用标签 | `auto_label_enabled` | false | 与“标签建议”功能分开控制 | +| 自动创建跟进 | `auto_follow_up_enabled` | false | 默认关闭 | +| 自动回复客户 | `auto_reply_enabled` | false | 高风险开关,需二次确认并提示绑定 Assistant/Inbox | + +Assistant 自身的 Temperature、Guardrails、Response Guidelines 优先级高于账户默认值。 + +--- + +## 7. 配置来源 + +- Copilot 始终启用,不存在部署级启用开关。 +- Provider、Base URL、API Key 与默认模型仅允许通过页面和对应 API 配置。 +- 不定义或读取任何 Captain/Copilot 环境变量,也不读取 `config*.yaml` 中的 Provider、模型或启用配置。 +- 数据库没有完整配置时,业务 API 返回“Provider 未配置”,不会使用空 Key 请求外部服务。 +- 页面、菜单、接口响应文案使用“Copilot”;内部 Captain 领域名保持不变。 + +--- + +## 8. 存储与密钥呈现 + +### 8.1 存储方案 + +复用 `installation_configs`,但通过专用 `CopilotConfigService` 管理以下固定键,不允许前端直接操作通用键值 CRUD: + +| InstallationConfig Name | 内容 | +|---|---| +| `COPILOT_PROVIDER_CONFIG` | 不含密钥的 JSON 配置 | +| `COPILOT_API_KEY` | 明文 API Key | + +### 8.2 API Key 处理要求 + +- 不对 Copilot API Key 使用 AES-256-GCM 或其他应用层加密。 +- API Key 以明文写入 `installation_configs.value`;数据库访问控制、备份权限和基础设施安全由部署方负责。 +- API 响应只返回:`configured: true/false`、`masked_value: "sk-****abcd"`。 +- 更新请求中省略 `api_key` 表示保留原值;`clear_api_key: true` 才允许清除。 +- 错误日志、审计日志、连接测试响应均不得包含 Key、Authorization Header 或完整请求体。 + +--- + +## 9. 后端 API 规划 + +### 9.1 平台级接口(SuperAdmin) + +| 方法 | 路径 | 用途 | +|---|---|---| +| GET | `/platform/api/v1/copilot/config` | 获取平台配置、掩码和状态 | +| PUT | `/platform/api/v1/copilot/config` | 校验并保存平台配置 | +| POST | `/platform/api/v1/copilot/config/test` | 用候选配置测试 Chat 和 Embedding,不保存 | + +连接测试返回: + +```json +{ + "chat": { "ok": true, "latency_ms": 320, "model": "gpt-4o-mini" }, + "embedding": { "ok": true, "latency_ms": 180, "model": "text-embedding-3-small", "dimensions": 1536 } +} +``` + +失败响应仅返回归一化错误:认证失败、Endpoint 不可达、模型不存在、限流、超时、响应格式不兼容、Embedding 维度不匹配。 + +### 9.2 账户级接口(Administrator/SuperAdmin) + +| 方法 | 路径 | 用途 | +|---|---|---| +| GET | `/api/v1/accounts/:account_id/copilot/config` | 返回平台只读状态 + 当前账户配置 | +| PUT | `/api/v1/accounts/:account_id/copilot/config` | 更新账户功能、模型和回复行为 | + +旧 `/captain/preferences` 接口保留兼容,但新页面只调用 `/copilot/config` 聚合接口。 + +--- + +## 10. 运行时 Provider 设计 + +新增 `CopilotProviderManager`,替代 bootstrap 中固定注入单个 `llm.Provider`: + +```text +CopilotConfigService + → 解析有效平台配置 + → 构造候选 Chat Provider + Embedding Provider + → 执行轻量健康校验 + → 原子替换 Provider Snapshot + → 新请求使用新 Snapshot,进行中的请求继续完成 +``` + +核心约束: + +1. 保存失败或 Provider 初始化失败时,不替换当前可用配置。 +2. Service 依赖 `ProviderResolver`,每次任务开始时获取不可变 Snapshot。 +3. Snapshot 包含 Chat Provider、Embedding Provider、默认模型和生成参数。 +4. 账户模型解析顺序:`账户 feature model → 平台 chat.model → provider default`。 +5. 所有硬编码 `gpt-4`、静态模型和直接读取启动配置的调用都必须迁移到 resolver。 +6. Provider 配置不完整时返回明确业务错误,不向外部服务发请求。 + +Embedding 维度变化不自动替换在线索引;页面应先提示重新索引,完成后再切换。 + +--- + +## 11. 前端交互要求 + +- 菜单展示名称固定为“Copilot 配置”。 +- 页面顶部显示状态徽标:配置完整、配置不完整、连接正常、连接异常。 +- API Key 输入框默认空白并显示“已配置”;不把掩码当作真实值回传。 +- Provider 改变时自动填充推荐 Base URL,但不覆盖用户已经编辑的值。 +- Anthropic + 复用 Chat Embedding 凭证属于无效组合,前端即时提示,后端再次拒绝。 +- “测试连接”分别展示 Chat 与 Embedding 结果。 +- 保存成功后展示实际生效的 Provider、模型和时间。 +- 修改 Embedding Dimensions 时展示阻断式警告,不允许无确认保存。 +- Account Administrator 看到平台配置状态但不能看到 Endpoint 之外的敏感信息,也不能编辑平台配置。 + +--- + +## 12. 实施阶段 + +### 阶段 1:配置闭环(P0) + +1. 新增 Copilot typed config DTO、Service 和平台/账户 API。 +2. 接入 InstallationConfig 明文密钥存储、API 掩码和不回显规则。 +3. 实现 Provider 工厂的 OpenAI、Anthropic、OpenAI-compatible 分支。 +4. 实现 `CopilotProviderManager` 和热切换。 +5. 新建“Copilot 配置”页面和菜单,移除安装类型限制。 +6. 接通 Chat/Embedding 连接测试。 + +### 阶段 2:运行链路统一(P0) + +1. 清理 Service 中硬编码模型。 +2. 将账户 feature model 接入所有对应 LLM 请求。 +3. 统一 Temperature、Max Tokens、Timeout、Retry 的解析。 +4. Provider 未配置时返回统一错误码和前端提示。 + +### 阶段 3:账户策略与质量(P1) + +1. 聚合现有 CaptainPreference 回复行为配置。 +2. 增加配置变更审计事件,但不记录密钥。 +3. 增加 Provider 健康状态和最近测试时间。 +4. 提供知识库 Embedding 重建入口和进度状态。 + +### 阶段 4:后续能力(P2) + +- Provider 动态模型列表发现与缓存。 +- 独立语音转写 Provider。 +- Token 用量、成本和账户配额。 +- Langfuse/OpenTelemetry AI 调用观测。 +- 多 Provider fallback;首期不自动跨供应商降级,避免数据和成本不可控。 + +--- + +## 13. 验证计划 + +### 后端 + +- 数据库配置读取、默认建议值和非法组合单元测试。 +- API Key 明文存储、API 掩码、保留、替换、清除测试。 +- SuperAdmin/Administrator/Agent 权限测试。 +- OpenAI-compatible 与 Anthropic 协议适配测试。 +- 使用本地 Fake LLM Server 验证 Chat、Streaming、Embedding、401、404、429、5xx、Timeout。 +- Provider 热切换测试:失败配置不替换旧 Provider,成功配置对新请求立即生效。 +- 检查所有 LLM Service 使用 resolver,不再硬编码模型。 + +### 前端 + +- 菜单和路由权限测试。 +- API Key 不回填、掩码状态、清除确认测试。 +- Provider 条件字段和无效组合校验测试。 +- Account Administrator 只读平台配置测试。 +- 保存、测试连接、错误提示和配置不完整状态测试。 + +### 回归 + +- `cd backend && GOCHAT_TEST_DB=sqlite go test ./internal/... ./pkg/... ./cmd/...` +- `cd frontend && pnpm build` +- 浏览器验证:SuperAdmin 配置 → 测试连接 → 保存 → Copilot 实际回复 → 请求使用所选模型。 +- 日志扫描确认不出现 API Key 或 Authorization Header。 + +--- + +## 14. 验收标准 + +1. 自托管 Community 安装可以进入“设置 → Copilot 配置”。 +2. 只有 SuperAdmin 可以修改平台 Provider 和 API Key。 +3. API Key 明文落库,所有读取接口只返回掩码/状态且日志不记录密钥。 +4. 页面可以独立测试 Chat 与 Embedding 连接。 +5. 保存有效配置后不重启即可让新 LLM 请求使用新 Provider。 +6. 页面选择的 editor/copilot/assistant 模型真实出现在对应 Provider 请求中。 +7. Anthropic Chat 可以搭配独立 OpenAI-compatible Embedding 配置。 +8. Provider 不可用或未配置时返回清晰错误,不出现空 Key 请求或模糊 500。 +9. 配置失败不会破坏当前正在工作的 Provider。 +10. 全部相关后端测试、前端构建和浏览器端到端验证通过。 + +--- + +## 15. 本次明确不做 + +- 不将所有 `Captain` 代码、表名和 API 全量改名为 `Copilot`。 +- 不允许普通 Agent 或任意 Account Administrator 修改平台 API Key。 +- 不提供 Copilot 总开关、环境变量配置或 YAML Provider 配置。 +- 不在首期支持任意 Header、关闭 TLS 校验或输出完整 LLM 请求日志。 +- 不展示或提供复制已保存 API Key 明文的能力。 +- 不在首期实现自动跨 Provider fallback。 +- 不把 Assistant 的知识库、工具、Guardrails 和 Inbox 绑定搬入 Copilot 配置页。 diff --git a/docs/product/08-ai-roadmap.md b/docs/product/08-ai-roadmap.md index 1df0520a..5264da50 100644 --- a/docs/product/08-ai-roadmap.md +++ b/docs/product/08-ai-roadmap.md @@ -1,5 +1,10 @@ # GoChat AI 功能支持评估与开发路线图 +> Copilot 配置中心的新命名、参数和存储定义以 +> `docs/plans/2026-07-12-copilot-configuration.md` 为准:Copilot 始终启用, +> 不提供总开关,不定义 Captain/Copilot 环境变量或 YAML Provider 配置;Provider、 +> Base URL、API Key 与模型仅通过页面写入数据库。API Key 明文存储,API/UI 仅返回配置状态和掩码。 + > 调研日期:2026-07-08(初版)/ 2026-07-09 更新 > 基于代码库:main 分支 @ 805402f > 对标项目:Chatwoot Captain AI (enterprise edition) @@ -33,7 +38,7 @@ GoChat 已搭建了一套对标 Chatwoot Captain AI 的完整基础设施,覆 - **代码就绪但未接入**:RAG 知识库问答(路由未注册)、自动回复规则(未接入消息流程)、 CaptainConversationService(被 `_ =` 忽略) - **完全缺失**:帮助中心语义搜索、AgentBot + Captain 端到端 AI 客服、多 LLM Provider 支持 -- **配置缺口**:config.yaml 无 captain 配置段,LLM API Key 未注入,AI 功能处于"空转"状态 +- **配置缺口**:缺少数据库驱动的 Copilot 配置页面,Provider/API Key 与实际运行链路尚未闭环 整体评估:基础设施成熟度高(9/10),功能可用度中等(5/10),需补齐配置与接缝工作。 @@ -174,30 +179,9 @@ bulk_actions POST ### 2.7 配置层 -**文件**:`backend/internal/config/config.go` - -`CaptainConfig` 结构体已定义: -```go -type CaptainConfig struct { - Enabled bool - LLMProvider string // openai, azure, custom - LLMModel string // gpt-4o, gpt-3.5-turbo - LLMAPIKey string - LLMBaseURL string // 自定义端点 - EmbeddingModel string // text-embedding-3-small - EmbeddingDims int // 1536 - MaxTokens int - Temperature float64 -} -``` - -- `LLMConfig()` 方法将 `CaptainConfig` 转为 provider 友好格式 -- 支持热重载(`config.go` reloader 中包含 captain 字段) -- ENV 映射:`GOCHAT_CAPTAIN_ENABLED` / `GOCHAT_CAPTAIN_LLM_PROVIDER` / `GOCHAT_CAPTAIN_LLM_MODEL` / - `GOCHAT_CAPTAIN_LLM_API_KEY` / `GOCHAT_CAPTAIN_LLM_BASE_URL` 等 - -**问题**:`backend/configs/config.yaml` 中**没有 captain 配置段**,所有 Captain 字段为默认零值。 -bootstrap.go:536 创建 OpenAIProvider 时传入空 API Key 和空 BaseURL。 +Copilot Provider 配置存储在 `installation_configs`,由设置页面写入;运行时 +`ProviderManager` 热替换底层 Provider。`backend/internal/config/config.go` 不再定义 +Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。 --- @@ -231,11 +215,11 @@ bootstrap.go:536 创建 OpenAIProvider 时传入空 API Key 和空 BaseURL。 ## 4. 关键缺口分析 -### 缺口 G1:config.yaml 缺少 captain 配置段 +### 缺口 G1:缺少数据库驱动的 Copilot 配置中心 -- **影响**:所有 AI 功能无法实际调用 LLM(API Key 为空) -- **位置**:`backend/configs/config.yaml` 缺少 captain 段;`bootstrap.go:536` 传入空值 -- **修复成本**:极低(加几行 YAML + .env 注入) +- **影响**:Provider/API Key 不能从页面配置,账户模型选择与实际运行 Provider 脱节 +- **位置**:前端 Captain 设置页、`installation_configs`、`bootstrap.go` 固定 Provider 注入 +- **修复成本**:中(配置 API、页面、Provider Manager 和模型解析) ### 缺口 G2:RAG 路由未注册 @@ -294,26 +278,16 @@ bootstrap.go:536 创建 OpenAIProvider 时传入空 API Key 和空 BaseURL。 **前提**:需要一个可用的 LLM API Key(OpenAI 或兼容端点)。 -#### 任务 1.1:config.yaml 添加 captain 配置段 +#### 任务 1.1:通过页面配置 Copilot Provider -**文件**:`backend/configs/config.yaml` +在“设置 → Copilot 配置”中保存 Provider、Base URL、API Key 和默认模型。 +配置写入数据库并热替换运行时 Provider,不使用环境变量或 `config*.yaml`。 -```yaml -captain: - enabled: true - llm_provider: "openai" # openai, azure, custom - llm_model: "gpt-4o-mini" # 可按需改为 gpt-4o / gpt-3.5-turbo - llm_api_key: "" # 通过 .env: GOCHAT_CAPTAIN_LLM_API_KEY 注入 - llm_base_url: "https://api.openai.com/v1" # 国内可改为火山引擎/豆芽等端点 - embedding_model: "text-embedding-3-small" - embedding_dims: 1536 - max_tokens: 1024 - temperature: 0.7 -``` +- Copilot 全局永久启用,不定义总开关。 +- Provider 未配置时返回明确的 `COPILOT_NOT_CONFIGURED`。 +- API Key 明文存储,读取接口仅返回掩码和配置状态。 -同时更新 `config.dev.yaml` 和 `config.prod.yaml` 的 captain 段(如有)。 - -**验收**:`go run cmd/gochat/main.go serve` 启动后,日志输出 LLM provider 初始化成功。 +**验收**:保存后无需重启,新请求立即使用页面配置的 Provider。 #### 任务 1.2:注册 RAG 路由 @@ -472,10 +446,10 @@ captain: 1. `llm/anthropic_provider.go` — Claude 系列(不同 API 格式,需适配) 2. `llm/volcengine_provider.go` — 火山引擎/豆包(OpenAI 兼容,可能只需 baseURL 配置) 3. `llm/qwen_provider.go` — 通义千问(OpenAI 兼容) -4. Provider 工厂函数:根据 `config.captain.llm_provider` 选择实现 +4. ProviderManager 根据页面保存的数据库配置选择实现并热切换 5. 前端 `ModelSelector` 已有 UI,后端按 feature(editor/assistant/copilot)支持不同模型 -**验收**:配置 `llm_provider: "anthropic"` 后,AI 功能使用 Claude 模型。 +**验收**:页面选择 Anthropic 并保存后,AI 功能使用 Claude 模型。 #### 任务 3.4:上下文窗口优化 @@ -562,7 +536,7 @@ ModelSelector、FeatureToggle)。阶段 1-2 的前端改动极小,主要是 | `backend/internal/model/copilot_models.go` | Copilot 线程/消息/建议模型 | | `backend/internal/model/auto_reply_rule_models.go` | 自动回复规则模型 | | `backend/internal/model/article_embedding.go` | 帮助中心文章 embedding | -| `backend/internal/config/config.go` | CaptainConfig 配置结构 | +| `backend/internal/llm/provider_manager.go` | 数据库配置驱动的运行时 Provider 热切换 | | `backend/internal/app/bootstrap.go` | 依赖注入(LLM Provider + Captain Services) | | `backend/internal/router/router.go` | 路由注册(captain 命名空间 ~L1319-1489) | | `backend/internal/service/captain_assistant_service.go` | 助手 CRUD + Playground + RAG | @@ -601,8 +575,8 @@ ModelSelector、FeatureToggle)。阶段 1-2 的前端改动极小,主要是 | 文件 | 说明 | |------|------| -| `backend/configs/config.yaml` | 基础配置(**缺少 captain 段**) | -| `backend/internal/config/config.go` | CaptainConfig 结构体 + ENV 映射 | +| `backend/internal/service/copilot_config_service.go` | 页面配置持久化、明文密钥存储、API 掩码和运行时生效 | +| `frontend/app/javascript/dashboard/routes/dashboard/settings/captain/Index.vue` | Copilot 配置页面 | ### 文档 @@ -618,8 +592,8 @@ ModelSelector、FeatureToggle)。阶段 1-2 的前端改动极小,主要是 ``` 阶段 1 (P0, 1-2天) 阶段 2 (P1, 3-5天) 阶段 3 (P2, 1-2周) 阶段 4 (P3, 2-4周) ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ 1.1 config.yaml │ │ 2.1 AutoReply │ │ 3.1 HC 语义搜索 │ │ 4.1 用量统计 │ -│ captain 段 │ │ 规则接入 │ │ 3.2 Function │ │ 4.2 质量管控 │ +│ 1.1 Copilot配置 │ │ 2.1 AutoReply │ │ 3.1 HC 语义搜索 │ │ 4.1 用量统计 │ +│ 中心 │ │ 规则接入 │ │ 3.2 Function │ │ 4.2 质量管控 │ │ 1.2 RAG 路由 │ │ 2.2 AgentBot + │ │ Calling 推广│ │ 4.3 多语言 AI │ │ 1.3 取消忽略 │ │ Captain 集成 │ │ 3.3 多 Provider │ │ 4.4 审计日志 │ │ 1.4 端到端验证 │ │ 2.3 工具调用实现 │ │ 3.4 上下文优化 │ │ │