全部文档

嵌入智能体接入指南

- 在 Cadau 创建/选定嵌入用智能体,确定 app_id

来源 sdk/host-embed/参考范例-HR接入指南.md

文档用途

本文是 第三方业务系统(ERP、OA、行业 SaaS 等)接入 Cadau 网站嵌入助手自包含改造手册

目标读者为 宿主系统的开发人员与管理人员:仅阅读本文并完成文内清单,即可在自有系统中完成「登记智能体 → 按用户分配 → 页面挂载对话助手 → 联调验收」,无需先通读 Cadau 全站文档或 HR 范例全部源码。

>

第三方完整手册README.md(总览);本文是 HR 范例 的改造对照手册。

- HR 范例现状:已 仅走 B 路径server/.envMINDLINK_* + embed-session);不再使用 web/.env.local 静态 token。本期整套宿主共用 一个 Cadau 工作区(多个 HR 租户也登记到同一区)。「一租户一区」见 宿主增强-AgentRun与数据权限.md §0.3,暂不实现

- Cadau 产品通用细节(挂件参数全集、SSE 协议、错误码):见 网站集成说明.mdSDK契约.md(V1.5.12)。

- 可运行参考实现:Cadau 仓库 examples/hr-multi-tenant(人力资源多租户范例);下文称 「HR 范例」,路径与表名以该范例为准,你的系统应映射为自有命名


0. 快速结论(给决策者)

问题答案
登记智能体时要填 embed token 吗?不要。只登记 Cadau 智能体 ID;token 由静态配置(A)或服务端代签(B)提供。
每个智能体要单独在 Cadau 生成令牌吗?不要。B 路径下一套集成账号即可;按用户分配在运行时换 token。
生产推荐哪种方式?B(服务端代签);A 仅用于本地联调或应急兜底。
Cadau 要存我们的用户吗?不要。用户与权限在宿主;Cadau 只提供智能体与对话。B 路径用 host_actor 标明当前登录用户,历史会话 / 人工客服 / 工单按此人隔离。传软查数见 宿主增强-AgentRun与数据权限.md §0。
同一电脑两人登录会串话吗?不会(B 路径须把当前登录用户身份传入挂件)。用户甲看不到乙的历史会话、人工客服与工单。
只接嵌入、不改业务后端行吗?A 路径可以(令牌不进后端);B 路径不行(必须有宿主 BFF 代签接口)。
人工客服 / 工单要在宿主自建吗?不要。与静态网站同一套挂件;在 Cadau 开启人工客服即可。
宿主原来直连大模型怎么办?改为请 指定智能体 代答(服务端调用,用户可看不见挂件)。见 宿主LLM服务.md
宿主多个客户共用一个 Cadau 工作区可以吗?可以,而且本期只做这一种。 人与人靠当前登录用户身份隔离;客服工作台仍是工作区一份。「一租户一区」以后需要再完善,见 宿主增强-AgentRun与数据权限.md §0.3。

1. 读完本文你将完成什么

1.1 管理人员

  • 在 Cadau 创建/选定嵌入用智能体,确定 app_id
  • 在宿主管理界面 登记 可接入的智能体(名称 + 智能体 ID)
  • 登录用户(非业务档案 id,如非员工 id)分配 智能体与操作权限(查询 / 新增 / 编辑 / 删除)
  • 配置宿主服务端 Cadau 集成账号(B 路径,一套即可)
  • §12 验收清单 确认助手可用

1.2 开发人员

  • 在宿主库中增加 登记表 + 用户分配表(或等价模块)
  • 实现 嵌入会话接口(如 GET .../me/embed-session),内部代调 Cadau embed-token
  • 在前端业务页 加载挂件脚本并 init;监听 功能导航 动作(可选)
  • (可选)在 Cadau 为该智能体开启 人工客服(本区座席或授权客服小组)——挂件会自行出现「人工客服 / 提交工单」,不必在宿主再做一套客服后台
  • (可选)实现 任务型 接口:在 Cadau 配好智能体后,用 .env 或宿主设置指定,服务端代答、页面先预览再落库(范例:按部门建议岗位)
  • 配置 网络(同域代理或 CORS)、密钥(集成密码仅服务端)
  • 按路径 A 或 B 完成联调与上线

2. 架构:谁管什么

flowchart LR
  subgraph Host["第三方宿主系统"]
    U["登录用户"]
    ADM["管理员:登记 + 分配"]
    BFF["宿主 BFF:embed-session 代签"]
    UI["业务前端 + 嵌入挂件"]
    U --> UI
    ADM --> DB[(登记与分配)]
    BFF --> DB
    UI --> BFF
  end

  subgraph ML["Cadau"]
    UA["用户智能体"]
    CHAT["对话 / 知识"]
    ET["embed-token API"]
    UA --> CHAT
    ET --> UA
  end

  BFF -->|"集成账号调用"| ET
  UI -->|"embed token 对话"| CHAT
