架构概述

架构概述

← 返回首页

Python SDK 与 Java SDK 架构 一致,本页着重描述 Python 端的差异点。

系统架构

text
┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                        灵心平台 (LinkSoul Platform)                               │
│                                                                                                 │
│  ┌─────────────────────┐         Bridge (桥接器)          ┌─────────────────────┐              │
│  │ LinkskyGateway       │ ◄──────────────────────────────► │   交互网关 (Gateway) │              │
│  │ (二开网关)            │   Boss Channel (控制面)           │                     │              │
│  │  接收二开SDK连接     │   Worker Channel (数据面)         │  连接机器人终端      │              │
│  │  认证 & 消息路由     │   双向信令握手                    │  音频/视频/指令转发   │              │
│  └──────────┬──────────┘                                  └──────────┬──────────┘              │
│             │                                                        │                         │
└─────────────│────────────────────────────────────────────────────────│─────────────────────────┘
              │                                                        │
              │ WebSocket (wss)                                        │ WebSocket / TCP
              │ wss://open.agibot.com/api/V1/open-portal/app/wss/agent-sdk                  │
              │                                                        │
┌─────────────▼──────────────┐                            ┌────────────▼─────────────┐
│   您的二开应用 (AgentSdk)    │                            │   机器人终端 / 智能体      │
│                            │                            │                          │
│  ┌──────────────────────┐  │                            │  ┌────────────────────┐  │
│  │  LinkskyClient       │  │                            │  │  音频采集 (MIC)     │  │
│  │  (websocket-client)  │  │                            │  │  视频采集 (Camera)  │  │
│  └──────────┬───────────┘  │                            │  │  TTS 播放 (Speaker) │  │
│             │              │                            │  │  动作执行 (Motor)   │  │
│  ┌──────────▼───────────┐  │                            │  └────────────────────┘  │
│  │  MessageRouter        │  │                           └──────────────────────────┘
│  │  (handlers.py 分发)   │  │
│  └──────────┬───────────┘  │
│             │              │
│  ┌──────────▼───────────┐  │
│  │  PassiveCallback     │  │     被动交互:机器人发起 → 二开处理 → 返回结果
│  │  (8 种业务子类)        │  │     Audio → ASR → LLM → TTS
│  ├──────────────────────┤  │
│  │  TaskFlowRequest     │  │     主动交互:二开发起 → 网关转发 → 机器人响应
│  │  (主动交互任务流)      │  │     register_task_flow / start_request / task_request / end_request
│  └──────────────────────┘  │
└────────────────────────────┘

数据流向

被动交互(机器人 → 二开 SDK)

text
机器人麦克风 → 交互网关 → Bridge Worker → LinkskyGateway(二开网关) → AgentSdk → callback.on_request()
                                                                                  │
callback 返回 → AgentSdk → LinkskyGateway(二开网关) → Bridge Worker → 交互网关 → 机器人扬声器

主动交互(二开 SDK → 机器人)

text
agent_sdk.register_task_flow() → LinkskyGateway(二开网关) → Bridge Boss → 交互网关 → 机器人
                                                                                  │
机器人响应 → 交互网关 → Bridge Boss → LinkskyGateway(二开网关) → AgentSdk → callback.on_*_ack()

模块结构

text
linksoul_agentsdk/
├── __init__.py                 # 公开 AgentSdk, AgentParam, AgentMeta, ... 11 个顶层符号
├── agent_sdk.py                # 主入口(单例工厂、回调注册、生命周期)
├── agent_param.py              # 扩展参数(链式 set_string/set_integer/...)
├── agent_meta.py               # 智能体元数据
├── agent_auth_callback.py      # 鉴权回调抽象基类
├── id_generator.py             # 唯一 ID 生成(基于 secrets)
├── client/linksky_client.py    # HMAC-SHA256 网关签名
├── enums.py                    # 5 个枚举:AgentCallbackType / AgentEventType / FlowMode / ...
├── client/                     # WebSocket 通信层
│   ├── linksky_client.py       # 同步阻塞 WebSocket 客户端 + 重连 + 心跳
│   ├── message_router.py       # 收到 JSON → 按 event_type 分发到 handler
│   └── handlers.py             # 各事件具体处理函数(被动 + 主动 ack)
├── passive/                    # 被动交互
│   ├── base.py                 # PassiveCallback / AgentSdkResponse / GreetResponse
│   ├── audio2_llm.py           # Audio2LlmCallback + Audio2LlmResponse
│   ├── audio2_tts.py / asr2_llm.py / asr2_tts.py
│   ├── asr_video2_vlm.py / asr_video2_tts.py
│   └── audio_video2_vlm.py / audio_video2_tts.py
├── active/                     # 主动交互
│   └── task_flow.py            # TaskFlowRequest + 4 个 Flow*Callback
└── mgr/                        # 全局管理器
    ├── callback_type_mgr.py    # app_id → 已注册 callback type 集合
    ├── response_mgr.py         # event_id → Response 缓存 + TTL 清理
    ├── task_flow_mgr.py        # flow_id → TaskFlowRequest 映射
    └── agent_thread_mgr.py     # agent_id → 单线程 worker 绑定

