网关与频道
Octos 以网关模式运行,将各消息平台桥接到你的 LLM 智能体。每个平台连接称为一个频道。你可以在同一个网关进程中同时运行多个频道——例如同时接入 Telegram 和 Slack。
频道概览
频道在 config.json 的 gateway.channels 数组中配置。每个条目指定一个 type、可选的 allowed_senders 用于访问控制,以及平台特定的 settings。
查看已编译和已配置的频道:
octos channels status
该命令会显示一张表格,列出每个频道的编译状态(feature flags)和配置摘要(环境变量的设置情况)。
Telegram
需要从 @BotFather 获取 bot token。
export TELEGRAM_BOT_TOKEN="123456:ABC..."
{
"type": "telegram",
"allowed_senders": ["your_user_id"],
"settings": {
"token_env": "TELEGRAM_BOT_TOKEN"
}
}
Telegram 支持 bot 命令、内联键盘、语音消息、图片和文件。
Slack
需要一个 Socket Mode 应用,同时提供 bot token 和 app-level token。
export SLACK_BOT_TOKEN="xoxb-..."
export SLACK_APP_TOKEN="xapp-..."
{
"type": "slack",
"settings": {
"bot_token_env": "SLACK_BOT_TOKEN",
"app_token_env": "SLACK_APP_TOKEN"
}
}
Discord
需要从 Discord Developer Portal 获取 bot token。
export DISCORD_BOT_TOKEN="..."
{
"type": "discord",
"settings": {
"token_env": "DISCORD_BOT_TOKEN"
}
}
需要一个运行在 WebSocket URL 上的 Node.js 桥接(Baileys)。
{
"type": "whatsapp",
"settings": {
"bridge_url": "ws://localhost:3001"
}
}
飞书(中国版)
飞书默认使用 WebSocket 长连接模式(无需公网 URL)。
export FEISHU_APP_ID="cli_..."
export FEISHU_APP_SECRET="..."
{
"type": "feishu",
"settings": {
"app_id_env": "FEISHU_APP_ID",
"app_secret_env": "FEISHU_APP_SECRET"
}
}
构建时需启用 feishu feature flag:
cargo build --release -p octos-cli --features feishu
Lark(国际版)
Lark(国际版飞书)不支持 WebSocket 模式,需改用 webhook 模式——由 Lark 通过 HTTP POST 将事件推送到你的服务器。
Lark Cloud --> ngrok --> localhost:9321/webhook/event --> Gateway --> LLM
开发者控制台配置
- 前往 open.larksuite.com/app,创建或选择一个应用
- 在 Features 下添加 Bot 能力
- 配置事件订阅:
- Events & Callbacks > Event Configuration > Edit subscription method
- 选择 “Send events to developer server”
- 将请求 URL 设为
https://YOUR_NGROK_URL/webhook/event
- 添加事件:
im.message.receive_v1(接收消息) - 启用权限:
im:message、im:message:send_as_bot、im:resource - 发布应用:App Release > Version Management > Create Version > Apply for Online Release
配置
export LARK_APP_ID="cli_..."
export LARK_APP_SECRET="..."
{
"type": "lark",
"allowed_senders": [],
"settings": {
"app_id_env": "LARK_APP_ID",
"app_secret_env": "LARK_APP_SECRET",
"region": "global",
"mode": "webhook",
"webhook_port": 9321
}
}
配置项参考
| 配置项 | 说明 | 默认值 |
|---|---|---|
app_id_env | App ID 的环境变量名 | FEISHU_APP_ID |
app_secret_env | App Secret 的环境变量名 | FEISHU_APP_SECRET |
region | "cn"(飞书)或 "global" / "lark"(Lark 国际版) | "cn" |
mode | "ws"(WebSocket)或 "webhook"(HTTP) | "ws" |
webhook_port | webhook HTTP 服务端口 | 9321 |
encrypt_key | Lark 控制台的 Encrypt Key(用于 AES-256-CBC) | 无 |
verification_token | Lark 控制台的 Verification Token | 无 |
加密(可选)
如果你在 Lark 控制台(Events & Callbacks > Encryption Strategy)配置了 Encrypt Key,需将其添加到配置中:
{
"type": "lark",
"settings": {
"app_id_env": "LARK_APP_ID",
"app_secret_env": "LARK_APP_SECRET",
"region": "global",
"mode": "webhook",
"webhook_port": 9321,
"encrypt_key": "your-encrypt-key-here",
"verification_token": "your-verification-token"
}
}
启用加密后,Lark 会发送加密的 POST 请求体。网关使用 SHA-256 密钥派生的 AES-256-CBC 进行解密,并通过 X-Lark-Signature 头验证签名。
支持的消息类型
入站消息: 文本、图片、文件(PDF、文档)、音频、视频、表情包
出站消息: Markdown(通过互动卡片)、图片上传、文件上传
运行
# 启动 ngrok 隧道
ngrok http 9321
# 启动网关
LARK_APP_ID="cli_xxxxx" LARK_APP_SECRET="xxxxx" octos gateway --cwd /path/to/workdir
常见问题排查
| 问题 | 解决方案 |
|---|---|
| WS 端点返回 404 | Lark 国际版不支持 WebSocket,请使用 "mode": "webhook" |
| Challenge 验证失败 | 确认 ngrok 正在运行且 URL 与 Lark 控制台中的一致 |
| 收不到事件 | 添加事件后需发布应用版本;检查控制台中的 Event Log |
| 机器人不回复 | 确认已授予 im:message:send_as_bot 权限 |
| Ngrok URL 变了 | 免费 ngrok URL 每次重启都会变化,需在 Lark 控制台更新请求 URL |
邮件(IMAP/SMTP)
通过 IMAP 轮询收件箱获取入站消息,通过 SMTP 发送回复。需启用 email feature flag。
export EMAIL_USERNAME="bot@example.com"
export EMAIL_PASSWORD="app-specific-password"
{
"type": "email",
"allowed_senders": ["trusted@example.com"],
"settings": {
"imap_host": "imap.gmail.com",
"imap_port": 993,
"smtp_host": "smtp.gmail.com",
"smtp_port": 465,
"username_env": "EMAIL_USERNAME",
"password_env": "EMAIL_PASSWORD",
"from_address": "bot@example.com",
"poll_interval_secs": 30,
"max_body_chars": 10000
}
}
企业微信(WeCom)
需要一个配置了消息回调 URL 的自建应用。需启用 wecom feature flag。
export WECOM_CORP_ID="ww..."
export WECOM_AGENT_SECRET="..."
{
"type": "wecom",
"settings": {
"corp_id_env": "WECOM_CORP_ID",
"agent_secret_env": "WECOM_AGENT_SECRET",
"agent_id": "1000002",
"verification_token": "...",
"encoding_aes_key": "...",
"webhook_port": 9322
}
}
微信(通过 WorkBuddy 桥接)
普通微信用户可以通过 WorkBuddy 桌面端桥接连接到你的智能体。WorkBuddy 负责微信传输层;Octos 通过其 WeCom Bot 频道处理 AI 逻辑。
微信(手机) --> WorkBuddy(桌面端) --> 企业微信群机器人(WSS) --> octos wecom-bot 频道
配置步骤
-
在企业微信管理后台的“应用管理 > 群机器人“中创建一个企业微信群机器人,记下 Bot ID 和 Secret。
-
配置
wecom-bot频道:
export WECOM_BOT_SECRET="your_robot_secret_here"
{
"type": "wecom-bot",
"allowed_senders": [],
"settings": {
"bot_id": "YOUR_BOT_ID",
"secret_env": "WECOM_BOT_SECRET"
}
}
- 构建并启动:
cargo build --release -p octos-cli --features "wecom-bot"
octos gateway
- 安装 WorkBuddy 桌面客户端,通过扫码关联你的微信,并连接到同一个企业微信群机器人。
连接详情
| 属性 | 值 |
|---|---|
| 协议 | WebSocket (WSS) |
| 端点 | wss://openws.work.weixin.qq.com |
| 心跳 | 每 30 秒 Ping/pong |
| 自动重连 | 支持,指数退避(5s–60s) |
| 最大消息长度 | 4096 字符 |
| 消息格式 | Markdown |
wecom-bot 频道使用出站 WebSocket 连接——无需公网 URL 或端口转发。适合部署在 NAT 或防火墙后的服务器。
限制
- 仅支持文本 – 语音和图片消息以占位符形式传递
- 不支持消息编辑 – 回复以新消息形式发送
- 单向触发 – 微信到 Octos 自动触发;主动推送需使用定时任务
DingTalk(钉钉)
钉钉支持通过自定义机器人向外发送消息,以及接收 outgoing-robot 回调。
export DINGTALK_BOT_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=..."
export DINGTALK_BOT_SECRET="SEC..."
{
"type": "dingtalk",
"allowed_senders": ["staff-id-1"],
"settings": {
"webhook_url_env": "DINGTALK_BOT_WEBHOOK",
"secret_env": "DINGTALK_BOT_SECRET",
"webhook_port": 8650
}
}
入站事件请配置钉钉 outgoing 机器人的回调 URL。在 octos serve 之后使用代理路由;在独立的 octos gateway 模式下,则指向该渠道自带的 webhook 服务器(webhook_port):
# 在 octos serve 之后(代理)
https://YOUR_OCTOS_HOST/webhook/dingtalk/<profile_id>
# 独立的 octos gateway
http://YOUR_OCTOS_HOST:<webhook_port>/dingtalk/webhook
使用 dingtalk 特性标志编译:
cargo build --release -p octos-cli --features dingtalk
Matrix
Matrix 是一等公民频道,也是本章多处提到的「人工审批」与「管理机器人」功能背后的传输层。由 matrix 特性门控。通过 mode 设置支持两种模式:
user——以普通 Matrix 账户身份通过 Client-Server API 与/sync登录。可用于任意 homeserver 上的任意账户,无需服务端注册。appservice——以应用服务(application service)身份注册到你自控的 homeserver(Conduit/conduwuit/Synapse),可为每个用户提供 bot 分身。
当省略 mode 时,网关会回退到 appservice(此时需要 as_token/hs_token),因此进行普通账户登录时请显式设置 "mode": "user"。
user 模式
{
"type": "matrix",
"settings": {
"mode": "user",
"homeserver": "https://matrix.org",
"user_id": "@mybot:matrix.org",
"access_token": "syt_...",
"device_name": "octos",
"rooms": ["!roomid:matrix.org"],
"auto_join": "allowlist",
"auto_join_allowlist": ["!roomid:matrix.org", "#alias:matrix.org"]
}
}
使用 access_token(推荐)登录,或使用 user_id + password(密码登录两者都必需)。这些凭据以字面 settings 值读取——不会从环境变量展开。auto_join(off / allowlist / always)控制邀请的自动接受;在 allowlist 下,auto_join_allowlist 列出被接受邀请的房间 ID / 别名(或 *)——按房间匹配,而非邀请者用户 ID——为空时回退到 rooms。
appservice 模式
{
"type": "matrix",
"settings": {
"mode": "appservice",
"homeserver": "http://localhost:6167",
"server_name": "localhost",
"as_token": "...",
"hs_token": "...",
"sender_localpart": "bot",
"user_prefix": "bot_"
}
}
使用 matrix 特性标志编译。在 appservice / 管理机器人房间中,Matrix 会为人工审批规则渲染原生的 批准/拒绝 卡片(通过 Robrix),并处理 /schedule、/schedules、/unschedule、/allbots 聊天命令(见下文定时任务)。而普通的 mode: "user" 账户渠道本身并不解释这些管理命令;它会把消息文本转发给 agent,但默认仅在机器人被 @ 提及时转发(require_mention 默认为 true——在其 settings 中设置 "require_mention": false 可转发每一条消息)。
LINE
入站 webhook + 出站 Messaging API。由 line 特性门控。
export LINE_CHANNEL_SECRET="..."
export LINE_CHANNEL_ACCESS_TOKEN="..."
{
"type": "line",
"settings": {
"channel_secret_env": "LINE_CHANNEL_SECRET",
"channel_access_token_env": "LINE_CHANNEL_ACCESS_TOKEN",
"webhook_port": 9323,
"bot_user_id": "U...",
"require_mention": false
}
}
在独立的 octos gateway 模式下,LINE 将事件推送到该渠道自带的 webhook 服务器 http://YOUR_OCTOS_HOST:<webhook_port>/line/webhook;在 octos serve 之后,则改用代理路由 https://YOUR_OCTOS_HOST/webhook/line/<profile_id>。入站签名针对请求体用 channel secret 校验(HMAC-SHA256),因此两种 URL 均可用。使用 line 特性标志编译。
Twilio(短信)
通过 Twilio Programmable Messaging webhook 实现双向短信。由 twilio 特性门控。
export TWILIO_ACCOUNT_SID="AC..."
export TWILIO_AUTH_TOKEN="..."
{
"type": "twilio",
"settings": {
"account_sid_env": "TWILIO_ACCOUNT_SID",
"auth_token_env": "TWILIO_AUTH_TOKEN",
"from_number": "+15551234567",
"webhook_port": 9324
}
}
将你的 Twilio 号码的入站 webhook 指向该渠道自带的 webhook 服务器:http://YOUR_OCTOS_HOST:<webhook_port>/twilio/webhook。Twilio 的 X-Twilio-Signature 会针对完整重建的 URL 校验,而该 URL 由请求的 Host 与 X-Forwarded-Proto 头构建(scheme 默认为 http)。在 HTTPS 反向代理之后,代理必须保留 /twilio/webhook 路径,并转发公网主机名与 X-Forwarded-Proto: https——否则重建出的 URL 是 http://…,签名校验会失败(403)。使用 twilio 特性标志编译。
会话控制命令
在任何网关频道中,以下命令用于管理对话会话:
| 命令 | 说明 |
|---|---|
/new | 清空当前会话(裸 /new 会清空历史,等同于 /clear) |
/new <name> | 切换到(或创建)具名会话 |
/s <name> | 切换到指定名称的会话 |
/s | 切换到默认会话 |
/sessions | 列出当前聊天的所有会话 |
/back | 切换到上一个活跃会话 |
/delete | 删除当前会话 |
每个聊天同一时间只有一个活跃会话。消息会路由到活跃会话。非活跃会话仍可执行后台任务(深度搜索、流水线等)。当非活跃会话完成工作时,你会收到通知——使用 /s <name> 查看结果。
语音转写
来自频道的语音和音频消息在发送给智能体前会自动转写。系统优先尝试本地 ASR(通过 OminiX 引擎),本地不可用时降级到云端 Whisper。转写结果会以 [transcription: ...] 的形式前置。
# 本地 ASR(优先) -- 由 octos serve 自动设置
export OMINIX_API_URL="http://localhost:8080"
# 云端降级
export GROQ_API_KEY="gsk_..."
config.json 中的语音配置:
{
"voice": {
"auto_asr": true,
"auto_tts": true,
"default_voice": "vivian",
"asr_language": null
}
}
auto_asr– 自动转写收到的语音/音频消息auto_tts– 用户发送语音时自动合成语音回复default_voice– 自动 TTS 的语音预设asr_language– 强制指定转写语言(null= 自动检测)
访问控制
使用 allowed_senders 限制谁可以与智能体交互。空列表表示允许所有人。
{
"type": "telegram",
"allowed_senders": ["123456", "789012"]
}
每种频道类型使用各自的发送者标识格式(Telegram 用户 ID、邮箱地址、企业微信用户 ID 等)。
定时任务
智能体可以调度周期性任务,通过任意频道发送消息:
octos cron list # 列出活跃任务
octos cron list --all # 包含已禁用的任务
octos cron add --name "report" --message "Generate daily report" --cron "0 0 9 * * * *"
octos cron add --name "check" --message "Check status" --every 3600
octos cron add --name "once" --message "Run migration" --at "2025-03-01T09:00:00Z"
octos cron remove <job-id>
octos cron enable <job-id> # 启用任务
octos cron enable <job-id> --disable # 禁用任务
任务支持可选的 timezone 字段,使用 IANA 时区名称(如 "America/New_York"、"Asia/Shanghai")。未指定时使用 UTC。
消息合并
长回复会自动拆分为符合频道限制的分段:
| 频道 | 每条消息最大字符数 |
|---|---|
| Telegram | 4000 |
| Discord | 1900 |
| Slack | 3900 |
拆分优先级:段落边界 > 换行符 > 句末 > 空格 > 硬截断。
配置热更新
网关会自动检测配置文件变更:
- 热更新(无需重启):系统提示词、AGENTS.md、SOUL.md、USER.md
- 需要重启:服务商、模型、API 密钥、频道设置
变更通过 SHA-256 哈希检测,并附带防抖机制。