架构概述 · iOS
架构概述 · iOS
系统架构
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) │ │
│ │ (URLSessionWebSocket)│ │ │ │ 视频采集 (Camera) │ │
│ └──────────┬───────────┘ │ │ │ TTS 播放 (Speaker) │ │
│ │ │ │ │ 动作执行 (Motor) │ │
│ ┌──────────▼───────────┐ │ │ └────────────────────┘ │
│ │ InboundHandler │ │ └──────────────────────────┘
│ │ (被动消息分发) │ │
│ ├──────────────────────┤ │
│ │ ActiveMsgHandler │ │
│ │ (主动消息分发) │ │
│ └──────────┬───────────┘ │
│ │ │
│ ┌──────────▼───────────┐ │
│ │ PassiveCallbacks │ │ 被动交互:机器人发起 → 二开处理 → 返回结果
│ │ (8种回调实现) │ │ Audio → ASR → LLM → TTS
│ ├──────────────────────┤ │
│ │ ActiveRequests │ │ 主动交互:二开发起 → 网关转发 → 机器人响应
│ │ (任务流 TaskFlow) │ │ registerTaskFlow / startRequest / taskRequest / endRequest
│ └──────────────────────┘ │
└────────────────────────────┘
数据流向
被动交互(机器人 → 二开 SDK)
text
机器人麦克风 → 交互网关 → Bridge Worker → LinkskyGateway(二开网关) → AgentSdk → Callback.onRequest()
│
Callback 返回 → AgentSdk → LinkskyGateway(二开网关) → Bridge Worker → 交互网关 → 机器人扬声器
主动交互(二开 SDK → 机器人)
text
AgentSdk.registerTaskFlow() → LinkskyGateway(二开网关) → Bridge Boss → 交互网关 → 机器人
│
机器人响应 → 交互网关 → Bridge Boss → LinkskyGateway(二开网关) → AgentSdk → Callback.onResponse()
Bridge 桥接器
桥接器是二开网关与交互网关之间的通信枢纽:
| 通道 | 方向 | 职责 |
|---|---|---|
| Boss Channel | 控制面 | Agent 注册/注销、callId 广播、信令同步 |
| Worker Channel | 数据面 | 音频/视频/ASR/TTS 数据转发、状态同步 |
- 每对网关之间建立 Boss + Worker 两条 WebSocket 连接
- 通过 ZooKeeper 服务发现,自动感知网关实例上下线
- 支持集群部署,多个二开网关实例可同时服务
模块结构
text
Sources/LinksoulAgentSDK/
├── AgentSdk.swift # 主入口(单例工厂、回调注册、生命周期)
├── AgentParam.swift # 类型安全参数包装器
├── AgentMeta.swift # 智能体元数据
├── AgentAuthCallback.swift # 认证回调协议
├── FunctionCallInfo.swift # Function Call 载体(v1.5.0)
├── HistoryInfo.swift # 对话历史条目(v1.5.0)
├── IdGenerator.swift # ID 生成器
├── Client/
│ ├── LinkskyClient.swift # URLSessionWebSocketTask 客户端
│ ├── InboundHandler.swift # 被动消息分发
│ ├── ActiveMsgHandler.swift # 主动消息分发
│ ├── TeleopMsgHandler.swift # 遥操消息路由(v1.5.0)
│ └── ExtSkillMsgHandler.swift # 扩展技能消息路由(v1.5.0)
├── Enums/ # 枚举定义
├── Passive/ # 被动交互(8 种 Callback + Response + GreetResponse)
├── Active/ # 主动交互(TaskFlowRequest / PullStreamRequest / Query)
├── Teleop/ # 超视距遥操(v1.5.0)
├── ExtSkill/ # 扩展技能(v1.5.0)
└── Mgr/ # 管理器(回调类型、响应缓存、清理定时器)
通信协议
连接认证
HTTP Header(HMAC-SHA256 五头签名,v1.4.0 起):
X-App-Id: 应用 IDX-App-Key: 应用 KeyX-Timestamp: 毫秒时间戳X-Nonce: 随机串X-Signature:HMAC-SHA256(appSecret, "GET\n{path}\n{timestamp}\n{nonce}")的 hex 摘要X-Callback-Types: JSON 数组字符串,如["audio2Llm"]
消息格式 (JSON)
json
{
"type": "agentsdk.audio_request.start",
"agentId": "AGENT_0000001",
"eventId": "event_xxxxx",
"robotCid": "cid_xxx",
"cid": "cid_xxx"
}
线程模型
- URLSession delegate 队列:WebSocket I/O
- per-agent 串行队列:每个
agentId绑定一个串行 DispatchQueue,保证同一智能体消息顺序处理 - 清理定时器:定期清理过期的 Response / 回调缓存(
AgentSdkClear)
重连机制
- 连接失败/断开后自动重连,延迟 3 秒
- 无限重连(直到调用
AgentSdk.release()) - 心跳:PingBurst 控制器发送协议级 ping
典型时序
下面以 Audio2Tts(音频输入 → ASR + LLM + TTS 全管道)为例展示一次完整对话的时序。
其他被动回调只是 onRequest 收到的数据形态不同,整体节奏一致。
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 连接 + HMAC 鉴权
Linksky-->>SDK: onAuthState(code=0)
Robot->>IGW: 机器人上线
IGW->>Bridge: 上线事件
Bridge->>Linksky: 上线事件
Linksky-->>SDK: onRobotOnline(agentId, agentMeta)
Note over Robot,SDK: 一次对话
Robot->>IGW: 用户开始说话 (VAD start)
Linksky-->>SDK: onRequest(flag=0)
loop 音频帧
Robot->>IGW: PCM 音频帧
Linksky-->>SDK: onRequest(flag=1, audio=...)
end
Robot->>IGW: VAD end
Linksky-->>SDK: onRequest(flag=2)
Note over SDK: 业务侧 ASR → LLM → TTS
SDK->>Linksky: response.onAsrMiddle / onAsrFinal
SDK->>Linksky: response.onLlmItemDelta × N
SDK->>Linksky: response.onLlmItemDone / onLlmDone
SDK->>Linksky: response.onSkill(技能指令)
SDK->>Linksky: response.onTtsItemDelta × N
SDK->>Linksky: response.onTtsItemDone / onTtsDone
关键点:
- 一次对话的整个生命周期通过
eventId关联,跨多次onRequest/response.on*调用都共用同一个eventId。 - ASR/LLM/VLM/TTS 都是流式输出,可以多次
*Delta,最后用*Done收尾。 - 技能下发
response.onSkill(...)与文本/音频输出可以并行,互不阻塞;技能全集见 语义技能参考。 - 业务侧异常时调用
response.onError(eventId:errorCode:errorMsg:)通知机器人端。