# 方案:bridge 只保留 tools,其余用 LibreDesk 内置能力 > 2026-10-28 评估。依据:LibreDesk v2.9.1 源码(`internal/aiagent/`、`internal/ai/tools.go`、`schema.sql`)+ crm-new 运行数据。 > 结论:**可行**,而且 LibreDesk 内置能力比预期多——bridge 可以从 11 个工具收缩到 4–6 个业务工具。 ## 0. 已确认的决策(2026-10-28) | 决策点 | 结论 | | --- | --- | | bridge-tools 部署 | **方案 A**:并入本实例 compose(服务名 `bridge-tools`,同 `libredesk` 网络) | | `create_opportunity`(Twenty) | **先不留** | | `search_email_history` / `collect_info` | **先删** | | 程序化输出护栏 | **先接受降级**(后续用 LibreDesk webhook 外采质量指标) | | `get_customer_info` | **保留**(业务需要) | | 保留工具清单 | `search_products` / `search_orders` / `search_inventory` / `get_customer_info` | ## 1. 关键证据:LibreDesk v2.9.1 已经内置了什么 AI agent 每次回复时自动注册的内置工具(`internal/aiagent/worker.go:290-314`): | 内置工具 | 作用 | 对应 crm-new bridge 的什么 | | --- | --- | --- | | `search_knowledge_base` | 检索 snippets + 帮助中心文章(向量),支持引用计数 | `search_kb`(bridge 的 pgvector RAG) | | `handoff`(`handoff_enabled`) | 转人工(`fallback_team_id`) | `handoff_to_human` | | `get_previous_conversations` | 拉该客户近 N 天其他会话 | `search_email_history`(部分覆盖) | | `send_email_verification` | 发 OTP 到联系人邮箱(走通知邮箱 SMTP;Redis 存码,10 分钟有效,30 分钟验证态) | `send_verification_code` | | `check_email_verification` | 校验 OTP,3 次尝试上限、重发上限 | `verify_email_code` | | `set_contact_email` | 访客改邮箱后再发码 | (bridge 无对应,新增能力) | | `resolve` | 结束时给会话打结果 | 无 | 其他内置: - **工具调用上下文自动注入**(`internal/ai/tools.go:250-270`):`X-Libredesk-Contact-Id` / `-External-Id` / `-Type` / `-Email` / `-Verified` / `X-Libredesk-Conversation-UUID` / `X-Libredesk-Inbox-Id` —— bridge 的多站点路由(sites.json)和身份判断可以直接用这些头,不再需要自己发验证 token。 - **工具级验证开关** `ai_tools.requires_verification`:不验证的客户调私有数据工具会被拦,并引导模型走内置 OTP 流程(`tools.go:186`)。 - **工具鉴权** `ai_tools.auth`(自定义 header,支持加密存储):bridge 的 shared key 直接配在工具上。 - **AI 助手配置**:instructions / guardrails / expectation / tone / response_length / max_turns / fallback_team_id / handoff_enabled / citations_enabled / languages / enabled。 - **知识库**:`ai_knowledge_base`(snippet 类)+ 帮助中心文章都会作为 embedding 源(`internal/ai/embedsource.go`)。 - **Widget 身份**:inbox secret 的 JWT 校验(`cmd/chat.go`),站点后端签 JWT 即可,不需要 bridge 的 identity 服务。 - **通知邮件 / OTP 发信**:`notification.email.*`(crm-new 里就是 163 SMTP)。 ## 1.5 落地进度 | 期 | 状态 | 说明 | | --- | --- | --- | | P0 root_url / timezone | ✅ 完成 | `root_url=https://192.168.31.61:9443`、`timezone=Europe/Berlin`(API 已写入并回读) | | P0 SMTP / embedding key | ✅ 完成 | 复用 crm-new 的 163 SMTP(smtp.163.com:465 TLS)和 DashScope key;completion 实际用 **qwen-max**(见下) | | P2 瘦身 bridge | ✅ 完成 | `bridge-tools/`(零第三方依赖,4 个工具,9 个单测通过),已并入 compose 并 healthy | | P3 工具注册 | ✅ 完成 | LibreDesk `ai_tools` 已注册 4 个,`search_orders`/`get_customer_info` 带 `requires_verification` | | P1 帮助中心/assistant | ✅ 完成 | Team「Wholesale Support」+ 帮助中心(108 篇,已嵌入)+ Assistant「Yehwang Assistant」(4 个工具、fallback team、handoff/citations 开);预览已能基于文章回答并返回 sources | | P4 渠道 | 🟡 部分完成 | **Website livechat 已建 + 自动化分配到 Assistant + 端到端验证通过**(含 OTP → search_orders);email / WhatsApp 待做 | ### ⚠️ 模型选择的关键发现 `qwen-plus-latest` / `qwen-plus` 在 LibreDesk 这套较长的 system prompt 下**不会调用工具**(实测 tool_calls=0),直接凭模型自身知识作答,还会编造 `[[cite:45]]` 这种不存在的引用(第一次预览回答「30 天退货」,而知识库实际是「非质量问题不退,质量问题 7 天内」)。 换成 **`qwen-max`** 后工具调用正常(sources 命中 5 篇,score 0.33–0.61),回答与知识库一致。因此 completion 配置为 `qwen-max`;如果以后换模型,务必用「退货政策/预购时效」这类问题验证是否会调用 `search_knowledge_base`。 ## 2. bridge 收缩后保留什么 | crm-new 现有工具 | 处理 | 说明 | | --- | --- | --- | | `search_products` | **保留** | 业务 RPC 商品搜索,LibreDesk 无替代 | | `search_orders` | **保留**(`requires_verification=true`) | 私有数据,用内置 OTP 把关 | | `search_inventory` | **保留** | 库存/ETA | | `get_customer_info` | 保留(可选) | 若 Twenty 客户资料要查;也可并进 orders | | `create_opportunity` | 保留(可选) | Twenty 商机写入,LibreDesk 无替代;不做 CRM 则去掉 | | `search_kb` | **删除** | 用内置 `search_knowledge_base`;108 篇帮助文章已在 LibreDesk 里 | | `search_email_history` | 先删 | 内置 `get_previous_conversations` 覆盖「本系统内历史」;旧邮件库不再接入 | | `collect_info` | 先删(可选保留) | lead 槽位采集改为 assistant 指令 + 联系人自定义属性;要做销售漏斗再保留 | | `handoff_to_human` | **删除** | 内置 handoff + fallback_team_id | | `send_verification_code` | **删除** | 内置 OTP 工具 | | `verify_email_code` | **删除** | 内置 OTP 工具 | **结果:bridge = 一个只暴露 3–5 个 HTTP 工具的瘦服务**(+ 多站点配置、RPC 客户端、Twenty 客户端、shared key 鉴权、健康检查)。 ## 3. 明确会被「降级」的能力(要接受或后补) | 现有能力 | 用内置后的状态 | 建议 | | --- | --- | --- | | 程序化输出护栏(URL 白名单、价格/库存数字校验、幻觉重写) | **没有等价物**;只有 assistant 的 `guardrails` 提示词约束 | 先接受(低流量验证);需要时用 LibreDesk webhook → 独立质量服务补 | | 质量飞轮 / 指标 / 日报 / 引用检查 / A-B | 无等价物;LibreDesk 只有基础报表 | 后续用 webhook 采集到外部(bridge 加一个 consumer,不做实时改回复) | | 旧 bridge Hybrid RAG(parent-child + 向量 + 全文 + RRF + rerank) | 退化为向量 top-k(snippets + 文章) | 用真实问题跑检索评测对比;不满意可把 snippet 切细或补 FAQ | | 邮件历史检索(旧 `kb_mail_docs`) | 只覆盖 LibreDesk 内会话 | 需要历史邮件时再做离线 ingest | | lead 槽位(Redis 跨轮) | 没有 | 用 assistant instructions + 自定义属性;或保留 `collect_info` 工具 | ## 4. 实施分期 ### P0 前置(0.5h) - 配置 `notification.email.*`(OTP + 通知都依赖它,必须有可用 SMTP); - AI provider:completion + **embedding**(内置 KB 检索依赖 embedding,必须配); - 修 `root_url`、`timezone`(见时区方案)。 ### P1 LibreDesk 内置能力配置(2–4h) 1. 帮助中心 + 108 篇文章(从 crm-new 导出后导入,或按原源重灌); 2. 需要时补 snippets(FAQ 短答案); 3. AI assistant:instructions / guardrails / tone / max_turns / languages / citations / fallback_team_id / handoff_enabled; 4. 团队(Wholesale Support)+ 自动化规则(AI 分配、邮件/WhatsApp 转人工)。 验收:AI 能基于帮助中心回答并带引用;越界/复杂问题按 fallback_team 转人工;OTP 流程能发码、验码(先用 livechat 访客验证)。 ### P2 瘦身 bridge(0.5–1d) - **新建目录 `bridge-tools/`(从 `crm-new/bridge` 裁剪,不改 crm-new 本身)**,保留: `server.js`(只留工具路由 + healthz)、`tools.js`(裁剪)、`rpc.js`、`product-query.js`、`sitemap.js`、`opportunity.js` / `twenty.js`(若保留)、`redis.js`、`auth.js`、`config.js`、`security.js` + 对应测试; - 删除:agent.js、prompts.js、llm*.js、rag.js、kb-*.js、embedding.js、reranker.js、verification.js、smtp.js、identity.js、jwt.js、libredesk-webhook.js、metrics/quality/citation-checker/output-guard/flywheel/audit/experiments/trace 等; - 依赖精简:PG 可去掉(若不做 lead/质量库),Redis 保留(RPC 缓存/限流); - 单测裁剪后必须 `npm test` 通过。 验收:`/healthz` 正常;5 个工具逐个用 curl + shared key 调通;容器内存/镜像明显变小。 ### P3 工具注册到 LibreDesk(2–4h) - 适配 `register-tools.js`:URL 指向 `bridge-tools:4100`,`auth` 带 shared key header; - `search_orders` / `create_opportunity` 设 `requires_verification=true`; - 绑定 assistant 的 tool allowlist; - 多站点:`X-Libredesk-Inbox-Id` 映射 sites.json(不需要改协议,LibreDesk 已经带)。 验收:livechat 里问「查订单」→ 触发 OTP → 验码后返回订单;问商品 → 返回价格/库存/链接。 ### P4 渠道(2–4h) - Live Chat inbox + widget(站点用 inbox secret 签 JWT 做身份锚定); - Email inbox(决定用 163 走 imap-proxy,还是换企业邮箱直连); - WhatsApp(依赖公网域名/隧道,单独排期)。 ### P5 公网/运维/质量(按需) - 固定域名 + 证书 + public-gateway 白名单; - 备份定时化、监控、smoke/e2e、上线文档; - 若需要质量护栏:LibreDesk webhook → 轻量质量服务(不改 AI 回复,只记指标)。 ## 5. 风险与前提 - **SMTP 必须可用**:内置 OTP 依赖通知邮箱,livechat 访客验证走它;没有就会卡住「查订单」这类工具。 - **embedding provider 必须配**:内置 KB 检索是向量检索,缺 key 时 `search_knowledge_base` 不可用。 - **RPC 网络**:bridge-tools 仍需要访问 yehwang RPC(crm-new 是靠外部网络 `spug-net`),新 compose 要接同一网络或走隧道。 - **内置 OTP 的边界**:只对「email 渠道会话」或「非 contact 类型联系人(访客)」提供;已存在且非访客的 contact 不会自动有 OTP 工具(`worker.go:308`),要确认业务场景。 - **检索质量下降**:内置 top-k vs 旧 hybrid;上线前用 20–30 个真实问题对比命中率。 - **两套并存**:bridge-tools 与 crm-new bridge 可共用 RPC/Redis 配置,但建议独立 redis db 和独立 shared key。 ## 6. 需要拍板 1. `create_opportunity` / Twenty 商机要不要保留?(决定 bridge 留 3 个还是 5 个工具) 2. `search_email_history`、`collect_info` 先删还是保留? 3. 程序化输出护栏:先接受降级,还是一开始就按 webhook 方案补? 4. bridge-tools 部署位置:同一台机新 compose,还是并到本实例 compose?