分类: Discord 机器人开发

Discord 机器人开发#9接入 AI(Claude·ChatGPT API)!(Python 示例)

本文译自韩语原文。

目录8 项

大家好!我是 Mojangcam 😎

上一篇 #8 我们学了用嵌入消息(Embed)把机器人的消息装饰得更漂亮。这一篇终于要做很多人期待已久的功能:给机器人接入 AI!只要像 /ai 질문(参数名意为"问题")这样输入,Claude 或 ChatGPT 就会给出回答。

服务器成员可以随时向 AI 提问,服务器规则说明、翻译、代码问题解答这些事情也都能交给一个机器人处理,用处真的非常多。

※ 上图并不是实际运行画面。因为我还没有给 API 充值额度,所以先放了一张临时制作的示例图来代替真实的调用结果。等充值之后会换成真实的运行截图!

⚠️ 开始之前先说一点:AI API 和机器人、库不一样,是按用量小额计费的付费服务。不过如果只是个人服务器用的机器人,使用轻量模型的话一个月也就几百韩元(几块人民币)左右,负担不大。

📌 准备工作

  • Python 3.8 及以上
  • discord.py 2.x
  • anthropic 库(用于 Claude API)或 openai 库(用于 ChatGPT)
  • API 密钥:Claude 在 platform.claude.com 申请,ChatGPT 在 platform.openai.com 申请(需要充值少量额度)
mipsasm
pip install -U discord.py anthropic python-dotenv

本文以 Claude API 为准进行讲解,最后也会给出 ChatGPT(OpenAI)版本。

📌 第 1 步 - 用 .env 安全保管 API 密钥

机器人 Token 也是一样,但 AI API 密钥是绑定了付费计费的密钥,一旦泄露真的会出大事。一定要把它单独放进 .env 文件。

INI
# .env
DISCORD_TOKEN=봇토큰
ANTHROPIC_API_KEY=sk-ant-...

📌 第 2 步 - 用 /ai 命令调用 Claude

Python
import discord
from discord import app_commands
from anthropic import AsyncAnthropic

ai = AsyncAnthropic()  # 自动读取 ANTHROPIC_API_KEY 环境变量

@tree.command(name="ai", description="向 AI 提问")
async def ai_command(interaction: discord.Interaction, 질문: str):
    await interaction.response.defer()  # ⭐ 关键!参见下方说明
    result = await ai.messages.create(
        model="claude-haiku-4-5",
        max_tokens=1000,
        system="你是 Discord 服务器里热心的助手。请简洁地回答。",
        messages=[{"role": "user", "content": 질문}],
    )
    answer = result.content[0].text
    await interaction.followup.send(answer[:2000])

我们逐个拆开来看 💡

  • AsyncAnthropic:discord.py 是异步(async)运行的,所以一定要用异步客户端。如果直接用 Anthropic(),AI 回答期间整个机器人都会卡住!
  • defer():Discord 规定斜杠命令3 秒内不响应就判定为失败。AI 的回答通常都会超过 3 秒,所以必须先用 defer 进入"正在思考..."状态,把回复往后推
  • model:示例用的是又快又便宜的 claude-haiku-4-5。如果需要更聪明的回答,换成 claude-sonnet-5 就行(费用会上涨)
  • system:决定机器人性格和角色的部分。可以按照服务器的主题随意修改
  • [:2000]:Discord 消息最多 2,000 字,截断后再发送才不会报错

📌 第 3 步 - 让机器人记住对话(可选)

上面的代码每次都是新对话,记不住上一个问题。下面让它按频道记住最近 10 条对话。

vim
from collections import defaultdict

history = defaultdict(list)  # 按频道 ID 保存的对话记录

async def ask_ai(channel_id: int, 질문: str) -> str:
    history[channel_id].append({"role": "user", "content": 질문})
    result = await ai.messages.create(
        model="claude-haiku-4-5",
        max_tokens=1000,
        system="你是 Discord 服务器里热心的助手。",
        messages=history[channel_id][-10:],  # 只传最近 10 条
    )
    answer = result.content[0].text
    history[channel_id].append({"role": "assistant", "content": answer})
    return answer