通信协议

连接认证

WebSocket HTTP Header:

  • AGIBOT_APP_ID: 应用 ID
  • AGIBOT_AUTHORIZATION: Bearer <JWT Token>

JWT Payload:{"appId": "xxx", "callbackTypes": "[\"asr2llm\"]", "exp": <epoch+3600>}

消息格式 (JSON)

json
{
    "type": "agentsdk.audio_request.start",
    "agentId": "AGENT_0000001",
    "eventId": "event_xxxxx",
    "robotCid": "cid_xxx",
    "cid": "cid_xxx"
}

线程模型

线程数量职责
linksky-recv-<app_id>1WebSocket 接收线程,跑 ws.run_forever
agent-worker-N1..50每个 agent_id(灵心平台配置的智能体 ID)绑定一个串行 worker,保证同一智能体消息顺序处理
threading.Timer daemon0..1重连定时器

关键约定:用户在 on_request 内的所有 response.on_* 调用都跑在 worker 线程。 LinkskyClient.send_text 内部用 threading.Lock 序列化,可在任意线程安全调用。

重连机制

  • 连接失败/断开后自动重连
  • 重连延迟:3 秒(reconnect_delay,可在构造时覆盖)
  • 默认无限重连(max_reconnect_attempts=-1),直到调用 agent_sdk.release()
  • 心跳:每 10 秒发送 Ping(websocket-client 内置)

典型时序

下面以 Audio2Tts(音频输入 → ASR + LLM + TTS 全管道)为例展示一次完整对话的时序。 其他被动回调只是 on_request 收到的数据形态不同,整体节奏一致。

mermaid
sequenceDiagram
    participant Robot as 机器人
    participant IGW as 交互网关
    participant Bridge as Bridge 桥接器
    participant Linksky as LinkskyGateway<br/>(二开网关)
    participant SDK as AgentSdk<br/>(二开应用)

    Note over SDK,Linksky: 启动阶段
    SDK->>Linksky: WebSocket 连接 + JWT 鉴权
    Linksky-->>SDK: on_auth_state(code=0)
    Robot->>IGW: 机器人上线
    IGW->>Bridge: 上线事件
    Bridge->>Linksky: 上线事件
    Linksky-->>SDK: on_robot_online(agent_id, agent_meta)

    Note over Robot,SDK: 一次对话
    Robot->>IGW: 用户开始说话 (VAD start)
    IGW->>Linksky: audio_request.start
    Linksky-->>SDK: on_request(flag=0)
    loop 音频帧
        Robot->>IGW: PCM 音频帧
        IGW->>Linksky: audio_request.append
        Linksky-->>SDK: on_request(flag=1, buf=audio)
    end
    Robot->>IGW: VAD end
    IGW->>Linksky: audio_request.commit
    Linksky-->>SDK: on_request(flag=2)

    Note over SDK: 业务侧 ASR → LLM → TTS
    SDK->>Linksky: response.on_asr_middle / on_asr_final
    SDK->>Linksky: response.on_interrupt(event_id, "chat", None)
    SDK->>Linksky: response.on_llm_item_delta × N
    SDK->>Linksky: response.on_llm_item_done / on_llm_done
    SDK->>Linksky: response.on_tts_item_delta × N
    SDK->>Linksky: response.on_tts_item_done / on_tts_done
    Linksky->>IGW: 转发响应帧
    IGW->>Robot: 屏幕显示 + 扬声器播放

关键点:

  • 一次对话的整个生命周期通过 event_id 关联,跨多次 on_request/response.on_* 调用都共用同一个 event_id
  • ASR/LLM/VLM/TTS 都是流式输出,可以多次 *_delta,最后用 *_done 收尾。
  • 命中有效指令必须先 on_interrupt,再 on_skill / on_llm_* / on_vlm_* / on_tts_*
  • 技能下发 response.on_skill(...) 与文本/音频输出可以并行,互不阻塞;具体可下发的技能见 语义技能参考
  • 业务侧异常时调用 response.on_error(event_id, code, msg) 通知机器人端。