Skip to content

渠道接入(Channel Plugin)

Sira 把每种 IM / 客户端通过 独立的 Python 包 + setuptools entry_points 装载——核心代码不需要修改即可新增渠道。每个 Application 绑定一种渠道,对应一份"应用凭据 + 推送方式"配置。

已支持的渠道

渠道License Feature状态
Web 客户端内置channel.web_client (TRIAL)内嵌网页聊天 / app-chat/[token]
企业微信传统应用内置channel.wecom (STANDARD)/features/wechat-work
企业微信 AI Botsira-channel-wecomchannel.wecom (STANDARD)/features/aibot-config
飞书机器人sira-channel-feishuchannel.feishu (STANDARD)/features/channels/feishu
钉钉机器人 🆕sira-channel-dingtalk— (暂未单独 gate,fail-open)/features/channels/dingtalk(Stream 长连接,无回调地址)
微信客服内置 (adapter)channel.weixin_kf (PROFESSIONAL)/features/channels/wechat-kf/overview
OpenAI 兼容 API内置channel.openai_compat (STANDARD)/features/api-service
LangGraph 兼容 API内置channel.langgraph_compat (PROFESSIONAL)/features/api-service

插件装载机制

Sira 启动时扫描所有声明 sira.channels entry_point 的 Python 包:

toml
# sira-channel-feishu/pyproject.toml
[project.entry-points."sira.channels"]
feishu = "sira_channel_feishu.entrypoint:define_channel_plugin"

每个插件实现 ChannelPlugin 抽象基类(位于 sira-channel-base),按需重写:

方法用途
verify_callback校验渠道平台的回调签名
decode_inbound把渠道平台原始消息解码成 Sira 统一的 ChannelMessage
push_response把编排器输出按渠道格式推送(streaming / 单次)
send_message主动发起的消息(非回复型)

新增渠道 = 新建包 + 实现这几个方法 + 加 entry_point + pip install -e ./ 后即可识别。

ChannelGatewayBridge(DMZ 中转)

License 提示

此功能需要 deploy.dmz_bridge (ENTERPRISE)。

应用场景:Sira 后端运行在纯内网环境,无公网入口,但渠道(飞书 / 企微)的回调必须从公网到达。解决方案:

公网回调


DMZ 区的 channel_gateway_bridge.py 服务(独立部署)
   │  WebSocket 反向隧道

内网 Backend 主动出站连接到 DMZ


回调被转发,结果反向推回

每个 Application 在创建时可选 deployment = "gateway" 走 DMZ 中转,否则默认 local(直接本地处理回调)。

详细部署在 devdocs/CHANNEL_GATEWAY_DEPLOYMENT.md、运维在 devdocs/CHANNEL_GATEWAY_OPS.md

跨渠道用户解析

不同渠道的用户 ID 会通过 users.external_ids[platform_key] 映射回同一个 Sira 用户。例如:

  • 张三在企微的 userid = zhangsan_wecom_idusers.external_ids.wecom = "zhangsan_wecom_id"
  • 张三在飞书的 open_id = ou_xxxusers.external_ids.feishu_bot = "ou_xxx"

两条记录指向同一个 Sira user.id,所以张三在企微装的沙箱 / 创建的定时任务,飞书里也能继续使用。

PlatformKeyapp/extensions/agent_system/services/channel_platform_keys.py 集中管理,含别名映射:wework → wecomlark → feishulark_bot → feishu_botweb → webclientsira → webclient 等。

自动建档

当一个新渠道用户首次和 AI 对话时,平台会自动创建占位 Sira 用户(provider="auto_provisioned",邮箱后缀 .invalid),保证 AI 立即可用,无需员工手动注册。

输出格式归一

ResponseNormalizer 统一处理流式 SSE → 渠道原生格式:

  • 文本类:累计 chunk → 按渠道允许的"流式"或"一次性"形式推送
  • 错误事件 (event=='error'):转成普通文本帧 + 友好提示,避免 AI 突然失声
  • 沙箱安装链接:错误信息中嵌入 /sandbox-install?token=... 短链

对话内命令(斜杠命令)

用户在渠道对话里发送以 / 开头的消息会被当成命令拦截(在路由到编排器之前处理),不消耗 AI 调用。支持渠道:企业微信 AI Bot / 飞书 / 钉钉(经统一渠道管线 + DMZ 中转)。Web 分享页(app-chat)暂不支持斜杠命令。

命令作用
/help列出所有可用命令
/clear显示当前会话信息 + 二次确认提示(不实际删除)
/clear confirm真正清除当前会话的 AI 记忆(确认有效期 5 分钟)
/whoami显示当前 用户 / 应用 / session_id(排查问题时提供给客服)
/wxbind发起微信个人号绑定,返回登录二维码(实验性,依赖 iLink)
/wxunbind解除当前用户的微信绑定
/wxstatus查询微信绑定状态
  • 命令必须以 / 开头;未识别/xxx 会原样交给 AI 处理。
  • /clear 的清除范围仅限 当前应用 × 当前用户 这一组合,不影响该用户在其他应用的上下文(thread_id = {application_id}_{user_id})。
  • 个微绑定(/wxbind 系列)为实验性功能,受腾讯服务条款限制,可能随政策调整不可用。
  • 命令注册表在 app/extensions/agent_system/services/slash_command_dispatcher.py,新增命令只需加一行,/help 会自动收录。

AI 发送文件(MEDIA 标签)

AI 要把一个文件真正发给用户(而不只是口头说"已发送"),必须在回复里输出 MEDIA: 标签。运行时会拦截标签、读取文件、按渠道原生形式投递,并把标签从用户可见文本里删除。只说"文件已发送"却没有标签 = 用户收不到任何东西。

两种写法(按字节来源二选一,不要混用):

来源写法说明
沙箱本地文件MEDIA:/绝对路径只接受沙箱内的绝对文件路径,单独成行(可用反引号包裹)。例:MEDIA:/tmp/report.pdf
已托管的图片 URL![](url)运行时下载该 URL 并作为图片发送。不要把 URL 放到 MEDIA: 后面,会被当成路径而失败

各渠道经 MEDIA 标签支持的文件类型

渠道文档 (pdf/docx/xlsx/pptx/txt/md)图片 (jpg/png/webp/gif)视频 (mp4)音频
飞书附件图片内联播放mp3/wav/m4a → 语音
企业微信附件图片内联播放mp3/wav → 语音
钉钉文件卡片图片
Web 客户端链接下载内联渲染
  • 一条回复最多带一个文件(出现多个标签只取第一个)。
  • 单文件默认上限 30 MiB(环境变量 MEDIA_MAX_BYTES_IN_REDIS 可调),超限会提示换更小的文件。
  • 标签必须指向真实存在的文件;文件没生成时 AI 应先在沙箱里写出文件再输出标签。

给最终用户的小贴士

模型偶尔会只说"文件已发送 / 已发给你"却忘了输出标签,于是你收不到文件。这时直接引导它:

请用 MEDIA: 标签把文件发给我(例如 MEDIA:/tmp/report.pdf)。

或者:「把结果存成 xlsx 后用 MEDIA 标签发我」。文件能不能发,取决于编排器是否带沙箱/文件系统(DeepAgents、或配了技能包的 Single 编排器)。

相关文档

Apache-2.0 Licensed