一方负责什么不负责什么
Cadau智能体、对话、知识索引、embed-token 签发、嵌入挂件脚本宿主业务用户 id、宿主权限、宿主业务 API
宿主(你)登录用户、登记多条 Cadau 智能体、按用户分配、代签短期 token、页面挂载与导航在 Cadau 内维护「按宿主用户登记」类 API

与宿主 HTTP API 密钥的关系:API 密钥管 机器调用宿主业务接口;嵌入管 页面内对话用哪条智能体。二者独立配置。


3. 概念映射:你的系统 ↔ HR 范例

改造时把 HR 范例当作 对照样例,概念映射如下:

通用概念(你的系统)HR 范例中的叫法说明
宿主登录用户hr_users(手机号)分配智能体的主体;不是员工档案 id
租户 / 组织 / 账套tenants(工作区)登记与分配按租户隔离
登记接入智能体hr_mindlink_agents存显示名、Cadau 智能体 ID、app_id;对话助手按角色分配。生成/分析另在 .env 或「嵌入助手登记」指定一条
用户智能体分配hr_user_agent_assignments登录用户 → 登记记录 + 操作权限
嵌入会话 BFFGET .../me/embed-session读分配 → 代签 → 返回挂件所需字段
静态联调配置web/.env.localVITE_MINDLINK_*第三方可选 AHR 范例已弃用,仅 B
服务端 Cadau 对接server/.envMINDLINK_*B 路径集成账号与 URL

4. 两种接入路径:A 与 B

4.1 对比

维度A:静态联调B:服务端代签(推荐生产)
token 来源配置文件/环境变量中 预先写入用户打开页面时 宿主 BFF 现签
是否经过宿主后端(浏览器直连 Cadau)
能否每人不同智能体通常全员共用一条配置可以
Cadau UI 是否要点「生成令牌」(或脚本代劳)不要
宿主是否要开发 BFF(至少 embed-session)

4.2 如何选择

需要按登录用户切换不同智能体?
  ├─ 是 → B
  └─ 否 → 仅联调 / 演示 → 可先用 A;上线仍建议 B

token 能否出现在前端构建产物或公开仓库?
  ├─ 不能 → B(或 A 仅 dev 环境)
  └─ 可以(仅内网 dev)→ A 可接受

宿主已有登录与权限体系?
  ├─ 是 → B,分配逻辑挂在你的用户 id 上
  └─ 否 → 先 A 验证挂件;再补登录 + B

4.3 「代签」含义

代签 = 宿主服务端用 Cadau 集成账号 调用 POST /api/v1/user-agents/{智能体ID}/embed-token 取得 短期 embed token,再下发给浏览器。用户 登录 Cadau 主站,浏览器 保存 Cadau 密码。

4.4 HR 范例与 A + B 策略

HR 范例(本仓库):前端 仅 B 路径——登录后请求 embed-session,未分配则不挂载助手;不再回退 A 或读取 web/.env.local

其它第三方宿主(可借鉴):

  1. 用户 未分配 智能体 → 可不请求 embed-session,或尝试 A(仅 dev)
  2. 用户 已分配 → 请求 B
  3. B 成功 → 用 B;B 失败 → 回退 A(仅建议开发环境

生产环境建议:全员分配 + 仅 B,去掉 A 的长期 token。


5. Cadau 侧准备(管理员)

在改造宿主之前,在 Cadau 完成:

步骤操作产出
1创建或选定 用户智能体(绑定知识文档)智能体 ID(UUID)
2确定 app_id(区分接入方,如 your-corp-hr与宿主登记、代签请求一致
3准备 集成用 Cadau 账号(B 路径)邮箱/密码;须为智能体 所在工作区的成员不必拥有该智能体)
4将集成账号 邀请/加入 智能体所在工作区代签前可 switch 进该工作区;生产在 Cadau UI 邀请,本地联调见 §7.3
5确认对外 URL挂件脚本 URL、API 前缀 /api/v1
6(可选)我的智能体 → 管理 → 人工客服:开启,并指定本区 客服席位 或授权 客服小组挂件出现「人工客服 / 提交工单」;客服在 Cadau 客服工作台 处理(与静态网站嵌入同一套)
7(A 路径,第三方可选)该助手 管理 → 网站嵌入 → 生成令牌access_tokenexpires_at

B 路径不需要在 Cadau UI 为每个用户或每个智能体重复「生成令牌」;代签与 UI 按钮调用同一 API。 人工客服 / 工单也不需要宿主再签一类专用令牌:embed-session 下发的嵌入令牌与静态站粘贴的令牌,对挂件客服接口权限相同。

知识文档:为嵌入智能体挂载 宿主业务说明(菜单、边界、功能导航约定)。HR 范例见 docs/宿主知识文档/


6. 宿主系统改造清单(开发)

6.1 数据层(必做,B 路径)

至少两张表(名称可自定):

登记接入智能体

字段说明
id宿主内部主键
tenant_id租户隔离
label显示名称
mindlink_user_agent_idCadau 智能体 UUID
app_id默认与全局配置一致
mindlink_workspace_id建议填写智能体所在 Cadau 工作区 UUID(本期与 MINDLINK_WORKSPACE_ID 相同)。代签时优先用此值 switch
statusactive / 停用

用户智能体分配

字段说明
tenant_id + user_id唯一;user_id = 宿主登录用户 id
agent_id指向登记记录
scopes_json助手操作权限(宿主自定义枚举,HR 范例见 §8.3)
user_label可选,展示用

HR 范例权限枚举:按 功能模块 × 操作 二维配置,键为 module.permission(如 employees.query)。操作含查询、新增、编辑、删除;编辑、删除 因大模型幻觉存在误操作风险,界面有安全注明,默认不开通。

6.2 管理功能(必做,B 路径)

管理员在宿主 UI 或通过 API 完成:

  1. 登记 Cadau 智能体(名称 + 智能体 ID + app_id)— 不含 token
  2. 分配 给登录用户:选登记记录 + 勾选操作权限(至少一项;默认仅开通查询)

HR 范例入口:侧栏 「用户管理」(工作区管理员)。运维可选 「外部访问授权 → 用户智能体」(跨租户令牌)。

6.3 嵌入会话 BFF(必做,B 路径)

实现类似:

GET /api/v1/tenants/{tenantId}/me/embed-session 请求头:Authorization: Bearer <宿主登录 JWT>

服务端逻辑:

  1. 解析当前登录用户
  2. 查该租户下是否有 active 分配
  3. 无分配 → 200 + { "available": false, "reason": "..." }勿用 404,避免浏览器误报)
  4. 有分配 → 用 MINDLINK_INTEGRATION_* 登录 Cadau → 按登记记录的 mindlink_workspace_id(若有)或 MINDLINK_WORKSPACE_ID POST /workspaces/{id}/switch

