全部文档

宿主增强:Agent Run 与数据连接行/字段权限

面向 传软 / 旧有业务系统(宿主增强,见产品规格 §4.2.4)。可运行范例与 API 对照见仓库 examples/hr-multi-tenant/docs/HOST_LEGACY_INTEGRATION.md。

来源 sdk/host-embed/宿主增强-AgentRun与数据权限.md

面向 传软 / 旧有业务系统(宿主增强,见产品规格 §4.2.4)。可运行范例与 API 对照见仓库 examples/hr-multi-tenant/docs/HOST_LEGACY_INTEGRATION.md


0. 传软用户模型(三类账号)

传软接入时常见困惑是「要在 Cadau 里为每个业务用户建账号吗?」——不要。请区分三类身份:

身份存在哪里数量用途
Cadau 集成账号Cadau每个传软部署一套(或每客户一套,视运维策略)宿主 服务端 代签 embed-token、调用 Host Agent Run;密码仅存 MINDLINK_* 环境变量
传软登录用户宿主业务库按企业实际人数管理员、主管、员工自助等;在宿主页面登录,注册 Cadau 主站
Cadau 终端用户不需要对话与查数身份由每次请求携带的 host_actor 表达

映射原则(用户视角):

传软概念Cadau(当前交付)
一套宿主系统(可含多个业务租户)一个工作区
按角色用的助手少数模板智能体(如管理员助手、主管助手、员工自助)
每次对话 / 服务端代调携带 host_actor(传软用户身份);历史会话、人工客服、工单与查数按此人隔离

不为每个登录用户克隆一个 Cadau 智能体;人与人隔离靠 host_actor(历史会话 / 人工客服 / 工单)+ 工作区数据连接上的行/字段策略(查数可再按租户键收窄)。「一宿主租户一个 Cadau 工作区」见 §0.3,本期不实现

0.1 两类传软登录用户

类型actor_kind典型场景host_actor 要点
业务用户business管理员、HR、主管管组织/管他人roles;主管可含管辖部门、下属员工 id
员工用户employee只查本人必须employee_id(绑定本租户员工档案)

host_actor 字段(与 backend/internal/datasource/host_actor.go 一致):

字段必填说明
external_user_id宿主登录用户编号;缺则身份无效
actor_kind否(可推断)businessemployee。未传时:有 employee_id 则为 employee,否则 business
employee_idemployee 时必填本租户员工档案编号
display_name展示名
tenant_external_id宿主租户编号(查数策略常用)
emp_no工号
rolestenant_adminmanageremployee
managed_org_unit_ids管辖部门 id 列表
managed_employee_ids下属员工 id 列表
org_unit_id / org_unit_name所在部门

数据连接策略占位符:{{host_actor.external_user_id}}{{host_actor.actor_kind}}{{host_actor.display_name}}{{host_actor.tenant_external_id}}{{host_actor.employee_id}}{{host_actor.emp_no}}{{host_actor.org_unit_id}}{{host_actor.org_unit_name}}{{host_actor.managed_org_unit_ids}}{{host_actor.managed_employee_ids}}(后两项为逗号拼接)。

无感开通:在传软侧创建业务用户或开通员工自助时,按角色写入「用户 → 模板智能体」分配;首次打开助手时若尚无分配,宿主 BFF 可按角色补默认(HR 范例 EnsureDefaultAgentAssignment)。

0.2 集成账号从哪来

场景做法
本地联调(HR 范例)web 目录 npm run setup:mindlink:脚本调用 Cadau POST /auth/register 注册 hr-embed-demo@mindlink.local(已存在则登录),探测工作区与智能体 ID,写入 server/.envMINDLINK_*
生产 / 新传软在 Cadau 手工创建专用集成账号(邮箱或手机号 + 强密码),邀请进对应工作区;使用范例演示邮箱

