传软接入 Cadau:架构、原理与实战教程
把助手嵌进已有的人事或 OA 系统:人仍在原系统登录办事,不必为每位员工再开一个账号。
来源 docs/技术博客/传软接入MindLink架构与实战教程.md
表述:本文面向 传软(旧有业务系统)的架构师与后端/前端开发,说明如何把 Cadau 工作智能体 嵌入 ERP、OA、人事等系统:用户仍在原系统登录办事,助手作为系统自带能力出现,不必 为每位员工注册 Cadau 账号。
用户视角产品说明见
docs/产品介绍.md;第三方交付文档包见sdk/host-embed/;可运行范例见仓库examples/hr-multi-tenant/。
日期:2026-08-17 相关代码:backend/internal/api/handlers/host_agent_run.go、examples/hr-multi-tenant/server/internal/mindlinkclient/、examples/hr-multi-tenant/server/internal/store/host_actor.go
结论(先读这段)
传软接入 Cadau 的核心不是「把 Cadau 嵌进页面」这么简单,而是一套 职责分离 的架构:
| 谁管什么 | 要点 |
|---|---|
| 传软 | 登录用户、角色、业务权限、员工档案绑定、按人分配用哪条助手模板 |
| Cadau | 模板智能体、对话与检索、嵌入令牌、Host Agent Run、数据连接上的 行/字段策略执法 |
| 每次请求 | 传软 BFF 携带 host_actor(当前办事人是谁),Cadau 据此 隔离会话 与 限制查数范围 |
不为每个终端用户克隆 Cadau 智能体;本期整套宿主(可含多个业务租户)共用 Cadau 一个工作区,用 少数模板智能体 + 运行时身份即可服务全员。人与人靠 host_actor 隔离。「一租户一区」见 宿主增强-AgentRun与数据权限.md §0.3,暂不实现。
本地可跑通全链路:examples/hr-multi-tenant + npm run setup:mindlink + 冒烟脚本 + 手工验收清单。
1. 典型场景:传软为什么需要 Cadau
许多企业已有运行多年的 传软(自研 HR、ERP、行业 SaaS)。它们有成熟的:
- 登录与组织架构
- 业务数据库与权限模型
- 页面与工作流
若直接在传软里 直连大模型 API,常见问题是:
- 密钥与提示词分散在各服务,难以统一治理与审计
- 每个用户一套 Prompt / 会话,运维成本高
- 助手读业务库时,很难在连接层强制「员工只能看本人、主管只能看下属」
- 对话能力难以与 知识文档、技能、记忆 等产品化能力对齐
Cadau 的定位是 智能体平台:传软保留「谁可以登录、管什么数据」的主权;Cadau 提供 可配置的工作智能体、嵌入挂件、以及传软增强下的 Host Agent Run 与 数据连接策略。用户感知是:「还是在老系统里登录,只是多了一个靠谱的助手。」
2. 架构总览
2.1 逻辑分层
flowchart TB
subgraph Legacy["传软(宿主)"]
U["终端用户登录"]
ADM["管理员:登记模板、分配助手"]
BFF["BFF:embed-session / agent-run"]
DB[(业务库 + 分配表)]
UI["业务页面 + 嵌入挂件"]
U --> UI
ADM --> DB
BFF --> DB
UI --> BFF
end
subgraph ML["Cadau"]
WS["工作区"]
UA["模板智能体"]
ET["embed-token / host agent-runs"]
DS["数据连接 + access_policy"]
CHAT["对话 / 工具 / 检索"]
WS --> UA
ET --> UA
UA --> CHAT
CHAT --> DS
end
BFF -->|"集成账号"| ET
UI -->|"短期 embed JWT"| CHAT
BFF -->|"host_actor"| ET
DS -->|"读传软业务库"| DB2.2 三类账号(务必分清)
接入过程中最容易混淆的是「要在 Cadau 里建多少用户」——答案是 只建集成账号,不建终端用户。
| 身份 | 存在哪里 | 数量级 | 作用 |
|---|---|---|---|
| Cadau 集成账号 | Cadau | 每个传软部署 一套(或每客户一套) | 仅 服务端 用来登录 Cadau、代签 embed-token、调 Host Agent Run;密码在 MINDLINK_* 环境变量 |
| 传软登录用户 | 传软业务库 | 企业真实人数 | 管理员、主管、员工自助;在传软页面登录 |
| Cadau 终端用户 | — | 0 | 不需要;身份由 host_actor 表达 |
集成账号 不是 传软里的「演示管理员」。前者是机器用的代签身份;后者是真实业务用户,其 UUID 会出现在 host_actor.external_user_id 里。
2.3 概念映射
| 传软侧 | Cadau 侧 |
|---|---|
| 一套宿主系统(可含多个业务租户) | 一个工作区(本期;MINDLINK_WORKSPACE_ID) |
| 管理员 / 主管 / 员工自助等角色 | 少数模板智能体(可共用一条,靠策略区分数据范围) |
| 传软用户 ID | host_actor.external_user_id |
| 员工档案 ID(自助场景) | host_actor.employee_id(必填) |
| 租户 ID | host_actor.tenant_external_id |
| 应用接入标识 | app_id(如 mindlink-embed-hr) |
3. 核心原理
3.1 host_actor:传软用户的「护照」
每次嵌入会话或服务端代跑,传软 BFF 都要构造 host_actor JSON,告诉 Cadau:当前办事人是谁、什么角色、能管哪些人。
{
"external_user_id": "传软用户 UUID",
"actor_kind": "business",
"display_name": "张明",
"tenant_external_id": "租户 UUID",
"employee_id": "",
"roles": ["manager"],
"managed_org_unit_ids": ["部门 UUID"],
"managed_employee_ids": ["下属员工 UUID…"]
}
| 字段 | 说明 |
|---|---|
actor_kind | business(管他人)或 employee(仅本人) |
external_user_id | 传软登录用户主键;会话隔离键之一 |
employee_id | 员工自助 必填;须已在传软绑定员工档案 |
managed_* | 主管场景:管辖部门 / 下属列表,供策略匹配 |
Cadau 会把它写入嵌入登记与会话上下文;数据连接工具执行查询时,策略引擎读取同一对象做 强制过滤。
3.2 会话隔离:同模板、不同人、不串话
传软增强下的会话键为:
(workspace_id, user_agent_id, app_id, host_actor.external_user_id)
因此:
- 全公司可以共用 一条「员工自助助手」模板智能体
- 张三和李四的对话 session_id 不同,历史互不可见
- 无需在 Cadau 为张三、李四各建智能体或各点「生成令牌」
3.3 模板智能体 + 按角色分配
传软库中通常有两张逻辑表(HR 范例名供对照):
| 表 | 含义 |
|---|---|
hr_mindlink_agents(可换名) | 登记 Cadau 模板智能体 ID、工作区 ID、app_id、角色模板标记 |
hr_user_agent_assignments | 传软 登录用户 → 使用哪条模板 + 行为 scope 说明 |
无感开通:新建传软用户时,按 admin / manager / employee 等角色自动写入分配;首次打开助手时若尚未分配,BFF 可再补默认(HR 范例 EnsureDefaultAgentAssignment)。
终端用户 从不 在 Cadau UI 里选智能体;传软管理员在「用户管理」里配好即可。
3.4 数据连接与行/字段策略
助手要通过 工作区数据连接 读传软业务库(SQLite / MySQL / Postgres 等)。仅有「技能说明」不够——必须在连接上配置 access_policy_json,在 工具执行层 强制:
- 行级:追加
force_params/row_filter_params(模型无法去掉) - 字段级:
allowed_columns/ 拒绝敏感列
策略规则按 host_actor 匹配,例如:
{
"require_host_actor": true,
"rules": [
{
"when": { "actor_kind": "employee" },
"tables": {
"hr_employees": {
"row_filter_params": {
"id": "{{host_actor.employee_id}}",
"tenant_id": "{{host_actor.tenant_external_id}}"
},
"allowed_columns": ["id", "emp_no", "full_name", "org_unit_id"]
}
}
}
]
}
HR 范例提供 GET …/mindlink-access-policy,从本租户权限与组织数据 编译策略草稿;管理员确认后 PUT 到 Cadau 数据连接。技能文档可同步描述边界,不能替代连接侧执法。
4. 两种接入路径
4.1 页面嵌入(用户看得见助手)
适合:传软 Web 页右下角/侧边 对话挂件。
sequenceDiagram participant U as 传软用户浏览器 participant H as 传软 BFF participant M as Cadau U->>H: 已登录,打开业务页 H->>H: 读用户分配 + 构造 host_actor H->>M: 集成账号 login + switch 工作区 H->>M: POST embed-token(含 app_id) M-->>H: 短期 access_token H-->>U: embed-session(token + user_agent_id + host_actor) U->>M: 挂件 chat/stream(embed JWT) M->>M: 按 host_actor 隔离会话 / 策略查数
要点:
- 浏览器 只拿短期 embed JWT,不出现 Cadau 密码
- 传软前端加载
mindlink-widget.min.js,init时传入api_base_url(建议 同域代理/mindlink-api)与host_actor(与 embed-session 下发的一致) - BFF 接口语义:
GET /tenants/{id}/me/embed-session;未分配返回200+{ "available": false }
4.2 Host Agent Run(服务端代跑,用户看不见 Cadau)
适合:传软后端原来 直连 LLM 的批处理、审批摘要、聊天机器人 API 等,改为走工作智能体。
POST /api/v1/host/agent-runs
Authorization: Bearer <集成账号 access_token>
Content-Type: application/json
{
"user_agent_id": "<模板智能体 UUID>",
"app_id": "mindlink-embed-hr",
"message": "帮我汇总本月本部门的入离职情况",
"stream": false,
"fresh": false,
"host_actor": { "...": "与 embed 相同" }
}
传软侧可封装 POST …/me/agent-run,内部转发到 Cadau。页面嵌入与 Agent Run 共用同一套 host_actor 与策略,避免「页面里一套权限、API 里另一套权限」。
5. 实施步骤(从零到可测)
以下按 推荐顺序;HR 多租户范例 (examples/hr-multi-tenant) 与 sdk/host-embed/ 可作为对照实现。
阶段 A:Cadau 侧
- 创建工作区(本期:整套宿主共用一个 Cadau 工作区)
- 在工作区内创建或选定 模板智能体,挂载 知识文档(业务口径、可跳转页面说明)
- 约定全局唯一的
app_id - 创建 集成专用 Cadau 账号,邀请进该工作区(不必拥有智能体)
- 配置 数据连接 指向传软业务库;建立 预定义查询(若用 query 工具)
- 写入
access_policy_json(可先由传软编译草稿再人工确认)
阶段 B:传软侧
- 环境变量(仅服务端,勿进前端仓库):
``env MINDLINK_API_BASE=https://your-mindlink/api/v1 MINDLINK_INTEGRATION_EMAIL=integration@your-corp.com MINDLINK_INTEGRATION_PASSWORD=*** MINDLINK_APP_ID=your-corp-hr MINDLINK_WORKSPACE_ID=<工作区 UUID> HRMS_SEED_MINDLINK_USER_AGENT_ID=<模板智能体 UUID> ``
- 数据表:登记模板智能体、用户分配(见 §3.3)
- BFF:
- 集成账号登录 → POST /workspaces/{id}/switch → POST /user-agents/{id}/embed-token - 响应中带 host_actor
- 前端:业务页拉 embed-session → 加载挂件 → 同域代理 Cadau API
- 开户流程:传软照常建用户;按角色写分配;员工自助须 绑定员工档案
阶段 C:本地 HR 范例一键探测
若使用仓库内范例(Cadau :8080 已启动):
cd examples/hr-multi-tenant/web
npm run setup:mindlink
脚本会 自动注册(或登录)演示集成账号 hr-embed-demo@mindlink.local,并将 MINDLINK_* 写入 ../server/.env。生产勿用该邮箱,应自建集成账号。
另开终端启动 HR 后端与前端:
cd examples/hr-multi-tenant/server
go run ./cmd/hrms-server
cd examples/hr-multi-tenant/web
npm run dev
# 浏览器 http://localhost:5180
# 演示账号 13800138000 / Demo-HR-2026
6. 如何测试
测试分 自动化冒烟(快)与 业务验收(全)两层。
6.1 自动化冒烟
在 examples/hr-multi-tenant/web 目录,Cadau 与 HR 后端均已启动 时:
| 命令 | 验证什么 | 失败常见原因 |
|---|---|---|
npm run smoke:embed | 挂件脚本可达 → HR 登录 → embed-session → 用 embed JWT 访问 Cadau 会话 | MINDLINK_* 未配、集成账号未进工作区、智能体 ID 错误 |
npm run smoke:host-agent | 策略编译非空 → 管理员/主管/员工的 host_actor 正确 → agent-run 会话隔离 | 缺 employee_id、策略 API 未实现、BFF 未带 host_actor |
冒烟 不能替代 数据连接与行字段策略的手工验证,但能快速回答:「链路通不通?」
6.2 手工验收(传软增强必做)
参考 examples/hr-multi-tenant/docs/ACCEPTANCE_HOST_LEGACY.md:
- 数据连接:Cadau 工作区新建 SQLite(或其它引擎)连接,路径指向传软业务库(如
…/server/data/hrms.db),测试连接成功 - access policy:管理员从传软拉策略草稿,写入 Cadau 数据连接
- 员工自助(如
13800138010):问「我的工号」,结果 仅本人 - 主管(如
13800138001):可查下属,薪资等敏感列被裁剪 - 管理员:范围更宽,仍带租户键
- 会话隔离:两账号先后
agent-run,session_id不同、历史不串 - 体验:用户界面 不出现 Cadau 登录/注册
6.3 推荐联调顺序
数据连接 + 预定义查询
→ 写入 access_policy
→ smoke:embed
→ smoke:host-agent
→ 分角色手工问数
→ 界面嵌入与导航(可选)
7. 安全与运维要点
| topic | 建议 |
|---|---|
| 集成账号 | 生产专用、强密码、可轮换;权限仅为「进工作区 + 代签」 |
| 凭证 | embed JWT 短 TTL;仅 HTTPS 下发;禁止写入前端静态配置仓库 |
| 网络 | 浏览器经 传软同域代理 访问 Cadau API,避免 CORS 与混用 localhost / 127.0.0.1 |
| 审计 | 智能体归属人在 Cadau 运行记录 → 嵌入 只读查看对话(不在集成账号个人「消息」里) |
| 策略 | 查数以 数据连接策略 为准;宿主 API Key 与嵌入分配是不同维度 |
| SQLite 路径 | Cadau 进程须能读该文件;若配置了 DATA_SOURCE_ALLOWED_HOSTS,路径须在允许前缀内 |
8. 常见问题
| 现象 | 排查方向 |
|---|---|
| embed-session 502 | 集成账号未加入工作区;MINDLINK_WORKSPACE_ID 与智能体实际工作区不一致;app_id 不匹配 |
| 助手出现但查数越权 | access_policy_json 未写入或未 require_host_actor;host_actor 缺 employee_id |
| 员工自助不可用 | 传软未绑定 hr_user_employee_links;actor_kind 不是 employee |
| 两人共用一个 session | BFF 未传或传错 external_user_id;用了静态 A 路径全员同一 token |
link:mindlink-agent 报智能体不存在 | Cadau 主库为 Postgres 时脚本读 SQLite mindlink.db 会失败;改 Cadau UI 邀请集成账号 + 重跑 setup:mindlink |
| 是否每人要在 Cadau 建账号 | 否;仅集成账号 + host_actor |
9. 与纯嵌入(无传软增强)的差异
| 能力 | 纯嵌入 SDK | 传软宿主增强 |
|---|---|---|
| 终端用户进 Cadau | 不需要 | 不需要 |
| 按传软用户隔离会话 | 依赖 embed 登记绑定 | host_actor.external_user_id 强制隔离 |
| 读传软业务库 | 可选,策略较粗 | access_policy_json 按角色行/字段执法 |
| 服务端代跑 LLM | 需自接模型 | Host Agent Run 统一走工作智能体 |
| 典型文档 | sdk/host-embed/README.md | 本文 + 宿主增强-AgentRun与数据权限.md |
若传软只需「挂一个全员相同的助手、不查业务库」,可先走 host-embed B 路径;一旦要 按人查数、代跑 LLM、会话隔离,应启用传软增强全套。
10. 文档与代码索引
| 资源 | 说明 |
|---|---|
sdk/host-embed/README.md | 第三方嵌入总览、冒烟说明 |
sdk/host-embed/宿主增强-AgentRun与数据权限.md | 用户模型、检查单、API 与策略 JSON |
sdk/host-embed/参考范例-HR接入指南.md | HR 范例 API、表结构、配置项 |
examples/hr-multi-tenant/docs/HOST_LEGACY_INTEGRATION.md | 传软映射真值(仓库内) |
examples/hr-multi-tenant/docs/ACCEPTANCE_HOST_LEGACY.md | 手工验收清单 |
examples/hr-multi-tenant/web/scripts/smoke-embed.mjs | 嵌入冒烟脚本 |
examples/hr-multi-tenant/web/scripts/smoke-host-agent.mjs | 传软增强冒烟脚本 |
11. 小结
传软接入 Cadau 的本质,是把 「谁在用助手」 和 「助手能读哪些行、哪些列」 留在传软主权范围内,同时复用 Cadau 的 智能体、知识、对话与审计。技术上记住四句话即可:
- 整套宿主 → 一个 Cadau 工作区(本期)
- 少数模板智能体 +
host_actor→ 全员覆盖 - 集成账号只给服务端代签,终端用户不进 Cadau
- 业务库权限在数据连接策略里强制,不靠 Prompt 自觉
按本文 §5 实施、§6 测试,配合 HR 范例与 host-embed 文档包,即可在较短时间内从架构理解走到可验收的联调环境。