扩展技能(ExtSkill)指南 · JS / 浏览器

扩展技能(ExtSkill)指南 · JS / 浏览器

⚠️ 尚未上线:本能力为 v1.5.0-SNAPSHOT 开发中特性,接口与协议可能调整,正式发布前请勿用于生产环境。

v1.5.0 新增。ExtSkill = 扩展技能:二开应用把自定义技能挂到智能体上,运行期先 query 拉取该智能体当前可用的扩展技能清单,再 invoke 触发某个技能执行。与超视距遥操并列,走独立事件族与独立策略枚举 AgentPolicy.ExtSkill(wire 值 "extskill")。JS SDK 复用与 Java 相同的 wire 协议,但运行在浏览器,鉴权经服务端代理,结果经 sdk.on('message') 统一分发。

使用场景

  • 二开应用在灵心平台为智能体配置了若干扩展技能(如天气查询、工单创建、设备控制),需要在运行期动态获取清单并按需触发;
  • 需要旁路对话链路直接调用一个确定性的能力(带结构化入参、拿结构化出参),而不是走 LLM 自由生成;
  • 一次 invoke 分两段收结果:先 invoke_ack 确认网关已受理,再 invoke_result 拿到技能真正的执行输出。

调用流程

createExtSkillSession 创建会话后,可任意次 query 拉取清单、invoke 触发执行。

text
   ┌─────────────────────────────┐
   │  session.query()             │  拉取可用扩展技能清单
   │    → query_result (message)  │
   └─────────────────────────────┘

   ┌─────────────────────────────┐
   │  session.invoke(id, input)   │  触发某个扩展技能执行
   │    → invoke_ack (message)    │  ← 第一段:网关已受理
   │    → invoke_result (message) │  ← 第二段:技能执行输出
   └─────────────────────────────┘
  • query / invoke 返回本次消息的 eventId(string),其结果通过 sdk.on('message') 收到对应 type 的消息判读;
  • 与原生 SDK 不同,JS SDK 没有 ExtSkillQueryCallback 之类的回调类:一切下行都从 message 事件走;
  • 若发送时 WebSocket 未连接,sdk.send 会直接抛错——业务侧应在 connected 之后再调用。

浏览器最小集成

1. 创建并连接 SDK

ts
import { createAgentSdk, AgentEventType } from 'linksoul-agentsdk';

const sdk = createAgentSdk(appId, {
  authProvider: async () => {
    const res = await fetch('/api/ws-auth', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ url: upstreamUrl, appId }),
    });
    return { url: (await res.json()).url };
  },
  reconnect: true,
});
await sdk.connect();

authProvider / 服务端签名代理见 快速开始。

2. 监听结果(统一在 message 事件)

ts
sdk.on('message', ({ data }) => {
  let msg;
  try { msg = JSON.parse(typeof data === 'string' ? data : ''); } catch { return; }
  switch (msg.type) {
    case AgentEventType.ExtSkillQueryResult:
      if (msg.code === 0) {
        console.log('技能清单:', msg.output);
      } else {
        console.error('query 失败:', msg.message);
      }
      break;
    case AgentEventType.ExtSkillInvokeAck:
      console.log('invoke 已受理, code =', msg.code);
      break;
    case AgentEventType.ExtSkillInvokeResult:
      if (msg.code === 0) {
        console.log('技能执行结果:', msg.output);
      } else {
        console.error('invoke 失败:', msg.message);
      }
      break;
  }
});

3. 创建 ExtSkill 会话

ts
const session = sdk.createExtSkillSession({ agentId });
// session.agentId / session.requestId 只读

4. 查询可用技能清单

ts
const queryEventId = session.query(); // 返回 eventId,结果在 message 事件里

5. 触发技能执行

ts
const invokeEventId = session.invoke('skill_weather', { city: 'shanghai', days: 3 });
// invoke_ack + invoke_result 均在 message 事件里

事件族与协议

AgentEventType(常量对象)里的扩展技能事件:

常量wire 值说明
AgentEventType.ExtSkillQueryagentsdk.ext_skill.query查询可用扩展技能清单(SDK → 网关)
AgentEventType.ExtSkillQueryResultagentsdk.ext_skill.query_result查询结果(网关 → SDK)
AgentEventType.ExtSkillInvokeagentsdk.ext_skill.invoke触发扩展技能执行(SDK → 网关)
AgentEventType.ExtSkillInvokeAckagentsdk.ext_skill.invoke_ack下发受理回执(网关 → SDK)
AgentEventType.ExtSkillInvokeResultagentsdk.ext_skill.invoke_result执行结果(网关 → SDK)

上行 query 消息 wire 结构:

json
{
  "type":      "agentsdk.ext_skill.query",
  "agentId":   "<目标智能体 agentId>",
  "eventId":   "event_xxxxxxxxxxxxxxxxxxxxx",
  "agentMode": "extskill",
  "requestId": "extskill_xxxxxxxxxxxxxxxxxxxxx"
}

invoke 额外携带 extSkillId(要触发的技能 ID)与 input(原样对象):

json
{
  "type":       "agentsdk.ext_skill.invoke",
  "agentId":    "<目标智能体 agentId>",
  "eventId":    "event_xxxxxxxxxxxxxxxxxxxxx",
  "agentMode":  "extskill",
  "requestId":  "extskill_xxxxxxxxxxxxxxxxxxxxx",
  "extSkillId": "skill_weather",
  "input":      { "city": "shanghai", "days": 3 }
}

agentMode 恒为 "extskill"(AgentPolicy.ExtSkill)。

结果错误码

query_result / invoke_ack / invoke_result 的 code 语义统一:

code含义
0成功(output 承载返回内容)
-1服务端返回失败,message 携带错误详情

未连接时调用 query / invoke,底层 sdk.send 会直接抛错;业务侧应确保在 connected 之后再操作。

与 Teleop 的区别

维度Teleop(超视距遥操)ExtSkill(扩展技能)
策略AgentPolicy.Teleop("teleop")AgentPolicy.ExtSkill("extskill")
标识字段agentId + teleopIdagentId + requestId
核心动作enter / audio / keepAlive / exitquery / invoke
结果模型单次 ACKquery 单次结果;invoke 两段(ack + result)
工厂方法sdk.createTeleopSession(options)sdk.createExtSkillSession(options)

常见问题

  1. query 没反应:确认已在 sdk.on('message') 里解析 ExtSkillQueryResult;JS SDK 没有 query 回调,结果只从 message 事件来。
  2. invoke 抛错:检查 WebSocket 是否已连接。未连接时 sdk.send 直接抛异常。
  3. 多智能体:每个 agentId 建一个 ExtSkillSession;SDK 按 requestId 区分,互不冲突(可复用同一个 AgentSdk 连接)。

完整 API 签名见 ExtSkill API。示例片段见 ExtSkill 示例。