Skip to content

External Skill 能力集成 ​

外部系统不是数据源,是可调用的能力。


职责 ​

负责不负责
注册外部能力(endpoint + 超时)外部系统的认证密钥管理
调用并把结果落成事实重试与熔断
幂等(同输入不重复请求)结果缓存过期
记录快照时间与原始响应复制对方的数据

为什么不是数据同步 ​

能力集成(本模块)事件接入 / 数据镜像
数据流向按需问一次持续同步
是否产生第二真相否是
审计粒度每次调用一条事实每条变更一条事实
失败影响单次调用失败管道失败可能静默

大多数「ERP 集成」需求其实是能力集成——只是过去没有 agent 这个概念,只能做数据同步。


调用链路 ​

register({ skillId, endpoint, method?, timeoutMs? })
  → invoke(skillId, input, { taskId, actor })
  → 结果落 /tasks/{taskId}/external-calls/{callId}
  → 因果链能追到「谁在何时问了什么」

三条规则 ​

#规则实现
1结果落事实每次调用写一条 external-call,带 actor 与输入指纹
2幂等callId = skillId:hash(input),同输入不重复发请求
3不猜非 2xx 与超时照实记录(ok=false + 原响应)

接口 ​

MethodPath说明
GET/api/external-skill/skills已注册能力(不含 headers)
POST/api/external-skill/:skillId/invoke调用(幂等,结果落任务因果链)

不开放 register:它接受任意 URL 并由服务端发起请求,暴露给登录用户会造成 SSRF。 注册走部署配置或管理员通道。


读的人必须知道 ​

结果带 snapshot: true 与 calledAt——它是某时刻的答案,不是当前值。 要刷新就换 input(幂等键是永久的)。


判据:能力还是事实 ​

外部系统提供的是「能力」还是「事实」?
  ├─ 能力(我能问你一个问题)→ 本模块
  └─ 事实(它的状态我必须知道)→
        ├─ 它能推变更 → 事件接入
        └─ 它只能被我拉 → 只读镜像 + 对账

后两种模式受「同一事实只有一个权威」约束:镜像域只接受同步写入,业务写入一律拒绝。


边界 ​

  • 认证密钥应在部署侧注入,不进代码
  • 只有超时,没有重试与熔断
  • 事件接入与数据镜像的整体设计已成型,代码未实现

源码 ​

libs/modules/src/external-skill/
├── interfaces/external-skill.interface.ts   skill 定义 + 调用结果
└── services/external-skill.service.ts       注册 / 调用 / 幂等 / 落状态

Released under the MIT License.