全部文档

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

宿主后端原来若直接调大模型,可改为:由 Cadau 里 指定的工作智能体 代为回答。用户不必登录 Cadau,也不必打开页面挂件。

来源 sdk/host-embed/宿主LLM服务.md

宿主后端原来若直接调大模型,可改为:由 Cadau 里 指定的工作智能体 代为回答。用户不必登录 Cadau,也不必打开页面挂件。

本期:整套宿主共用 一个 Cadau 工作区(见 宿主增强-AgentRun与数据权限.md §0.3)。

对照实现examples/hr-multi-tenantPOST …/me/agent-run(问答)与 POST …/positions/suggest-for-org(编制建议)。


1. 和页面挂件有什么不同

页面助手(嵌入挂件)宿主 LLM 服务(本文)
谁发起浏览器里的挂件宿主服务端
用户看见什么右下角对话浮层由你决定(审批摘要、机器人接口、批处理……用户可以完全看不见 Cadau)
用哪条智能体按登录用户 分配 的那条服务端指定:日常问答可用同一套分配;生成/分析用 任务型智能体(§5.1),不要占用页面助手
当前是谁host_actor 传给挂件请求体带同一套 host_actor
对话落在哪嵌入会话同一类嵌入会话(按登录用户隔离)

两种路径 共用 智能体知识、数据连接策略与「当前是谁」。不要页面一套权限、服务端另一套。

不要把本文接口暴露给浏览器;页面对话继续走挂件。集成账号密码只放宿主服务端。


2. 调用链(用户视角)

sequenceDiagram
  participant App as 宿主业务(服务端)
  participant BFF as 宿主对接层
  participant ML as Cadau
  participant Agent as 指定工作智能体

  App->>BFF: 已登录用户要一句回答
  BFF->>BFF: 查该用户分配的智能体 + 组装当前用户身份
  BFF->>ML: 集成账号登录并进入工作区
  BFF->>ML: 请这条智能体代答(消息 + 当前用户身份)
  ML->>Agent: 按知识、工具、数据策略作答
  Agent-->>ML: 回复
  ML-->>BFF: 回复 + 会话编号
  BFF-->>App: 你的业务接口原样返回

智能体由 宿主管理员分配,终端用户不挑选「用哪条模型」。


3. Cadau 侧要准备什么

与 B 路径嵌入相同,不必另开一套账号:

  • 工作区 + 模板智能体(知识已挂)
  • 集成账号 已加入该工作区(不必拥有该智能体)
  • (若要查业务库)工作区 数据连接 与访问策略已写入

详见 宿主增强-AgentRun与数据权限.md §1。


4. 对接:Cadau 接口

仅宿主服务端调用。鉴权用 集成账号 登录后的访问令牌(先 login,再按需 switch 工作区)。

POST /api/v1/host/agent-runs
Authorization: Bearer <集成账号访问令牌>
Content-Type: application/json
{
  "user_agent_id": "<智能体 UUID>",
  "app_id": "your-app-id",
  "workspace_id": "<工作区 UUID,可省略则用令牌当前工作区>",
  "message": "本月我的职级是什么?",
  "session_id": "",
  "stream": false,
  "fresh": false,
  "host_actor": {
    "external_user_id": "宿主用户编号",
    "actor_kind": "employee",
    "display_name": "陈晨",
    "tenant_external_id": "宿主租户编号",
    "employee_id": "员工档案编号",
    "roles": ["employee"]
  }
}

4.1 请求字段

字段必填说明
user_agent_id代答的那条工作智能体,须在该工作区内
message用户问题或任务说明
host_actor当前宿主登录用户。actor_kindemployee必须employee_id
app_id缺省 mindlink-embed;与嵌入登记一致便于会话归并
workspace_id缺省用集成账号当前工作区;本期与 MINDLINK_WORKSPACE_ID 相同
session_id续聊时传入上次返回的编号;空则默认接上该用户在此智能体下最近一条,没有则新建
freshtrue 且未带 session_id总是新建会话(适合「按部门生成岗位」这类一次性任务,避免部门 A 的上下文接到部门 B)
stream见 §4.3

4.2 非流式响应(stream 为 false 或省略)

{
  "session_id": "…",
  "request_id": "…",
  "reply": "助手全文",
  "message_id": "…",
  "user_agent_id": "…",
  "workspace_id": "…",
  "app_id": "…",
  "host_actor": { }
}
字段说明
reply给业务侧展示或落库的完整回答
session_id下次续聊带上,同一登录用户不会串到别人
request_id本轮追踪号

失败时常见:unauthorized(未登录)、forbidden_embed_token(误用嵌入令牌)、validation_error(缺消息 / 缺智能体 / 身份无效)、workspace_requirednot_found(智能体不在该工作区)、host_agent_run_failed(作答失败)。

4.3 关于 stream: true

接口接受该字段,但 不是 页面挂件那种边生成边吐字:服务端仍一次跑完,再按 SSE 依次发出 sessiondelta(整段回复)、done

HR 范例对接层 固定按非流式 取整段 reply。需要真流式时,用页面挂件的对话通道。


5. 宿主侧建议怎么包一层

