第 4 章:先部署到 Telegram
目标:先把你的 Bot 接到 Telegram,让它在真实聊天场景中工作;再理解为什么 nanobot 能继续扩展到其他平台。
阅读顺序提示:虽然它排在第 4 章,但第一次跟做时,更推荐你先完成 第 5 章 的
5.1到5.4和5.6,先把 Bot 本身在本地验收通过,再回来接 Telegram。这样能把“Bot 没配对”和“平台没接通”两类问题分开排查。
如果你还没确认 Telegram 账号、Bot Token、数字用户 ID,或者连本地 CLI 都还没跑通,先看 附录:环境预检。
4.1 从 CLI 到 Gateway
前三章我们一直用 nanobot agent 在终端里聊天。现在先选一个最容易上手的平台,把 Bot 真正放进聊天场景里。
关键区别:
| CLI 模式 | Gateway 模式 | |
|---|---|---|
| 命令 | nanobot agent |
nanobot gateway |
| 用户界面 | 终端 | Telegram / 其他聊天平台 |
| 运行方式 | 聊完就退出 | 持续运行,等待消息 |
| 消息来源 | 键盘输入 | 聊天平台 API |
4.2 实操:连接 Telegram
Telegram 是最容易上手的平台。
接平台前,先确认这 3 件事
在继续之前,先停 30 秒确认:
- 你已经能用
nanobot agent -m "你好"在 CLI 中拿到正常回复 - 你改过
SOUL.md或AGENTS.md,并观察到回复确实发生变化 - 你至少让一个 Skill 成功触发过一次
如果这 3 条还没成立,建议先回到前 3 章。否则你接下来一旦收不到 Telegram 回复,会很难判断问题到底出在平台、配置还是 Bot 本身。
第一步:创建 Telegram Bot
- 在 Telegram 里搜索
@BotFather - 发送
/newbot,按提示设置名字 - 复制得到的 Bot Token(格式类似
123456:ABC-DEF...)
第二步:找到你的 Telegram 数字用户 ID
allowFrom 需要的不是用户名,而是你的 数字用户 ID。最简单的取法通常有两种:
- 直接给一些常见的 Telegram ID 查询机器人发消息,读取它返回的数字 ID
- 暂时把
allowFrom设成["*"]做一次本地验证,从日志或调试输出中拿到你的发送者 ID,再立刻改回只允许自己
无论哪种方式,最终都应该拿到类似 123456789 这样的纯数字字符串。
第三步:配置
在第 1 章已经可用的 ~/.nanobot/config.json 基础上,至少补齐下面两段;如果 provider 或 model 还没配好,先回到第 1 章完成:
第一次上线前,先确认两件事:
allowFrom先只放你自己的 Telegram 数字用户 ID;tools.restrictToWorkspace先设为true。allowFrom是安全白名单。空数组[]会拒绝所有人,设为["*"]允许任何人。这里要填的是类似123456789这样的数字 ID,不是用户名,也不带@。
最容易配错的字段:allowFrom
第一次接 Telegram,最常见的误区不是 token,而是 allowFrom:
- 填
@username:错,应该填数字 ID - 填空数组
[]:这会拒绝所有人 - 长时间保留
["*"]:可以临时调试,不建议长期这么放 - 以为“Bot 在线但不回复”一定是 gateway 坏了:很多时候只是白名单没放行
所以第一次最稳的配置是:
第四步:启动
输出:
现在打开 Telegram,给你的 Bot 发消息,它就会回复了。
如果没有回复,先不要急着改代码,按下面顺序排查:
nanobot gateway是否持续运行,没有直接退出- 日志里是否显示
Channels enabled: telegram allowFrom是否真的包含你的 Telegram 数字用户 ID- Bot Token 是否来自正确的 Bot,而不是旧 token
- provider 和 model 是否本来就在 CLI 模式下可用
第一次部署时,建议先用前台运行的 nanobot gateway 调通,不要一开始就放进 systemd 或 Docker。先把“能不能收到消息并回复”这条最短链路跑通,再做后台运行。
4.3 为什么先从 Telegram 开始
Telegram 是最适合做第一站的平台:
- 配置最少,只需要 Bot Token
- 调试路径短,
gateway启动后就能立即发消息验证 - 跑通 Telegram 后,再理解 Discord、Slack、飞书等平台的接入方式会轻松很多
这一章只手把手带你完成 Telegram。其他平台的共性原理和配置形态,放在下面做总览。
4.4 其他平台
每个平台的配置方式类似——在 channels 中启用对应平台并填入凭据:
| 平台 | 关键配置 | 连接方式 |
|---|---|---|
| Telegram | Bot Token | 长轮询 |
| Discord | Bot Token | WebSocket |
| Slack | Bot Token + App Token | Socket Mode |
| 飞书 | App ID + App Secret | WebSocket |
| 钉钉 | Client ID + Client Secret | Stream Mode |
| QR 码扫描 | WebSocket Bridge | |
| App ID + App Secret | WebSocket | |
| IMAP/SMTP 凭据 | 轮询 | |
| Matrix | Access Token | 长连接 |
| 企业微信 / WeCom | Bot ID + Secret | 平台 API |
| Microsoft Teams | App ID + App Password | 公网 HTTPS 回调 |
| Mochat | Claw Token | Socket.IO |
| WebSocket | 本地端口 + Token | 自定义前端 / 脚本接入 |
多个平台可以同时启用——一个 nanobot gateway 进程就能同时服务所有平台。
4.5 多实例部署
如果你想运行多个不同的 Bot(比如一个 Telegram 财务顾问 + 一个 Discord 编程助手),可以用 --config 隔离:
每个实例有独立的配置、工作区、记忆和技能。
原理:消息总线架构
nanobot 能同时支持这么多平台,核心设计是消息总线(MessageBus)。
整体架构
sequenceDiagram
autonumber
participant P as Telegram / CLI / Discord
participant C as Channel
participant B as MessageBus
participant A as AgentLoop
P->>C: 原始平台消息
C->>B: InboundMessage
B->>A: consume_inbound()
A-->>B: publish_outbound()
B-->>C: OutboundMessage
C-->>P: 发回原平台
所有平台的消息都被转换成统一的 InboundMessage 格式,通过 MessageBus 传给 AgentLoop。AgentLoop 不关心消息来自哪个平台——它只处理文本,返回 OutboundMessage,再由 MessageBus 路由到正确的平台。
你可以把整个系统先压缩成一句话:Channel 负责“翻译平台消息”,AgentLoop 负责“统一处理消息”,MessageBus 负责“在两者之间转运消息”。 先抓住这条主线,再去看具体类和字段,会轻松很多。
消息格式
MessageBus 的实现
MessageBus 的核心就是两组方法(nanobot/bus/queue.py):
整个 MessageBus 代码量很小,但实现了完全的解耦——Channel 和 Agent 互不依赖。
为什么这么设计?
- 加新平台零成本:添加一个新 Channel 只需要实现"收消息 → InboundMessage"和"OutboundMessage → 发消息"的转换,不需要改 Agent 的一行代码
- 统一处理:不管消息来自 Telegram 还是 Email,Agent 的处理逻辑完全一样
- 天然支持多平台:同一个 Agent 可以同时服务 Telegram + Discord + Slack,因为它根本不关心消息来源
Gateway 的启动流程
当执行 nanobot gateway 时,可以从 nanobot/cli/commands.py 的 gateway 命令入口往下读:
Session 会话管理
nanobot 用 session_key(格式:channel:chat_id)来区分不同的对话。比如:
- telegram:123456 — Telegram 上 ID 为 123456 的用户的对话
- discord:789012 — Discord 上 ID 为 789012 的用户的对话
- cli:direct — 命令行直接对话
每个 session 有独立的对话历史,互不干扰。
聊天内命令
Gateway 模式下,很多运维动作可以直接在聊天窗口里完成,不必登录服务器改文件:
| 命令 | 作用 |
|---|---|
/new |
停止当前任务并开始新会话 |
/stop |
停止当前正在执行的任务 |
/restart |
重启 Bot 进程 |
/status |
查看版本、模型、上下文、任务等状态 |
/history [n] |
查看当前会话最近 N 条消息 |
/dream |
立即触发 Dream 记忆整理 |
/dream-log |
查看最近一次 Dream 记忆变更 |
/dream-restore |
列出或恢复 Dream 记忆历史版本 |
这些命令的底层入口在 nanobot/command/builtin.py。第一次部署时,/status 和 /history 5 最适合用来确认“消息确实进入了正确会话”。
4.6 安全配置
部署到公网后,安全很重要:
restrictToWorkspace:沙箱模式
设为 true 后,Bot 的所有文件操作和 shell 命令都被限制在工作区内,无法访问系统其他目录。生产环境强烈建议开启。
allowFrom:访问白名单
[](空数组):拒绝所有人(默认,最安全)["123456789"]:只允许指定用户["*"]:允许所有人(谨慎使用)- 这里的值是 Telegram 的数字用户 ID,不是
@username
4.7 后台运行
使用 systemd(Linux 推荐)
创建 ~/.config/systemd/user/nanobot-gateway.service:
启动:
查看日志:
使用 Docker
当前官方 Dockerfile 默认使用非 root 用户 nanobot,所以配置目录应挂载到 /home/nanobot/.nanobot。如果遇到权限问题,优先检查宿主机上 ~/.nanobot 的 owner / mode,而不是改容器内路径。
4.8 验证与排障
部署成功后,至少确认下面几项:
- gateway 进程持续存活
- 日志里能看到启用的 channel
- 从目标平台发消息后,能看到 inbound 处理痕迹或回复结果
- 会话目录中开始出现对应 session 文件
常见问题:
- 进程一启动就退出:通常是配置缺失、token 错误或 provider 初始化失败
- Bot 在线但不回复:先检查
allowFrom、平台回调权限和日志报错 - 回复串台:检查
chat_id/session_key的隔离逻辑,而不是只看最终文本 - Docker 中能启动但平台不可达:通常是挂载配置没进去,或容器内缺少本地依赖
如果你想快速缩小范围,最有效的顺序是:
- 先确认 CLI 模式本来就能回复
- 再确认
gateway进程持续存活 - 再确认 Telegram channel 已启用
- 再确认
allowFrom放行了你自己 - 最后才去怀疑平台侧或 Docker/systemd
如果你已经分不清问题是在 CLI、Skill、provider,还是 Telegram 这一层,先回到附录:常见坑与排障按分层方式排查。
总结:你的 Bot 全貌
经过前四章的学习,你已经理解了 nanobot 的完整架构:
你定制的每一部分都对应架构中的一个模块:
| 你做的事 | 对应的模块 |
|---|---|
| 改 config.json | providers / channels |
| 改 SOUL.md / AGENTS.md | ContextBuilder |
| 创建 Skill | SkillsLoader |
| 编辑 MEMORY.md | MemoryStore |
核心实现规模依然相当克制,却实现了一个功能完备的 AI Agent。这就是 nanobot "超轻量"的含义——不是功能少,而是设计精炼。
下一章我们不再新增概念,而是把前四章真正串起来,做出一个从配置、定制、扩展到 Telegram 上线都完整闭环的 Bot。