POST /api/v1/user-agents/{mindlink_user_agent_id}/embed-token body: { "app_id": "...", "ttl_seconds": 3600 } (Cadau 要求:集成账号为该工作区成员;智能体须在该工作区内,不要求归集成账号所有)

  1. 返回挂件所需字段(见 §9.2)

集成账号与 URL 仅存在于服务端环境变量,不得写入前端仓库。

6.4 前端挂载(必做)

  1. 用户进入需展示助手的页面
  2. (B)带宿主 JWT 请求 embed-session;或(A)读静态配置
  3. 动态加载 widget_script
  4. 调用 window.MindLinkWidget.init({ app_id, api_base_url, user_agent_id, workspace_id, auth: { token, expires_at }, ... })
  5. 监听 widget.on("action", ...) 处理 功能导航(见 §10)
  6. token 将过期时,由 BFF 刷新并 widget.updateAuth({ token, expires_at })(过期不续签时,挂件里的人工客服 / 工单请求会 401)
  7. 不必为人工客服或工单另写宿主 API;见 §10.4

HR 范例参考:web/src/mindlinkOrgEmbed.tsweb/src/mindlinkHostActions.ts

6.5 网络(必做)

  • 浏览器访问 Cadau API 需 同域反向代理CORS 允许
  • 开发范例(web/vite.config.ts):

