# LibreDesk 后台配置步骤 > 面向 `crm-new` 全栈(方案 B:LibreDesk 内置 AI 回复客户)。 > 本栈已通过 `scripts/setup-defaults.js` 自动建好 Inbox / Assistant / Automation;本文用于手工核对或重建。 > 登录:用户 `System`,密码见 `.env` 的 `LIBREDESK_SYSTEM_USER_PASSWORD`。 ## 0. 前置检查 ```bash bash scripts/bootstrap.sh # LibreDesk 已启动 bash scripts/start-tools.sh # 另开终端,tools 服务 :4010 curl -s http://localhost:4100/healthz ``` ## 1. AI Provider(必须先配) `Admin → AI → Providers`,两个 provider 都要配(LibreDesk 要求 OpenAI 兼容端点): | 项 | Completion | Embedding | |---|---|---| | Base URL | `https://dashscope.aliyuncs.com/compatible-mode/v1` | 同左 | | API Key | DashScope key(与旧项目 `kb.config.json` 同一个) | 同左 | | Model | `qwen-plus-latest` | `text-embedding-v4` | | Dimensions | — | **1024**(必须与模型输出一致,否则报维度不匹配) | | Temperature | 0.3 | — | | Max tokens | 800 | — | 点 **Test connection** 两个都通过再继续。改 embedding 模型/维度会自动重新嵌入全部 snippets。 成本上限在 `config/config.toml` 的 `[ai_agent]`:`max_steps`、`max_history_messages`、`worker_count`。 ## 2. 知识库(帮助中心文章) 本栈已把旧 `customer-service-kb` 导入为**帮助中心文章**(而不是 snippets),原因:只有文章能被 AI 引用(`[[cite:id]]`),并且同时进入帮助中心站内搜索。 公开地址:`http://localhost:9000/hc/yehwang-help/en`(1 个帮助中心 / 9 个 collection / 108 篇文章,全部 `published + ai_enabled`)。 重新导入(幂等): ```bash cd /home/dev/code/crm-new node scripts/import-kb-helpcenter.js --dry-run # 只解析 node scripts/import-kb-helpcenter.js # 登录 System 并导入 ``` 以下为 LibreDesk 原生 snippets 的用法(内部/敏感内容才用): 1. **手工**:一条 Q&A 一个 snippet,正文写完整答案(不要写片段) 2. **Import from URL**:抓取官网 FAQ 页面 3. **API 批量导入**(迁移旧 KB 时用): ```bash curl -X POST http://localhost:9000/api/v1/ai/snippets \ -H "Authorization: token ${LIBREDESK_API_KEY}:${LIBREDESK_API_SECRET}" \ -H 'Content-Type: application/json' \ -d '{"title":"Minimum order","content":"The minimum order value is €30.","enabled":true}' ``` 迁移建议:旧 `customer-service-kb/*.md` 按 `### Q:` 切块,标题用问题,正文用答案,逐条 POST。Import from URL 走 `POST /api/v1/ai/snippets/import-url`。 > RAG 差异:LibreDesk 是 **纯向量 top-k**,没有旧 bridge 的「向量+全文+RRF+rerank+翻译兜底」。EU 语种召回需要用真实问题抽检。 ## 3. 注册业务工具 ### 方式 A:自动(推荐) 1. `Admin → Teammates → System → API Key` 生成 key/secret,填进 `.env`: ``` LIBREDESK_API_KEY=... LIBREDESK_API_SECRET=... ``` 2. 执行: ```bash node scripts/register-tools.js ``` ### 方式 B:手工 `Admin → AI → Tools → New tool`,4 个工具按下面填: | 字段 | search_products | search_orders | search_inventory | create_opportunity | |---|---|---|---|---| | URL | `http://bridge:4100/tools/search_products` | `.../search_orders` | `.../search_inventory` | `.../create_opportunity` | | Method | POST | POST | POST | POST | | Header | `X-Tools-Key: ` | 同 | 同 | 同 | | Parameters | 见 `GET /tools/manifest` | 同 | 同 | 同 | | Require verified contact | 否 | **是** | 否 | **是** | | Copilot / Generate reply | 开 | 开 | 开 | 开 | | Require agent approval | 否 | 否 | 否 | 否 | `GET http://localhost:4100/tools/manifest`(带 `X-Tools-Key`)会输出每个工具的完整 JSON Schema,可直接复制。 ## 4. 创建 AI Assistant `Admin → AI → Assistants → New assistant`: | 项 | 建议值 | |---|---| | Name | `Yehwang Assistant` | | Tone / Length | Friendly / Concise | | Languages | English, Dutch, German, French, Spanish, Italian(留空=跟随客户) | | Max turns | 8–10 | | Fallback team | `Support`(先建团队) | | Offer handoff | 开 | | Tools | 勾选上一步的 4 个工具 | **Instructions 草稿(可直接改)**: ``` You are the Yehwang B2B customer assistant for stainless-steel jewelry wholesale. - Always reply in the customer's language. - For product questions call search_products; never invent catalog items. - For order questions call search_orders. If the result says verification is required, ask the customer to verify their email with the one-time code, then retry. - For stock questions call search_inventory with the SKU digits. - When you have company + contact name + product/need, call create_opportunity once. - Never quote prices, discounts or stock that did not come from a tool result. - If you cannot help or the customer asks for a human, hand off to the Support team. ``` **Guardrails**: ``` Never reveal another customer's data. Never promise discounts above the published tiers. Never create an opportunity before the contact is verified. ``` > AI Assistant 目前是 **beta**,官方建议先在低流量 inbox 验证。 ## 5. 自动路由(关键) Assistant **只有被分配给会话才会回复**。配置: `Admin → Automations → New rule` - 触发:`new_conversation` - 条件:`inbox = Live chat`(如需只处理工作时间,再加 business hours 条件) - 动作:`assign_user` → `Yehwang Assistant` 可选第二条规则:`conversation_update` + `status = Resolved` → 发送 CSAT。 人工一旦在会话里回复,assistant 会自动 handoff 并取消分配。 ## 6. Live Chat Inbox 与 Widget 1. `Admin → Inboxes → New inbox → Live chat` - Name:`Website` - Brand / Website URL:`https://www.yehwang.com` 2. **Security** 标签:生成 widget **Secret key**(用于签 JWT,绝不能放前端) 3. **Installation** 标签复制 snippet: ```html ``` ### 登录用户身份锚定(已实现) bridge 提供 `POST /identity`:站点 JWT → member RPC 取邮箱 → 用 inbox secret 签 LibreDesk widget JWT。 本地 POC 也可用 `IDENTITY_DEV_MODE=true` 直接传 email 生成。前端拿到 `userJWT` 后传给 widget。 ### 原始说明(LibreDesk 侧) 已在网站登录的客户,服务端用 inbox Secret 签 HS256 JWT 传给 `userJWT`: ```js // 服务端(Node 示例,密钥只在服务端) const payload = { external_user_id: String(user.id), // 与旧栈 yw_uid 对齐 email: user.email, // 这才是可信邮箱 first_name: user.firstName, last_name: user.lastName, contact_custom_attributes: { site: 'www', locale: user.locale }, exp: Math.floor(Date.now() / 1000) + 3600 }; // HS256(payload, inboxSecret) → window.LibredeskSettings.userJWT ``` 多站点(www / US)建两个 livechat inbox,各自 widget + secret;联系人按 email 全局共享,注意隐私口径。 参考 `us-site/ai-snippet.js`(旧栈 Chatwoot 版)需要改写的点:`$chatwoot.setUser` → `userJWT`,`setCustomAttributes` → `contact_custom_attributes`。 ## 7. Email Inbox(可选) `Admin → Inboxes → New inbox → Other provider`: | 项 | 值 | |---|---| | IMAP | `imap.163.com:993`,SSL/TLS | | SMTP | `smtp.163.com:465`,SSL | | 用户名/密码 | 163 邮箱 + 授权码 | | Scan interval | `5m`(默认) | 接完后旧桥的 `bridge/mail/`(IMAP 轮询 + 自动回复)可以退役;邮件摘要改为定时调 LibreDesk 报表 API。 ## 8. WhatsApp(v2.9.0 已可用) > **版本现状**:本套已运行 `v2.9.0` 正式版(2026-10-22 发布,2026-10-26 从 rc.10 升级),`channels` 枚举为 `email / livechat / whatsapp`,`whatsapp_templates` 表已就绪。 > 升级前已 `pg_dump` 备份;本次无 DB migration,回滚见 `docs/runbook.md`「回滚」。 1. Meta 侧准备:Business Account、WABA ID、Phone Number ID、Permanent Access Token、App Secret、Webhook Verify Token 2. `Admin → Inboxes → New inbox → WhatsApp`,填上述凭据 3. Meta App 的 Webhook 指向 `https://你的域名/webhooks/whatsapp`(以实际路由为准),订阅 `messages` 4. 模板:`whatsapp_templates` 表 + 后台模板管理;24 小时窗口外的主动消息必须用已审核模板 5. **AI 对 WhatsApp 的支持文档未覆盖**(文档只写 email + live chat),需实测 assistant 是否在 WhatsApp 会话触发 切换镜像:`.env` 里改 `LIBREDESK_IMAGE` 后 `docker compose up -d --force-recreate libredesk`;升级前先 `pg_dump` 备份,并记录当前镜像 digest 便于回滚。 ## 9. 验收清单 - [ ] `Admin → AI → Providers` 两个 Test connection 通过 - [ ] Snippets 至少 10 条,问一个政策问题能引用 - [ ] Tools 4 个,`crm-tools` 日志能看到调用 - [ ] Assistant 已建 + automation 已分配 - [ ] widget 能开聊,收到 AI 回复 - [ ] 未验证时问订单 → AI 引导验证;验证后能查单 - [ ] 说“我要人工” → handoff 到 Support 团队 - [ ] `curl -s http://localhost:4100/healthz` 正常 ## 10. 常见问题 | 现象 | 原因 | 处理 | |---|---|---| | 登录后立刻掉登录 | 用 http 访问但 cookie 是 Secure | `config.toml` 里 `disable_secure_cookies = true` | | 容器反复重启,日志提示 `system user password is not strong` | System 密码不满足规则(10–72 位,含大小写+数字+特殊字符) | 改 `.env` 的 `LIBREDESK_SYSTEM_USER_PASSWORD`,再 `docker compose up -d --force-recreate app` | | 工具 401 | `X-Tools-Key` 与 `TOOLS_SHARED_KEY` 不一致 | 核对 `.env` 和工具 Header | | 工具 403 verification_required | 未验证联系人 / 工具未开验证 | 先走 OTP 验证,或该工具不需要验证则关掉 `requires_verification` | | 工具 503 tools_key_not_configured | tools 服务未配置共享密钥 | 重启 `start-tools.sh` | | AI 不回复 | 会话未分配给 assistant / 会话不是 open | 检查 automation 规则与状态 | | embedding 维度报错 | dimensions 与模型不符 | `text-embedding-v4` 用 1024 | | 容器访问不了 tools | `host.docker.internal` 未解析 | compose 已配 `extra_hosts`;Linux 需 Docker 20.10+ |