不要让每个业务模块自己拿集成账号调 Cadau。做成「当前登录用户的一句问答」:

  1. 校验宿主登录与权限
  2. 查该用户已分配的智能体(未分配则明确失败,勿默默换一条)
  3. 组装与嵌入会话相同的 当前用户身份
  4. 集成账号进入工作区后调用上一节接口
  5. reply / session_id 返回给业务

HR 范例:

  • 日常问答:POST /api/v1/tenants/{租户}/me/agent-run(用该用户已分配的对话助手)
  • 任务型生成:POST /api/v1/tenants/{租户}/positions/suggest-for-org(调用 已指定的生成/分析智能体
  • 指定方式:服务端 .envMINDLINK_GENERATE_USER_AGENT_ID,或宿主「用户管理 → 嵌入助手登记」
  • 客户端:examples/hr-multi-tenant/server/internal/mindlinkclient/ 的代调
  • 验收:examples/hr-multi-tenant/web 目录 npm run smoke:host-agent(问答链路);岗位建议在「岗位与职级」页手工验收

5.1 对话助手 vs 生成/分析智能体

页面挂件用的是 对话助手(管理员 / 主管 / 员工自助):给人聊天、可开人工客服。 生成、分析、填表 由宿主服务端调用 另一条指定的智能体(可与对话助手不同,也可复用已有助手)。

先在 Cadau 创建并配置好(知识、数据连接等),再在宿主 指定 它。不要靠脚本偷偷建一条。指定位置只有这两处,分析调用都走这里:

  1. 服务端 .envMINDLINK_GENERATE_USER_AGENT_ID=<Cadau 智能体 UUID>(部署默认)
  2. 宿主设置:「用户管理 → 嵌入助手登记 → 生成与分析用智能体」(保存后覆盖环境变量)

不要和 HRMS_SEED_MINDLINK_USER_AGENT_ID 搞混:后者只是 HR 范例启动时给演示账号补登记/分配,不是生成/分析用的智能体。

对话助手生成 / 分析
谁用登录用户在页面里问宿主某个按钮 / 批处理
指定按用户分配.env 或宿主设置 一条
应用标识挂件 MINDLINK_APP_ID默认 mindlink-embed-hr-generate(会话不和聊天混在一起;HR 范例可用 MINDLINK_GENERATE_APP_ID 覆盖,不必写入 .env
会话默认可续聊每次任务传 fresh: true
落库助手只回答宿主先 预览,由人确认后再写业务表

HR 范例:选定部门 → 建议该部门应有哪些岗位(「岗位与职级」页)。结果只展示,不自动写入岗位库。


6. 会话与隔离

  • 会话记在 Cadau,归属 集成账号,并打上当前宿主用户编号。
  • 同一智能体下,用户甲与用户乙的代答历史 互不续接
  • 续聊:把上次的 session_id 传回;若会话已属于另一用户,接口拒绝。
  • 不传 session_id 时:默认使用该用户在「同一工作区 + 同一智能体 + 同一应用标识」下最近一条;没有则新建。
  • 一次性生成任务:传 fresh: true(且不要带 session_id),每次新建,避免上一部门的建议污染这一次。

页面挂件里的对话与代答会话都按同一套用户编号隔离,但 不是 强制合成一条时间线。要「页面里接着服务端刚问的」需自行约定是否共用 session_id(一般两套入口分开即可)。


7. 智能体实际会做什么

代答走该智能体的知识、技能与数据连接,与页面里问同一助手相同:

  • 系统会带上「当前是哪位宿主用户」(姓名、角色、员工档案等),避免再向用户索要工号来「确认身份」
  • 查业务库必须走数据连接;行/字段由访问策略强制,模型去不掉
  • 员工自助只能协助查本人(策略 + 身份提示共同约束)

策略写法见 宿主增强-AgentRun与数据权限.md §3。


8. 联调清单

  • [ ] 集成账号能登录并进入智能体所在工作区
  • [ ] 指定的智能体 ID 确在该工作区
  • [ ] 请求带完整当前用户身份;员工自助含员工档案编号
  • [ ] 未分配助手的用户:宿主接口明确失败,而不是随便找一条智能体
  • [ ] 两名登录用户先后代答,session_id 不同、内容不串
  • [ ] 同一用户第二次带上 session_id(或不带、走自动接续)能续上
  • [ ] 任务型调用使用独立智能体 + 独立 app_id + fresh: true;结果先预览再落库
  • [ ] (可选)npm run smoke:host-agent 通过
  • [ ] 集成密码未出现在前端或公开仓库

9. 常见问题

现象排查
无权 / 智能体不存在集成账号未进工作区;智能体 ID 与工作区不一致;未 switch
请提供有效的宿主用户身份host_actorexternal_user_id;员工未带 employee_id
员工用户须绑定员工档案自助账号尚未绑本租户人员档案
调用助手失败 / 大模型未配置Cadau 侧模型未就绪
答出了不该看的行或列数据连接访问策略未写入或未按当前用户身份收窄
浏览器直接调本接口不要;页面走挂件,代答只走宿主服务端

10. 维护信息

文档类型宿主服务端 LLM 代答对接说明
Cadau 接口POST /api/v1/host/agent-runs
参考范例examples/hr-multi-tenantPOST …/me/agent-run;生成/分析见 POST …/positions/suggest-for-org(智能体由 .env / 宿主设置指定)
相关宿主增强-AgentRun与数据权限.md参考范例-HR接入指南.mdSDK契约.md V1.5.12