- /mindlink-api → Cadau :8080/api(挂件对话 API) - /mindlink-embed → Cadau :8080(挂件脚本 /embed/mindlink-widget.min.js

  • 前端 api_base_url / widget_script 宜与浏览器地址栏同源(如统一 http://localhost:5180),避免 localhost127.0.0.1 混用导致跨源失败
  • 生产:宿主域名下配置 /mindlink-api(及脚本路径)→ Cadau 网关

7. 配置项一览

7.1 服务端环境变量(B 路径,宿主后端 .env

MINDLINK_API_BASE=https://mindlink.example.com/api/v1
MINDLINK_API_BASE_PUBLIC=https://your-host.example.com/mindlink-api/v1
MINDLINK_WIDGET_SCRIPT=https://mindlink.example.com/embed/mindlink-widget.min.js
MINDLINK_INTEGRATION_EMAIL=integration@your-corp.com
MINDLINK_INTEGRATION_PHONE=
MINDLINK_INTEGRATION_PASSWORD=<仅服务端>
MINDLINK_APP_ID=your-corp-app
MINDLINK_WORKSPACE_ID=
MINDLINK_GENERATE_USER_AGENT_ID=
# 以下两项仅 HR 范例本地演示种子,生产不要依赖
# HRMS_SEED_MINDLINK_USER_AGENT_ID=
# HRMS_SEED_MINDLINK_DEMO=0
变量作用
MINDLINK_API_BASE宿主 服务端 调 Cadau(代签 / 代跑)
MINDLINK_API_BASE_PUBLIC浏览器 调 Cadau(经宿主代理的对外 URL)
MINDLINK_WIDGET_SCRIPT挂件脚本地址
MINDLINK_INTEGRATION_EMAIL / PHONE代签用 Cadau 账号(邮箱或手机号二选一),一套服务所有登记智能体
MINDLINK_INTEGRATION_PASSWORD集成账号密码,仅服务端
MINDLINK_APP_ID页面挂件默认 app_id;登记记录可覆盖
MINDLINK_WORKSPACE_ID本期整套宿主共用的 Cadau 工作区
MINDLINK_GENERATE_USER_AGENT_ID生成/分析(如建议岗位)调用的 Cadau 智能体 UUID。须先在 Cadau 配好。「嵌入助手登记」里指定后覆盖此项。不是页面挂件用的助手
HRMS_SEED_MINDLINK_USER_AGENT_ID仅演示种子。人事服务启动时,把该 UUID 登记进 DEMO 工作区并分给演示账号,便于本地一登录就有右下角助手。日常对话 / 代签 不读 这一项(读的是「用户管理」里的分配)。已跑过 setup:hr-work-agents、成员已有分配后可留空或删除。与 MINDLINK_GENERATE_USER_AGENT_ID 无关
HRMS_SEED_MINDLINK_DEMO设为 0 关闭上述演示种子

MINDLINK_EMBED_TTL_SECONDSMINDLINK_WIDGET_INLINE 有代码默认值(3600 秒、浮动挂件),不必写进 .env

7.2 前端静态配置(A 路径:通用第三方可用;HR 范例已弃用

HR 范例前端 不再 读取 VITE_MINDLINK_* / web/.env.local;以下仅供其他系统本地静态联调参考。

VITE_MINDLINK_WIDGET_SCRIPT=...
VITE_MINDLINK_API_BASE_URL=...
VITE_MINDLINK_APP_ID=...
VITE_MINDLINK_USER_AGENT_ID=<Cadau 智能体 UUID>
VITE_MINDLINK_EMBED_TOKEN=<嵌入令牌,勿提交仓库>
VITE_MINDLINK_TOKEN_EXPIRES_AT=...
VITE_MINDLINK_WORKSPACE_ID=...

7.3 智能体 ID、集成账号与本地联调脚本

方式说明
Cadau UI该助手 管理 → 网站嵌入
Cadau APIGET /api/v1/user-agents
HR 范例:写服务端 .envweb 目录 npm run setup:mindlink(或 node scripts/write-mindlink-env.mjs

setup:mindlink 会做什么

  1. 调用 Cadau POST /api/v1/auth/register 注册集成账号 hr-embed-demo@mindlink.local / MindLink-HR-demo-2026(若已存在则改 POST /api/v1/auth/login;脚本默认 API_BASE=…/api/v1
  2. 探测或创建可用工作区,读取工作区内智能体 ID
  3. MINDLINK_* 写入 ../server/.env;并写入 HRMS_SEED_MINDLINK_USER_AGENT_ID(取到的工作智能体 UUID),供人事服务启动时给 DEMO 演示账号做一次性登记/分配。这不是运行时挂件配置;生产请在宿主「用户管理」登记并分配,不必依赖此项。

因此 无需手工在 Cadau 创建该邮箱;生产环境请 自建专用集成账号,勿用范例演示邮箱。

方式说明
HR 范例:接入已有智能体web 目录 npm run link:mindlink-agent -- <MindLink智能体UUID>:修正登记表 mindlink_workspace_id、(SQLite 主库时)将集成账号加入该工作区、验证 embed-token
HR 范例:工作智能体web 目录 npm run setup:hr-work-agents:三档对话助手。生成/分析智能体在 Cadau 配好后写入 MINDLINK_GENERATE_USER_AGENT_ID,或在「嵌入助手登记」指定

登记智能体时若工作区与 MINDLINK_WORKSPACE_ID 不同,务必填写 mindlink_workspace_id 或运行 link:mindlink-agent,否则 embed-session 可能 502。

Postgres 主库:Cadau 本地若使用 Postgres(非 backend/mindlink.db),link:mindlink-agent 可能报「智能体不存在」。请在 Cadau UI 邀请集成账号进工作区,或重跑 setup:mindlink;并核对 HR 登记表与 .env 中的工作区 / 智能体 ID 一致。

自动化冒烟web 目录,HR 与 Cadau 后端均已启动):

命令用途
npm run smoke:embed嵌入 B 路径:登录 → embed-session → Cadau 对话
npm run smoke:host-agent传软增强:host_actor、access policy 编译、agent-run 会话隔离

详见 README.md §8.1;完整手工项见仓库 examples/hr-multi-tenant/docs/ACCEPTANCE_HOST_LEGACY.md


8. 管理操作(HR 范例对照)

以下在 HR 范例 中验证;你的系统应提供等价界面或 API。

8.1 前置

  • Cadau 运行中
  • 宿主后端、前端运行中
  • 工作区 管理员 已登录(演示:13800138000 / Demo-HR-2026

8.2 登记智能体

路径:工作区 → 用户管理嵌入助手登记

推荐:点 「从 Cadau 同步」。宿主服务端用集成账号调用 Cadau GET /api/v1/user-agents?scope=workspace,把当前 MINDLINK_WORKSPACE_ID(或登记用工作区)内的智能体 upsert 到本租户登记表(更新名称与工作区;不会自动停用本地已有、但本次未出现的登记)。

也可手工登记:

字段必填
显示名称
Cadau 智能体 ID
app_id否(默认 mindlink-embed-hr

API:POST /api/v1/tenants/{tenantId}/mindlink-agents/sync(需租户管理员;可选 body workspace_id / app_id)。

8.3 分配用户

用户管理 → 成员 配置智能体(齿轮)→ 选智能体 → 左侧选功能模块、右侧勾选操作权限 → 保存。

功能模块(与 HR 业务域一致):

模块 id界面名称
org_structure组织架构
employees人员
positions岗位与职级
employee_lifecycle入离调
competency胜任力
succession继任与梯队

每个模块下的操作权限

权限 id界面名称说明
query查询允许助手代查该模块数据;建议默认开通
create新增允许助手代发起该模块的新增类写入
edit编辑大模型可能产生幻觉;为数据安全,除非特殊用途勿开通
delete删除误删风险高;除非特殊用途勿开通

存储格式为扁平键 模块id.权限id(如 employees.query)。新建分配时 HR 范例默认仅 组织架构 · 查询 开通。


9. API 契约与示例

以下路径以 HR 范例为准;你的系统保持 语义等价 即可。

9.1 宿主用户登录

POST /api/v1/auth/login
Content-Type: application/json

{ "phone": "13800138000", "password": "Demo-HR-2026" }

响应含 access_token(宿主 JWT),后续租户 API 均需:

Authorization: Bearer <access_token>

9.2 嵌入会话(B 核心)

GET /api/v1/tenants/{tenantId}/me/embed-session
Authorization: Bearer <宿主 JWT>

未分配 — 200

{
  "available": false,
  "reason": "尚未为该用户分配智能体"
}

已分配且代签成功 — 200

{
  "available": true,
  "user_id": "...",
  "user_label": "演示管理员",
  "agent_id": "...",
  "agent_label": "HR 通用助手",
  "user_agent_id": "4b2819de-8fcf-432c-b1ee-5593c78d4e64",
  "workspace_id": "be02b465-de92-4e3f-9352-67ff37a51dc9",
  "app_id": "mindlink-embed-hr",
  "access_token": "<embed JWT>",
  "expires_at": "2026-05-21T12:00:00Z",
  "scopes": {
    "org_structure.query": true,
    "org_structure.create": true,
    "employees.query": true
  },
  "host_actor": {
    "external_user_id": "...",
    "actor_kind": "business",
    "display_name": "演示管理员",
    "tenant_external_id": "...",
    "roles": ["admin", "manager"],
    "managed_org_unit_ids": []
  },
  "widget_script": "http://127.0.0.1:8080/embed/mindlink-widget.min.js",
  "api_base_url": "http://127.0.0.1:5180/mindlink-api/v1",
  "widget_inline": false
}

前端将 access_tokenauth.tokenuser_agent_idapp_idapi_base_urlwidget_scripthost_actorMindLinkWidget.init。换票后续签时同步 updateAuthupdateHostActor。员工自助须带 employee_id;字段全集见 宿主增强-AgentRun与数据权限.md §0.1。挂件会自动带请求头 X-Host-External-User-Id(B:登录用户编号;A:浏览器访客标识)。

常见错误

HTTP含义
401未登录宿主
503宿主未配 MINDLINK_API_BASE
502代签失败(集成账号、智能体 id、app_id 等)

9.3 登记智能体(管理员)

POST /api/v1/tenants/{tenantId}/mindlink-agents
Authorization: Bearer <宿主 JWT>
Content-Type: application/json

{
  "label": "HR 通用助手",
  "mindlink_user_agent_id": "4b2819de-8fcf-432c-b1ee-5593c78d4e64",
  "app_id": "mindlink-embed-hr"
}

9.4 保存用户分配(管理员)

PUT /api/v1/tenants/{tenantId}/members/{userId}/agent-assignment
Authorization: Bearer <宿主 JWT>
Content-Type: application/json

{
  "agent_id": "<登记记录 id>",
  "scopes": {
    "org_structure.query": true,
    "org_structure.create": true,
    "employees.query": true,
    "employees.create": false,
    "employees.edit": false,
    "employees.delete": false
  }
}

9.5 成员资格(可选,用于前端优化)

GET /api/v1/tenants/{tenantId}/me/membership

响应含 is_adminhas_agent_assignment(已分配时可跳过不必要的 embed-session 失败重试)。

9.6 Cadau 代签 API(宿主服务端调用,非浏览器)

须先 切换工作区(JWT 内带 wid),再代签;不要依赖 X-Workspace-Id 请求头(HR 范例客户端见 mindlinkclient)。

POST /api/v1/auth/login
Content-Type: application/json

{ "email": "integration@your-corp.com", "password": "..." }
POST /api/v1/workspaces/{workspaceId}/switch
Authorization: Bearer <上一步 access_token>
POST /api/v1/user-agents/{mindlinkUserAgentId}/embed-token
Authorization: Bearer <switch 返回的 access_token>
Content-Type: application/json

{
  "app_id": "mindlink-embed-hr",
  "ttl_seconds": 3600
}

浏览器持 embed JWT 对话时,Cadau 按 工作区内智能体 + 令牌登记绑定的 user_agent_id 校验(集成账号无需拥有该智能体)。

9.7 任务型:按部门建议岗位(服务端代调,非挂件)

me/agent-run 不同:不走用户已分配的对话助手,而调用 已指定的生成/分析智能体,每次 fresh: true。结果只预览,不写入岗位库。

指定方式(二选一,设置页优先):

  1. server/.envMINDLINK_GENERATE_USER_AGENT_ID=<Cadau 智能体 UUID>
  2. 「用户管理 → 嵌入助手登记 → 生成与分析用智能体」

智能体须先在 Cadau 创建并加入工作区,再到本页登记后才能从下拉框选择。

GET /api/v1/tenants/{tenantId}/mindlink-generate-agent
Authorization: Bearer <宿主 JWT>
{
  "agent_id": "<登记记录 id,未用设置页指定时为空>",
  "mindlink_user_agent_id": "<Cadau 智能体 UUID>",
  "label": "…",
  "source": "tenant | env | none",
  "env_user_agent_id": "<.env 中的 UUID>"
}
PUT /api/v1/tenants/{tenantId}/mindlink-generate-agent
Authorization: Bearer <宿主 JWT>
Content-Type: application/json

{ "agent_id": "<已登记助手的登记记录 id;空字符串则回退 .env>" }

需工作区管理员。sourcetenant 表示设置页已指定;env 表示回退环境变量;none 表示尚未指定。

POST /api/v1/tenants/{tenantId}/positions/suggest-for-org
Authorization: Bearer <宿主 JWT>
Content-Type: application/json

{ "org_unit_id": "<部门 ID>" }

页面:「岗位与职级」→ 选定部门 → 建议本部门岗位。说明见 宿主LLM服务.md §5.1。

完整 API 列表见 HR 范例 HOST_USER_AGENTS.md


10. 前端挂载与功能导航

10.1 最小 init(与路径无关)

const widget = window.MindLinkWidget.init({
  app_id: session.app_id,
  api_base_url: session.api_base_url,
  user_agent_id: session.user_agent_id,
  workspace_id: session.workspace_id,
  auth: {
    token: session.access_token,
    expires_at: session.expires_at,
  },
  // B 路径必传:与 embed-session 返回的 host_actor 一致(历史/客服/工单隔离;传软查数)
  host_actor: session.host_actor,
  theme: "auto",
  position: "bottom-right",
  locale: "zh-CN",
  entry: { auto_open: false, auto_execute_navigation: true },
});

widget.on("action", (ev) => {
  if (ev.type !== "action" || !ev.action) return;
  // 解析 mindlink_action(emit_event),跳转宿主路由
});

// 续签示例:
// widget.updateAuth({ token, expires_at });
// widget.updateHostActor(session.host_actor);

范例实现见 examples/hr-multi-tenant/web/src/mindlinkOrgEmbed.ts

10.2 功能导航(可选但推荐)

在智能体 知识文档 中约定 Markdown 链接:

`打开组织架构`

宿主页 白名单 注册动作名并跳转(HR 范例:page.overviewpage.org 等,见 mindlinkHostActions.ts)。

10.3 挂件体验(与 Cadau 主站对齐)

嵌入挂件(mindlink-widget.min.js)已包含:多轮对话 右侧提问快速定位(悬停展开标题)、回复结束后 焦点回到输入框、浮动入口 贴边不跑出视口。第三方无需额外实现;升级 Cadau 提供的脚本即可。

10.4 人工客服与工单(与静态网站嵌入同一套)

静态官网(A 路径,如 examples/cadau-embed-site)把一段 script 贴进页面后,只要该智能体 开启了人工客服,挂件输入区旁就会出现 「人工客服」「提交工单」B 路径(服务端代签)用的是同一份挂件脚本,这两项 自动具备,宿主 不要再实现客服队列、留言线程或工单表。

| | 人工客服(即时) | 工单(异步) | |--|---------------------|------------------| | 用户期望 | 马上有人在线聊 | 留言后可离开,稍后查进度 | | 挂件入口 | 「人工客服」 | 「提交工单」;排队中可 「不等了,改提工单」 | | 何时可用 | 该智能体已开启人工客服,且至少一名覆盖该工作区的客服为 上班(本区席位,或已授权小组的队员在小组工作台点了上班) | 智能体已开启人工客服即可(无人上班时只保留此项) | | 客服在哪处理 | Cadau 工作台 即时客服 | Cadau 工作台 工单 |

文案上 不要把即时协助称作「工单」。机制对照:Cadau docs/core-mechanisms/人工客服.md工单.md

Cadau 侧(管理人员)

  1. 打开嵌入用的那条智能体 → 管理 → 人工客服 → 开启。指定本区成员为 客服席位 不勾本区人员、改为授权 客服小组(不是默认把管理员当成客服)。
  2. 客服打开 Cadau 顶栏 「客服」(本区席位或小组成员可见;否则从功能菜单进工作台),把自己状态调成 上班。小组成员接多个客户时,在工作台右侧切到 小组工作台 再点上班,不必切换顶栏当前工作区。
  3. 访客在宿主页提交后,工作台列表会更新(即时来单可有提示音);不必刷新整页。
  4. 关闭智能体的人工客服后,挂件不再显示这两项入口。

宿主侧(开发,B 路径)

  • embed-session 代签的 token 已可调用挂件内人工客服与工单;不必在宿主再做客服后台。
  • 把 embed-session 下发的 host_actor 传入 MindLinkWidget.init;换登录用户时 updateHostActor(或重新 init)。未传则同一浏览器里可能看到上一人的历史 / 客服 / 工单。
  • 前端照常 updateAuth 续签。令牌过期后挂件会停止空转请求(避免 401 刷屏);用户重新进入页面或完成续签后客服入口恢复。
  • B 路径(已登录宿主用户):历史会话、人工客服、工单按当前登录用户隔离——用户甲只能看到自己的,看不到乙的;换浏览器用同一账号仍是本人。
  • A 路径(网站未登录访客):按本浏览器隔离进行中请求。同一浏览器再打开仍是同一访客;换浏览器或清站点数据会变成新访客。
  • 座席回复在客户侧一律显示为 「客服」,不会露出座席手机号。
  • 客服同事在 Cadau 处理,不在 HR / 宿主后台。

联调建议:静态官网与 HR 范例 常常不是同一条智能体、也不是同一个工作区。静态范例站开了人工客服,不会自动出现在 HR「操作助手」上。须在 正在嵌入的那条(如管理员助手)上开启。本仓库 npm run setup:hr-work-agents 会给三档演示工作智能体开启人工客服,并以集成账号为席位、设为上班。处理来单时:本区席位请确认顶栏当前工作区就是该智能体所在区;若用 客服小组,在工作台右侧切到 小组工作台 即可看到已授权客户的队列,不要靠切换顶栏工作区。


11. 推荐实施顺序

11.1 阶段一:验证挂件(A,1~2 天)

  1. Cadau 部署可访问
  2. 生成 embed token(UI 或 write-mindlink-env.mjs
  3. 宿主任意页面静态 init,能对话
  4. 确认网络(代理/CORS)无报错

11.2 阶段二:宿主 BFF + 分配(B,主要改造)

  1. 建表 + 管理 API/UI(登记、分配)
  2. 实现 embed-session + 服务端 MINDLINK_*
  3. 前端改为登录后拉 embed-session 再 init
  4. 为测试用户完成分配

11.3 阶段三:生产

  1. 专用集成账号、短 TTL、HTTPS
  2. 生产构建 不含 A 路径长期 token
  3. 挂载宿主知识文档
  4. 完成 §12 验收

12. 验收清单

改造完成后逐项确认:

Cadau

  • [ ] 智能体已创建,知识文档已挂载
  • [ ] app_id 已确定并与宿主一致
  • [ ] B:集成账号可登录、已加入智能体工作区,并能代调 embed-token
  • [ ] 登记表 mindlink_workspace_id 与智能体实际工作区一致(或已运行 link:mindlink-agent
  • [ ] (可选)该智能体已开启 人工客服,并指定本区席位或授权客服小组;客服可在工作台切换 上班 / 休息中 / 下班

宿主后端

  • [ ] 登记、分配 API 可用
  • [ ] embed-session 对已分配用户返回 available: trueaccess_token
  • [ ] embed-session 对未分配用户返回 available: false(非 404)
  • [ ] MINDLINK_INTEGRATION_PASSWORD 未出现在前端或公开仓库

宿主前端

  • [ ] 登录后右下角(或指定容器)出现助手
  • [ ] 不同用户分配不同智能体时,对话身份正确(B)
  • [ ] (B)init 已传入 host_actor;两名登录用户互看不到对方的历史会话、人工客服与工单
  • [ ] 两名访客可同时提问并各自收到回复;过载时挂件提示「当前对话人数已达上限,请稍后再试」
  • [ ] token 过期前可刷新或重新进入页面可续签
  • [ ] (可选)点击回答内导航链接可跳转宿主页面
  • [ ] (可选)智能体已开人工客服时:挂件有 「人工客服」(须有人上班)与 「提交工单」;无人上班时只保留提交工单
  • [ ] (可选)访客提交后,Cadau 客服工作台 即时 / 工单列表无需整页刷新即可看到;挂件 我的工单 可查看进度

自动化(HR 范例,可选)

  • [ ] npm run smoke:embed 通过
  • [ ] (传软增强)npm run smoke:host-agent 通过

传软增强(若启用 Host Agent Run / 业务库查数)

  • [ ] embed-session / agent-run 含正确 host_actor(员工含 employee_id
  • [ ] Cadau 工作区数据连接 + access policy 已配置
  • [ ] 员工仅本人、主管字段裁剪、会话不串话(见 ACCEPTANCE_HOST_LEGACY.md
  • [ ] (可选)已指定生成/分析智能体(.envMINDLINK_GENERATE_USER_AGENT_ID 或「嵌入助手登记」);「岗位与职级」可生成岗位建议且 自动写入岗位库

安全与运维

  • [ ] 生产仅 B 或 A 仅 dev 环境
  • [ ] Cadau API 经宿主同域代理或合规 CORS
  • [ ] 吊销/轮换集成账号流程已文档化

13. 常见问题

现象排查
embed-session 404升级宿主后端;未分配应返回 200 + available:false
embed-session 502,正文含 embed-token / not_found / 智能体不存在集成账号未加入智能体工作区;登记表 mindlink_workspace_id 错误;Cadau UI 邀请集成账号,或(SQLite 主库)npm run link:mindlink-agent -- <智能体ID>,或重跑 setup:mindlink
link:mindlink-agent 报智能体不存在Cadau 主库为 Postgres 时脚本读不到 mindlink.db;改 UI 邀请 + 核对 .env,或只用 setup:mindlink
embed-session 502,无权切换工作区MINDLINK_WORKSPACE_ID 与集成账号可访问工作区不一致
助手出现但对话 400 invalid_user_agentCadau 版本过旧;须支持嵌入令牌访问工作区内(非仅「我的」)智能体
删了 HRMS_SEED_MINDLINK_USER_AGENT_ID 助手没了不会(成员已有分配时)。该项只在启动时给演示账号补登记;日常挂件读「用户管理」分配。生成/分析看 MINDLINK_GENERATE_USER_AGENT_ID 或「嵌入助手登记」
控制台 CORS / 连不上 Cadau APIapi_base_url 与页面 同源;开发勿混用 localhost127.0.0.1
控制台 401 embed-session宿主 JWT 未带或过期
A/B 助手行为不一致对齐同一 mindlink_user_agent_id
点「用户管理」登录失效租户 API 须带 Authorization: Bearer
是否每个智能体单独 token;登记 ID,代签时现换
挂件没有「人工客服 / 提交工单」正在嵌入的那条智能体未开启人工客服(静态站开过不等于 HR 助手已开);或看错了智能体 / 工作区
有「提交工单」但没有「人工客服」正常:当前没有覆盖该工作区的客服 上班;本区席位或已授权小组的队员到 Cadau 客服工作台点上班
访客已提交,客服页要刷新才看到确认 Cadau 后端已含客服实时推送;座席请保持工作台打开且已登录
挂件客服请求一直 401嵌入令牌过期未 updateAuth;检查 embed-session TTL 与续签
要不要在 HR 里做工单列表不要;工单在 Cadau 客服工作台,挂件内有「我的工单」
一组客服要接多个客户工作区用 Cadau 客服小组(本队建组、客户授权、列入服务范围);队员切 小组工作台,不要把他们加成每个客户区的成员
换账号仍看到上一用户的历史 / 客服 / 工单init 未传 host_actor,或换用户后未 updateHostActor;对照 §10.4

14. 相关文档与参考代码

资源说明
网站集成说明.mdCadau 通用嵌入、init、导航
SDK契约.md令牌、SSE、安全契约
README.md第三方接入总览
宿主LLM服务.md宿主服务端请指定智能体代答
宿主增强-AgentRun与数据权限.md传软用户模型、新传软检查单、数据连接策略
HR 范例 docs/HOST_LEGACY_INTEGRATION.md传软映射与 SQLite 联调(仓库内)
HR 范例 docs/ACCEPTANCE_HOST_LEGACY.md传软增强手工验收(仓库内)
HR 范例 docs/HOST_USER_AGENTS.mdHR 范例 API 与表结构摘要(仓库内)
HR 范例 docs/宿主知识文档/00-总则与功能导航.md助手回答边界(HR 范例)
examples/hr-multi-tenant/web/src/mindlinkOrgEmbed.tsB 路径加载与挂载
examples/hr-multi-tenant/web/scripts/setup-hr-work-agents.mjs三档对话助手
examples/hr-multi-tenant/web/scripts/link-mindlink-agent.mjs本地接入已有 Cadau 智能体
examples/hr-multi-tenant/server/internal/mindlinkclient/代签客户端
examples/hr-multi-tenant/server/.env.example环境变量模板

15. 维护信息

文档类型第三方宿主改造手册
参考实现examples/hr-multi-tenant
文档版本2026-08-17(对齐 SDK 契约 V1.5.12)
HR 范例默认 app_id对话 mindlink-embed-hr;生成任务 mindlink-embed-hr-generate