我们逐个拆开来看 💡

  • history[channel_id][-10:]:如果把整段对话都发过去,Token 费用会越来越高。只截取最近 10 条是省钱的关键!
  • 保存 assistant 角色:把 AI 的回答也存进记录里,才能实现"刚才你说的那个"这种连续对话

📌 完整代码(可直接复制)

Python
# discord.py 2.x / anthropic 最新版 / Python 3.8+
import os
import discord
from discord import app_commands
from collections import defaultdict
from anthropic import AsyncAnthropic
from dotenv import load_dotenv

load_dotenv()

intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)
ai = AsyncAnthropic()
history = defaultdict(list)

@client.event
async def on_ready():
    await tree.sync()
    print(f"{client.user} 登录成功!")

@tree.command(name="ai", description="向 AI 提问")
async def ai_command(interaction: discord.Interaction, 질문: str):
    await interaction.response.defer()
    try:
        history[interaction.channel_id].append({"role": "user", "content": 질문})
        result = await ai.messages.create(
            model="claude-haiku-4-5",
            max_tokens=1000,
            system="你是 Discord 服务器里热心的助手。请简洁地回答。",
            messages=history[interaction.channel_id][-10:],
        )
        answer = result.content[0].text
        history[interaction.channel_id].append({"role": "assistant", "content": answer})
        await interaction.followup.send(answer[:2000])
    except Exception as e:
        await interaction.followup.send(f"⚠️ 出错了:{e}")

client.run(os.getenv("DISCORD_TOKEN"))

💡 想用 ChatGPT(OpenAI)?只要把调用部分改成这样就行(pip install openai,环境变量 OPENAI_API_KEY)。

makefile
from openai import AsyncOpenAI
ai = AsyncOpenAI()

result = await ai.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "system", "content": "你是热心的助手。"},
              {"role": "user", "content": 질문}],
)
answer = result.choices[0].message.content

OpenAI 唯一的区别是system 消息也要放进 messages 里,整体结构几乎一样。

📌 运行结果

启动机器人后,在服务器里输入 /ai 파이썬이 뭐야?("Python 是什么?"),会先短暂显示"正在思考...",随后 AI 的回答就会发到频道里。在同一个频道继续提问,它会记住前面的对话再回答!

※ 这张对话图同样是因为 API 费用问题临时制作的示例图。(并非实际运行画面)

📌 常见报错

  1. 404 Not Found 或 Unknown interaction — 原因:没有在 3 秒内响应,就直接调用了 response.send_message。解决:一定要先 defer() → 再用 followup.send() 回复
  2. authentication_error (401) — 原因:API 密钥写错、缺失或过期。解决:重新检查 .env 里的密钥,并在控制台确认额度余额
  3. HTTPException: Must be 2000 or fewer in length — 原因:AI 的回答超过了 2,000 字。解决:像示例那样用 [:2000] 截断,或者内容较长时拆成多条消息发送
  4. rate_limit_error (429) — 原因:短时间内请求过于集中。解决:最好给命令加上冷却时间 — 冷却的实现会在下一篇讲解!

📌 结语

今天我们把 Claude·ChatGPT API 接入了机器人,做出了真正的"AI 机器人"。用 defer 绕开 3 秒限制,再加上按频道记忆对话,使用体验会一下子提升很多。下一篇会讲防止滥用 AI 命令的冷却时间与权限管理。敬请期待 🙌

📚 Discord 机器人开发系列

  • #1 ~ #4 基础篇
  • #5 按钮(Button)交互
  • #6 下拉菜单(Select Menu)
  • #7 用模态框(Modal)接收输入
  • #8 用嵌入消息(Embed)的图片和字段美化消息
  • #9 接入 AI(Claude·ChatGPT API)← 就是这一篇!
  • 番外:24 小时免费托管大全

