手把手教你用 Python 写一个 Telegram AI 机器人:从零到能聊天,附完整代码。
前言:最近把手里一个闲置的 Telegram Bot 翻出来,给它接上了大模型,效果意外不错。整个过程踩了几个版本的坑,索性整理成文,分享给想动手的朋友。全程只讲技术,不涉及其他。
为什么选 Telegram Bot 做练手项目
如果你最近想做一个"能被真实用户使用"的 AI 应用,Telegram Bot 几乎是最低成本的路:
-
Bot 注册零成本,跟官方账号聊几句就完事
-
天然解决前端问题——聊天窗口就是 UI,不用写页面
-
消息推送、文件收发、按钮交互都是现成的
-
部署简单,一台几十块一年的小鸡都能跑
所以这篇文章就带你从零写一个能接入大模型的 Bot,支持上下文记忆、Markdown 渲染,代码可以直接拿去改着用。
一、注册 Bot,拿到 Token
打开 Telegram,搜索官方账号 @BotFather,发送 /newbot,按提示给 Bot 起名字和用户名(用户名必须以 bot 结尾),它会回给你一串 Token,长这样:
7123456789:AAHq8xxxxxxxxxxxxxxxxxxxxxxx
这串 Token 就是 Bot 的"钥匙",后面所有请求都靠它。注意别提交到 Git 仓库,我一般是放 .env 文件里。
顺手再发一条 /setdescription 和 /setabouttext,把 Bot 的介绍填了,不然用户搜到的时候一脸空白。
二、环境准备
技术栈很简单:Python 3.10+,核心库就两个:
pip install python-telegram-bot openai python-dotenv
这里重点说一下坑:python-telegram-bot 从 v20 开始全面转向了异步,网上一大批老教程的同步写法直接跑不通,新手最容易卡在这。所以本文所有代码基于 v21+ 的异步写法,照着抄不会错。
三、先跑通一个 Echo Bot
不管做什么 Bot,第一步永远是先让消息"进得来、回得去"。新建 bot.py:
import os
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
load_dotenv()
TOKEN = os.getenv("BOT_TOKEN")
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("你好,我是活的,请吩咐。")
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
text = update.message.text
await update.message.reply_text(f"你刚说:{text}")
def main():
app = Application.builder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
app.run_polling()
if __name__ == "__main__":
main()
.env 文件:
BOT_TOKEN=7123456789:AAHq8xxxxxxxxxxxxxxxxxxxxxxx
跑起来:
python bot.py
去 Telegram 给你的 Bot 发消息,能原样回给你,说明链路通了。这个环节如果收不到消息,九成九是 Token 复制错了,或者公司网络把 api.telegram.org 的请求拦了,别怀疑人生。
四、接入大模型,让它真的会聊天
Echo 没意思,上主菜。这里用 OpenAI 兼容的 SDK 写法,这样不管你用的是官方 API 还是任何兼容服务,只改一个 base_url 就行:
from openai import AsyncOpenAI
ai_client = AsyncOpenAI(
api_key=os.getenv("AI_API_KEY"),
base_url=os.getenv("AI_BASE_URL"), # 兼容接口地址
)
完整的聊天逻辑:收到消息 → 取这个用户的历史记录 → 拼成 messages → 调模型 → 回复。直接替换掉上面的 echo 函数:
# 用字典存每个用户的对话历史,key 是 user_id
# 正式项目请换 Redis 或数据库,重启就丢的内存版只适合自用
history_store = {}
SYSTEM_PROMPT = "你是一个友善、简洁的中文助手,回答控制在 300 字以内。"
async def chat(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
user_text = update.message.text
history = history_store.setdefault(user_id, [
{"role": "system", "content": SYSTEM_PROMPT}
])
history.append({"role": "user", "content": user_text})
# 防止历史无限膨胀,只保留最近 20 轮
if len(history) > 41:
history[:] = [history[0]] + history[-40:]
try:
resp = await ai_client.chat.completions.create(
model="gpt-4o-mini", # 换成你在用的模型名
messages=history,
temperature=0.7,
)
answer = resp.choices[0].message.content
history.append({"role": "assistant", "content": answer})
await update.message.reply_text(answer)
except Exception as e:
await update.message.reply_text(f"模型那边出问题了:{e}")
到这一步,Bot 已经能正经聊天了,记得上下文。发给朋友玩玩,基本都说不出"这是机器人在回"。
五、两个必做的体验优化
1. Markdown 渲染
模型回复默认是纯文本,像代码、列表这种格式显示得很丑。Telegram 支持 MarkdownV2,加一个参数就行:
await update.message.reply_text(
answer,
parse_mode="MarkdownV2"
)
但注意!MarkdownV2 对转义极其严格,.、(、! 这些符号不转义直接报错。实用做法是先渲染,失败了降级回纯文本:
try:
await update.message.reply_text(answer, parse_mode="MarkdownV2")
except Exception:
await update.message.reply_text(answer)
我反正是偷懒直接纯文本,看个人追求。
2. 打字状态提示
模型生成要好几秒,用户盯着空白对话框会以为挂了。加一行"正在输入"的状态,体验立刻不一样:
await context.bot.send_chat_action(
chat_id=update.effective_chat.id,
action="typing"
)
放在调模型之前即可。
六、部署:polling 还是 webhook
本地跑用 run_polling() 够了,简单粗暴。上生产的话两个选择:
-
polling:你的服务器主动轮询 Telegram 拿消息,代码简单,适合 QPS 低的 Bot。缺点是有秒级延迟。
-
webhook:Telegram 把消息推给你的回调地址,实时性好,但需要域名 + HTTPS 证书。
个人项目 polling 完全够用,别为了 webhook 那几百毫秒的优化给自己找事。一台便宜云服务器,nohup python bot.py & 挂后台,配合 systemd 或者 supervisor 保活,齐活。
总结
整件事拆开看就四步:BotFather 拿 Token → 装好 python-telegram-bot → 跑通收发 → 拼 messages 调模型。核心代码不到一百行,但已经是一个有上下文记忆的 AI 聊天机器人。
这玩意的扩展空间也很大:加 /clear 命令清空记忆、接语音消息转文字、做成群组里的问答助手、挂定时任务推送日报……都是在这个骨架上长出来的。
最后提醒三个最容易翻车的点:Token 别泄露、v20 之后必须异步写法、对话历史要设上限(不然 token 费用会教你做人)。
有问题评论区见,踩到新坑也欢迎来补充。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)