# M10 Captain AI与Copilot 功能梳理 > 版本标注:Chatwoot Enterprise v3.13+ > 模块定位:企业版核心功能,为客服团队提供AI助手(Captain)与智能副驾驶(Copilot)能力 --- ## 1. Captain::Assistant CRUD — 助手模型+控制器+路由 ### 功能描述 Captain Assistant 是企业版的AI助手实体,每个Account可创建多个Assistant,分别绑定不同Inbox,提供自动回复、FAQ检索、Copilot副驾驶等能力。支持CRUD全生命周期管理及Playground在线调试。 ### 用户操作流程 1. 管理员进入 Settings → Captain → Assistants 2. 创建Assistant:填写名称、描述、配置(温度、产品名、功能开关) 3. 将Assistant绑定到特定Inbox(CaptainInbox关联) 4. 在Playground页面输入消息测试Assistant回复效果 5. 编辑/删除Assistant ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/v1/accounts/{id}/captain/assistants` | 列表 | | GET | `/api/v1/accounts/{id}/captain/assistants/{id}` | 详情 | | POST | `/api/v1/accounts/{id}/captain/assistants` | 创建 | | PATCH | `/api/v1/accounts/{id}/captain/assistants/{id}` | 更新 | | DELETE | `/api/v1/accounts/{id}/captain/assistants/{id}` | 删除 | | POST | `/api/v1/accounts/{id}/captain/assistants/{id}/playground` | Playground调试 | | GET | `/api/v1/accounts/{id}/captain/assistants/tools` | 获取可用工具列表 | | CRUD | `/api/v1/accounts/{id}/captain/assistants/{id}/inboxes` | 绑定/解绑Inbox | ### 涉及的数据模型+关键字段 - **captain_assistants** 表 - `id`, `account_id`(必填), `name`(必填), `description`(必填) - `config` (jsonb): `temperature`, `feature_faq`, `feature_memory`, `feature_contact_attributes`, `product_name` - `guardrails` (jsonb): 限制性规则 - `response_guidelines` (jsonb): 回复指导方针 - 关联:`documents` → Captain::Document, `responses` → Captain::AssistantResponse, `captain_inboxes` → CaptainInbox, `copilot_threads`, `scenarios` ### 涉及的业务逻辑 - Playground调试分两路:v2启用 → AgentRunnerService;否则 → AssistantChatService - `available_agent_tools` 方法合并内置工具 + account下enabled的CustomTool - Assistant创建后可作为消息sender(`messages, as: :sender`),在对话中自动回复 ### 涉及的自动化/规则/事件 - Assistant创建/删除时,通过CaptainInbox自动关联/清理Inbox - Playground调用实时LLM生成回复 ### Chatwoot原实现代码路径 - `enterprise/app/models/captain/assistant.rb` - `enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb` - `config/routes.rb` → namespace :captain → resources :assistants --- ## 2. Captain::Document 知识库 — 文档上传+嵌入+搜索 ### 功能描述 Document是Captain的知识来源,支持两类来源:URL网页抓取和PDF文件上传。文档创建后自动触发抓取/解析Job,内容通过LLM生成FAQ(AssistantResponse),再经EmbeddingService生成向量嵌入用于语义搜索。 ### 用户操作流程 1. 管理员在Assistant详情页上传知识文档(URL或PDF) 2. 系统自动抓取/解析内容,状态从 in_progress → available 3. LLM自动从文档内容生成FAQ对(AssistantResponse),并计算嵌入向量 4. 文档可手动触发重新同步(sync) 5. 在对话/Copilot中通过SearchDocumentationService语义检索 ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/v1/accounts/{id}/captain/documents` | 列表(支持过滤/搜索/分页) | | GET | `/api/v1/accounts/{id}/captain/documents/{id}` | 详情 | | POST | `/api/v1/accounts/{id}/captain/documents` | 创建(URL或PDF) | | DELETE | `/api/v1/accounts/{id}/captain/documents/{id}` | 删除 | | POST | `/api/v1/accounts/{id}/captain/documents/{id}/sync` | 手动重新同步 | ### 涉及的数据模型+关键字段 - **captain_documents** 表 - `id`, `account_id`(必填), `assistant_id`(必填) - `external_link`(必填,URL来源), `name`, `content`(最大200K) - `status`: in_progress(0) / available(1) - `sync_status`: syncing(0) / synced(1) / failed(2) - `metadata` (jsonb): `content_fingerprint`, `last_sync_error_code`, `sync_step`, `openai_file_id` - `content_fingerprint` (string): 内容哈希,用于判断是否需要重新生成FAQ - `pdf_file`: ActiveStorage附件(PDF类型文档) - 关联:`responses` → Captain::AssistantResponse (as: documentable), `assistant` → Captain::Assistant ### 涉及的业务逻辑 - 创建后自动触发 `enqueue_crawl_job`(URL用FirecrawlService/SimplePageCrawlService抓取) - PDF文档用 `PdfProcessingService` 解析 - 内容变更后通过 `enqueue_response_builder_job` → FaqGeneratorService 生成FAQ - FAQ生成后由 `EmbeddingService` 调用RubyLLM计算向量嵌入 - 搜索时先 `TranslateQueryService` 将查询翻译为目标语言,再在approved responses中语义搜索 - 文档数量有上限限制(`LimitExceededError`) ### 涉及的自动化/规则/事件 - `after_create_commit :enqueue_crawl_job` — 自动抓取 - `after_create_commit :update_document_usage` — 更新用量统计 - `after_commit :enqueue_response_builder_job` — 自动生成FAQ+嵌入 - `after_destroy :update_document_usage` — 删除后更新用量 - 同步超时阈值:`SYNC_STALE_TIMEOUT = 2.hours` ### Chatwoot原实现代码路径 - `enterprise/app/models/captain/document.rb` - `enterprise/app/controllers/api/v1/accounts/captain/documents_controller.rb` - `enterprise/app/services/captain/documents/sync_service.rb` - `enterprise/app/services/captain/documents/single_page_fetcher.rb` - `enterprise/app/services/captain/llm/embedding_service.rb` - `enterprise/app/services/captain/llm/faq_generator_service.rb` --- ## 3. Captain::Llm 聊天服务 — AssistantChatService+OpenAI集成 ### 功能描述 AssistantChatService是Captain核心LLM对话引擎,继承BaseAiService,负责构建system prompt + 历史消息 + 工具调用链,与OpenAI(通过RubyLLM)交互生成回复。支持工具调用(function calling)循环直到获得最终文本回复。 ### 用户操作流程 1. 用户在Inbox对话中发送消息 2. 系统判定需要Captain回复(通过AssistantActionClassifierService判断动作类型) 3. AssistantChatService构建消息序列:system prompt + 历史 + 用户消息 + 工具定义 4. LLM返回回复,可能包含工具调用(如search_documentation) 5. 工具执行后结果回填消息序列,再次调用LLM 6. 最终文本回复发送到对话 ### 涉及的API端点 间接调用,主要通过 `POST /api/v1/accounts/{id}/captain/assistants/{id}/playground` 触发 ### 涉及的数据模型+关键字段 - 依赖 `Captain::Assistant`(config, guardrails, response_guidelines) - 依赖 `Captain::AssistantResponse`(FAQ知识对,嵌入向量) - 依赖 `Captain::CustomTool`(自定义HTTP工具) ### 涉及的业务逻辑 - **System Prompt构建**:由 `SystemPromptsService.assistant_response_generator` 生成,包含产品名、回复指导方针、护栏规则 - **工具构建** (`build_tools`):内置 SearchDocumentationService + account下enabled的CustomTool(→ CustomHttpTool) - **对话循环**:`request_chat_completion` → 若返回tool_call → 执行tool → 回填结果 → 再请求 → 直到文本回复 - **消息格式**:`generate_response(additional_message:, message_history:, role:)` 拼接历史+新消息 - 继承 `Llm::BaseAiService` 使用RubyLLM与OpenAI通信 - 包含 `Captain::ChatHelper` 模块(共享辅助方法) ### 涉及的自动化/规则/事件 - Assistant自动回复触发:当Inbox配置了Captain Assistant且用户消息到达 - ActionClassifierService判断是否需要AI回复 vs 转人工 - 工具调用循环由RubyLLM的function calling机制驱动 ### Chatwoot原实现代码路径 - `enterprise/app/services/captain/llm/assistant_chat_service.rb` - `enterprise/app/services/captain/llm/system_prompts_service.rb` - `enterprise/app/services/captain/llm/assistant_action_classifier_service.rb` - `enterprise/app/services/captain/open_ai_message_builder_service.rb` - `app/services/llm/base_ai_service.rb` --- ## 4. Captain::Tools 工具注册 — SearchDocumentationService+BaseTool+CustomTool ### 功能描述 Captain工具系统为LLM提供function calling能力。BaseTool是所有工具的基类(继承RubyLLM::Tool),SearchDocumentationService是内置核心工具(语义搜索知识库),CustomTool允许企业自定义HTTP API工具。ToolRegistryService负责注册和管理工具集合。 ### 用户操作流程 1. 系统自动注册内置工具(search_documentation) 2. 管理员可在 Settings → Captain → Custom Tools 创建自定义HTTP工具 3. 自定义工具配置:名称、描述、HTTP方法、端点URL、参数Schema、认证方式(none/bearer/basic/api_key) 4. 工具在Assistant对话/Copilot对话中被LLM自动调用 ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | CRUD | `/api/v1/accounts/{id}/captain/custom_tools` | 自定义工具管理 | | POST | `/api/v1/accounts/{id}/captain/custom_tools/test` | 测试自定义工具 | ### 涉及的数据模型+关键字段 - **Captain::Tools::BaseTool** (非DB模型,继承RubyLLM::Tool) - `assistant`, `@user` 属性 - `active?` 方法(默认true) - `user_has_permission(permission)` 权限检查 - prepend `Captain::Tools::Instrumentation`(监控埋点) - **captain_custom_tools** 表 - `id`, `account_id`, `slug`(唯一), `title`, `description` - `endpoint_url`, `http_method`(GET/POST), `auth_type`(none/bearer/basic/api_key) - `auth_config` (jsonb), `param_schema` (jsonb), `request_template`, `response_template` - `enabled`(bool, 默认true) - 每account上限15个(`MAX_PER_ACCOUNT = 15`) ### 涉及的业务逻辑 - **SearchDocumentationService**:接收query参数 → TranslateQueryService翻译 → 在assistant.responses.approved中语义搜索 → 格式化返回FAQ+来源链接 - **CustomHttpTool**:将CustomTool配置转为LLM可调用的工具定义 → LLM触发时执行HTTP请求 → 按response_template格式化结果 - **ToolRegistryService**:`register_tool(tool_class)` → 检查active? → 存入@tools字典 → 支持 `method_missing` 动态调用 - 工具名slug有64字符限制(OpenAI function name限制) ### 涉及的自动化/规则/事件 - CustomTool创建前自动生成slug(`before_validation :generate_slug`) - CustomTool创建前检查数量上限(`before_create :ensure_within_limit`) - Instrumentation模块自动记录工具调用监控数据 ### Chatwoot原实现代码路径 - `enterprise/app/services/captain/tools/base_tool.rb` - `enterprise/app/services/captain/tools/search_documentation_service.rb` - `enterprise/app/services/captain/tools/custom_http_tool.rb` - `enterprise/app/services/captain/tool_registry_service.rb` - `enterprise/app/services/captain/tools/instrumentation.rb` - `enterprise/app/models/captain/custom_tool.rb` --- ## 5. Copilot对话 — CopilotMessage+CopilotThread+ChatService ### 功能描述 Copilot是面向客服代理(Agent)的AI副驾驶,在侧边栏提供实时对话辅助。每个代理拥有独立的CopilotThread(对话线程),消息通过CopilotMessage记录,ChatService构建含上下文(当前查看对话、历史消息)+ 多工具的LLM请求。 ### 用户操作流程 1. Agent在对话详情页点击Copilot侧边栏 2. 创建新Thread或继续已有Thread 3. 输入问题(如"如何处理这个客户?") 4. Copilot根据当前查看的对话上下文+知识库搜索给出建议 5. 可在Thread中持续追问 ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/v1/accounts/{id}/captain/copilot_threads` | Thread列表(仅当前用户) | | POST | `/api/v1/accounts/{id}/captain/copilot_threads` | 创建Thread+首条消息 | | GET | `/api/v1/accounts/{id}/captain/copilot_threads/{id}/copilot_messages` | 消息列表 | | POST | `/api/v1/accounts/{id}/captain/copilot_threads/{id}/copilot_messages` | 发送消息 | ### 涉及的数据模型+关键字段 - **copilot_threads** 表 - `id`, `account_id`(必填), `user_id`(必填), `assistant_id`(可关联Assistant) - `title`(必填,默认为首条消息内容) - **copilot_messages** 表 - `id`, `copilot_thread_id`(必填), `account_id` - `message` (jsonb, 必填): `{ content: "..." }` - `message_type`: user(0) / assistant(1) / assistant_thinking(2) ### 涉及的业务逻辑 - **Thread创建**:CopilotThreadsController.create 事务中同时创建Thread + 首条user消息 → enqueue_response_job - **消息创建**:CopilotMessagesController.create 创建user消息 → `enqueue_response_job` 触发Copilot::ResponseJob - **ResponseJob** → 调用 `Captain::Copilot::ChatService.generate_response` - **ChatService构建**: - system_message: `SystemPromptsService.copilot_response_generator`(含产品名+工具摘要) - account_id_context: 注入当前account信息 - previous_history: 从copilot_thread.previous_history加载 - current_viewing_history: 如果有conversation_id,注入当前对话内容作为上下文 - **工具集**:SearchDocumentation + Copilot专用工具(GetConversation, SearchConversations, GetContact, GetArticle, SearchArticles, SearchContacts, SearchLinearIssues) - 回复生成后 `account.increment_response_usage` 计量 ### 涉及的自动化/规则/事件 - `after_create_commit :broadcast_message` — 消息创建后通过ActionCable实时推送 - CopilotMessage创建 → `enqueue_response_job` → ResponseJob异步执行 - Thread创建时检查用量限制(`usage_limits[:captain][:responses][:current_available]`) - 用量耗尽时返回限制提示消息而非AI回复 ### Chatwoot原实现代码路径 - `enterprise/app/models/copilot_thread.rb` - `enterprise/app/models/copilot_message.rb` - `enterprise/app/controllers/api/v1/accounts/captain/copilot_threads_controller.rb` - `enterprise/app/controllers/api/v1/accounts/captain/copilot_messages_controller.rb` - `enterprise/app/services/captain/copilot/chat_service.rb` - `enterprise/app/services/captain/tools/copilot/` (7个专用工具) --- ## 6. Copilot建议 — 建议生成+嵌入搜索+对话上下文 ### 功能描述 Copilot建议功能允许Agent在查看对话时一键获取AI生成的回复建议。系统基于当前对话上下文 + 知识库语义搜索 + 对话历史,自动生成针对客户问题的建议回复,Agent可直接采纳或修改后发送。 ### 用户操作流程 1. Agent打开一个对话,看到客户消息 2. 点击Copilot侧边栏或"建议回复"按钮 3. 系统自动基于对话上下文生成建议 4. Agent选择采纳建议,或在此基础上编辑后发送 ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/v1/accounts/{id}/captain/tasks/reply_suggestion` | 生成回复建议 | | POST | `/api/v1/accounts/{id}/captain/tasks/summarize` | 对话摘要 | | POST | `/api/v1/accounts/{id}/captain/tasks/rewrite` | 重写回复 | ### 涉及的数据模型+关键字段 - 复用 `Captain::Assistant`, `Captain::AssistantResponse`(嵌入向量) - 复用 `CopilotThread`, `CopilotMessage` - Tasks控制器处理独立建议任务(不走Thread流程) ### 涉及的业务逻辑 - **回复建议生成**:基于当前对话最后几条消息 + SearchDocumentationService搜索相关FAQ → 构建prompt → LLM生成建议回复 - **对话摘要**:提取对话内容 → LLM压缩为关键信息摘要 - **回复重写**:Agent输入草稿 → LLM润色优化语气/格式 - **上下文注入**:`current_viewing_history(conversation_id)` 将当前对话消息注入system context - **Copilot工具**提供对话/联系人/文章/工单检索能力,使建议基于真实数据 ### 涉及的自动化/规则/事件 - 建议生成异步执行(通过Captain::Copilot::ResponseJob) - 回复建议可配置自动触发或手动触发 - 用量限制检查:每次建议生成消耗response_usage ### Chatwoot原实现代码路径 - `enterprise/app/controllers/api/v1/accounts/captain/tasks_controller.rb` - `enterprise/app/services/captain/copilot/chat_service.rb` - `enterprise/app/services/captain/tools/copilot/` (7个上下文检索工具) - `enterprise/app/services/captain/llm/search_reply_documentation_service.rb` --- ## 交叉依赖与架构总览 ``` Captain::Assistant (核心实体) ├── Captain::Document (知识库) │ ├── EmbeddingService (向量嵌入) │ ├── FaqGeneratorService (FAQ自动生成) │ └── AssistantResponse (FAQ对 + 向量) ├── Captain::CustomTool (自定义HTTP工具) ├── Captain::Llm::AssistantChatService (对话引擎) │ ├── SystemPromptsService (prompt构建) │ ├── Tools: SearchDocumentationService + CustomHttpTool │ └── BaseAiService → RubyLLM → OpenAI └── Copilot (副驾驶) ├── CopilotThread + CopilotMessage (对话线程) ├── Captain::Copilot::ChatService (专用引擎) │ ├── 7个Copilot专用工具 │ └─ current_viewing_history (对话上下文注入) └── Tasks (独立建议:reply_suggestion/summarize/rewrite) ``` ### 关键技术选型 - **LLM SDK**: RubyLLM(统一OpenAI/其他Provider接口) - **嵌入模型**: 可配置(`CAPTAIN_EMBEDDING_MODEL`),默认`LlmConstants::DEFAULT_EMBEDDING_MODEL` - **向量搜索**: 基于AssistantResponse的嵌入向量,通过pgvector或类似机制语义检索 - **异步Job**: Sidekiq(crawl_job, response_builder_job, copilot_response_job) - **实时推送**: ActionCable(CopilotMessage broadcast_message) ### 企业版限制 - 所有Captain/Copilot功能仅Enterprise版本可用 - Document数量上限(`LimitExceededError`) - CustomTool每account上限15个 - Copilot回复有用量配额限制(`usage_limits[:captain][:responses][:current_available]`)