连载 · 共 32 篇中的第 9 篇

Discord 机器人开发

  1. #1Discord 机器人开发 - Slash Command 完全攻略!
  2. #2为 Slash Command 添加选项(Arguments)!
  3. #3在 Slash Command 中添加子命令(Subcommand)!
  4. #4用 Slash Command 发送 Embed 嵌入消息!
  5. #5实现按钮(Button)交互!
  6. #6实现下拉菜单(Select Menu)!
  7. #7用模态框(Modal)接收用户输入(Python 示例)
  8. #8用嵌入消息(Embed)的图片和字段美化消息(Python 示例)
  9. #9接入 AI(Claude·ChatGPT API)!(Python 示例)当前文章
  10. #10支持多语言(i18n)!(Python 示例)
  11. #11用 Flask 制作网页仪表盘!(Python 示例)
  12. #12管理命令冷却时间(Cooldown)与权限(Permission)!(Python 示例)
  13. #13用身份组·频道自动化管理服务器!(Python 示例)
  14. #14保存数据!JSON vs SQLite(Python 示例)
  15. #15슬래시 명령어 그룹(Group)으로 명령어 정리하기! (파이썬 예제) (韩语)
  16. #16리마인더·알림 기능 만들기! 봇이 먼저 말 걸게 하기 (파이썬 예제) (韩语)
  17. #17RAG로 문서 기반 답변봇 만들기! 우리 서버 전용 FAQ 봇 (파이썬 예제) (韩语)
  18. #18투표(Poll) 기능 만들기! 다수결로 정하는 서버 규칙 (파이썬 예제) (韩语)
  19. #19Cog로 코드 쪼개기! 1000줄 봇도 안 더러워지는 구조 (파이썬 예제) (韩语)
  20. #20자동 환영 메시지·온보딩 만들기! 규칙 동의 버튼으로 자동 역할 부여 (파이썬 예제) (韩语)
  21. #21키워드 자동응답·금지어 필터 만들기! 경고 누적으로 자동 제재까지 (파이썬 예제) (韩语)
  22. #22슬래시 명령어 자동완성(Autocomplete) 만들기! 금지어를 골라서 추가·삭제 (파이썬 예제) (韩语)
  23. #23aiosqlite로 비동기 DB 제대로 설계하기! JSON 탈출 (파이썬 예제) (韩语)
  24. #24채널 난독화(Channel Obfuscation) 대응하기! 11/16부터 안 보이는 채널이 생겨요 (파이썬 예제) (韩语)
  25. #25봇이 죽지 않게! 에러 핸들링·로깅 체계 잡기 (파이썬 예제) (韩语)
  26. #26티켓(Ticket) 문의 시스템 만들기! 버튼 하나로 1:1 상담 채널 자동 생성 (파이썬 예제) (韩语)
  27. #27티켓 담당자 배정·우선순위 만들기! 스태프가 여러 명이어도 안 꼬이게 (파이썬 예제) (韩语)
  28. #28레벨·경험치(XP) 시스템 만들기! 채팅할수록 레벨업, 랭킹판까지 (파이썬 예제) (韩语)
  29. #29화폐·상점(Economy) 시스템 만들기! 코인 벌어서 아이템 사기 (파이썬 예제) (韩语)
  30. #30打造投票·问卷(Poll)机器人!原生投票 + 按钮实时统计(Python 示例)🗳️
  31. #32打造服务器日志·审核日志(Audit Log)频道!自动记录消息删除、编辑、成员进出和踢出(Python 示例)🕵️
  32. #33임시 음성방 확장, 파티방 만들기! 방장 위임·강퇴·초대 전용(비공개) 방 + 전용 채팅방 자동 생성 (파이썬 예제) 🎉 (韩语)
显示全部 32 篇收起

作者

Mojangcam

亲手写代码、跑服务器、解决卡住的报错,把一路学到的东西记录下来的开发与 IT 实战博客