集成账号与传软演示登录用户(如 HR 范例 13800138000不是同一个人:前者仅服务端代签,后者才是页面里登录的业务用户。

0.3 B 路径工作区:两种方式(本期只做第一种)

B 路径可以按 Cadau 工作区怎么划,分成两种:

方式一:宿主共用一个工作区(本期交付)方式二:一租户一区(以后需要再完善)
怎么配整套宿主系统(含多个业务租户)对应 一个 Cadau 工作区;登记与 MINDLINK_WORKSPACE_ID 指向同一区每个宿主隔离租户对应 一个 Cadau 工作区;登记表按租户写不同工作区 ID
人与人host_actor:历史会话 / 人工客服 / 工单按登录用户隔离同左
租户与租户查数可在数据连接策略里按租户键收窄;客服工作台、座席、知识、规范/资料仍是工作区一份。若要一组 Cadau 客服服务 多个客户工作区,用 客服小组(授权只给客服权,队员不必加入客户区),不要按方式二拆区客服队列、知识按工作区自然分开;也可用客服小组跨区接单,而不把队员加成每个客户区成员
本期只做这种方式(HR 范例即如此)暂不实现开户自动建区、按租户复制助手等;下文仅保留说明

方式二(预留,勿当本期清单)

若日后要做:每开一个宿主租户,在 Cadau 新建工作区 → 邀请同一套(或每客户一套)集成账号 → 在该区创建/复制助手、知识、座席、数据连接 → 宿主登记表填写该区 ID。代签 switch 到登记记录上的工作区,而不是所有租户回落同一个环境变量。旧区里的对话与工单不会自动迁过去。

在实际需要前,不要按方式二改造现网;也不要把方式二写成接入必做项。


1. 新传软接入检查单

新接一家传软或新客户租户时,可按下列顺序核对(概念层;HR 范例脚本路径见 参考范例-HR接入指南.md §7.3)。

Cadau 侧(本期:整套宿主一个工作区)

  • [ ] 创建工作区(或确认已有)
  • [ ] 在工作区内准备 模板智能体(管理员 / 主管 / 员工自助等,或共用一条)
  • [ ] 创建 集成专用账号加入该工作区(不必拥有智能体)
  • [ ] 配置 数据连接(指向传软业务库,如 SQLite / MySQL / Postgres)
  • [ ] 写入 access_policy_json(可从宿主 GET …/mindlink-access-policy 编译草稿后 PUT 到数据连接)

传软侧

  • [ ] 服务端环境变量:MINDLINK_API_BASEMINDLINK_INTEGRATION_*MINDLINK_WORKSPACE_IDMINDLINK_APP_ID;生成/分析另指定 MINDLINK_GENERATE_USER_AGENT_ID(或宿主设置)。HR 范例本地演示才用 HRMS_SEED_MINDLINK_USER_AGENT_ID(启动时给演示账号补分配,不是运行时挂件配置)
  • [ ] 宿主库 登记模板智能体(Cadau 工作区 ID + 智能体 ID + app_id
  • [ ] BFF:GET …/me/embed-sessionPOST …/me/agent-run 均携带完整 host_actor
  • [ ] 传软侧 开户流程 不变:新用户仍在宿主注册/导入;按角色分配模板智能体

自动化与手工验收

  • [ ] npm run smoke:embed — 嵌入链路(见 README.md §8.1)
  • [ ] npm run smoke:host-agenthost_actor、策略编译、会话隔离(传软增强)
  • [ ] 手工:员工仅本人、主管下属与字段裁剪;两账号互看不到对方的历史会话、人工客服与工单(HR 范例见仓库 ACCEPTANCE_HOST_LEGACY.md

2. 宿主 LLM 服务(指定智能体代答)

宿主后端不要直连大模型,改为请工作区内 指定智能体 代答。完整对接(调用链、字段、会话隔离、清单)见 宿主LLM服务.md

摘要:POST /api/v1/host/agent-runs(集成账号;必带 user_agent_idmessagehost_actor)。页面挂件与代答共用身份与数据策略。HR 范例日常问答封装为 POST …/me/agent-run;生成类任务走 已指定的分析智能体.env / 宿主设置,fresh: true),见 宿主LLM服务.md §5.1。


3. 数据连接 access_policy_json

保存在工作区数据连接上。结构概要:

{
  "require_host_actor": true,
  "rules": [
    {
      "when": { "actor_kind": "employee" },
      "queries": {
        "employees_directory": {
          "force_params": {
            "employee_id": "{{host_actor.employee_id}}",
            "tenant_id": "{{host_actor.tenant_external_id}}"
          },
          "allowed_columns": ["id", "emp_no", "full_name", "org_unit_id", "lifecycle_status"]
        }
      },
      "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", "lifecycle_status"]
        }
      }
    }
  ]
}

占位符见 §0.1 字段表。执法时机:query.run / table.preview / select.run。无 host_actor 且策略要求时 拒绝查数