基于OpenClaw的单网关多智能体Discord机器人部署实践
1. 项目概述一个网关两个智能体如果你正在寻找一个方案想在同一台服务器上同时运行一个私密的个人AI助手和一个面向公众的Discord群聊机器人并且希望它们彼此独立、互不干扰那么这个基于OpenClaw的多智能体Discord部署模板可能就是你要找的答案。简单来说这个项目提供了一个完整的、可直接用于生产环境的参考架构。它核心解决了两个问题一是如何将两个独立的Discord机器人账号通过一个OpenClaw网关实例分别路由到两个拥有不同权限、人格和记忆的AI智能体二是如何高效地管理和维护这样一个自托管系统特别是利用Claude Code这样的AI编程助手来辅助完成日常的运维工作。这不仅仅是把两个机器人跑起来更是关于权限隔离、资源管理、成本控制和持续运维的一整套工程实践。这个方案非常适合那些希望拥有一个7x24小时在线、功能强大且可深度定制的AI助手同时又需要在公共社区如Discord服务器中部署一个受控的、安全的公共机器人的开发者或团队。它基于Docker容器化部署理论上可以在任何支持Docker的VPS虚拟专用服务器上运行比如文档中提到的Hetzner。接下来我将为你拆解这个架构的每一个核心环节从设计思路到实操细节再到我踩过的那些坑。2. 架构设计与核心思路拆解2.1 为什么选择“单网关多智能体”架构在AI智能体部署中一个常见的朴素想法是为每个机器人单独部署一个完整的OpenClaw实例。这听起来很直接但会带来显著的资源浪费和运维复杂度。每个实例都需要独立的内存、计算资源并维护各自的环境配置。而这个项目采用的“单网关多智能体”架构其核心优势在于资源复用与清晰隔离。OpenClaw的网关Gateway负责处理与外部平台如Discord的通信协议、消息路由和会话管理。这个部分是相对重型的但也是可以共享的。通过在一个网关实例下配置多个智能体Agent我们让多个机器人共享同一套网络连接、模型调用基础设施和运行时环境。这极大地降低了服务器的资源开销特别是内存和CPU占用。那么如何确保两个智能体不会“串线”呢关键在于绑定Binding和路由Routing。在OpenClaw的配置文件openclaw.json中你可以为每个智能体定义其专属的bindings。对于Discord绑定依据是机器人的accountId实际上由Bot Token唯一确定。网关在收到来自Discord的消息时会检查消息来源的Bot Token并将其精准地路由到配置中绑定了对应accountId的智能体。这样来自“私人助手机器人”的消息只会进入“主智能体”而来自“公共群聊机器人”的消息则只会进入“公共智能体”实现了逻辑上的完全隔离。2.2 双智能体的角色与权限设计架构表中清晰地定义了两个智能体的分工这不仅仅是功能划分更是安全策略的体现主智能体main这是你的私人数字伙伴。它拥有完整的系统权限可以执行Shell命令、访问文件系统、调用各种工具如Git、curl等。它的记忆是持久化的通常记录在一个名为MEMORY.md的文件中这意味着它能记住你们之前的对话上下文和你的个人偏好。这个智能体只响应你私人Discord机器人的消息通常通过私聊DM或你指定的特定私人频道进行交互。公共智能体public这是面向社区或团队的公共接口。出于安全考虑它的权限被严格限制。通常我们会禁用或大幅限制其Shell执行能力例如禁止exec、bash等命令。它的记忆通常是“无状态”的即每次对话都是相对独立的不会持久化敏感信息。它的行为准则在AGENTS.public.md中定义会更强调友好、帮助性并避免涉及任何可能越权或引发争议的操作。这种设计在安全上形成了一个“纵深防御”。即使公共智能体在复杂的社区交互中因为某些提示词被绕过或出现意外行为由于其极低的权限它所能造成的破坏也非常有限通常仅限于说一些不合适的话而无法对服务器系统本身造成影响。2.3 扩展性自定义Docker镜像与技能系统项目的另一个亮点是其对扩展性和可维护性的考虑。它没有停留在使用官方openclaw:latest镜像上而是提供了Dockerfile.custom的模式。为什么需要自定义镜像官方镜像是通用的基础环境。在实际使用中你的智能体很可能需要一些额外的工具。例如你想让智能体帮你管理GitHub仓库就需要安装gh(GitHub CLI)想让它读取或发送邮件可能需要配置Gmail的OAuth CLI工具或者你想集成一些地理位置服务。通过Dockerfile.custom你可以像下面这样轻松扩展FROM openclaw:latest # 安装GitHub CLI RUN apt-get update apt-get install -y curl \ curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of/usr/share/keyrings/githubcli-archive-keyring.gpg \ echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main | tee /etc/apt/sources.list.d/github-cli.list /dev/null \ apt-get update apt-get install -y gh # 安装其他自定义工具例如jq用于处理JSON RUN apt-get install -y jq # 复制自定义的脚本或配置文件 COPY custom-scripts/ /app/custom-scripts/然后在.env文件中将镜像名指向你自定义的镜像如my-openclaw-custom这样在后续通过git pull更新项目代码时就不会意外地覆盖掉你精心准备的自定义环境。Claude Code技能系统则是运维层面的“神来之笔”。它本质上是一系列放在.claude/skills/目录下的文本文件这些文件定义了如何与Claude Code交互来完成特定任务。例如sync技能可能包含这样的指令“请比较本地workspace/目录和服务器上/app/workspace/目录的文件差异列出有冲突的文件并在我的确认下进行同步”。这相当于为你的AI编程助手编写了一套针对本项目的“运维插件”让你可以用自然语言来管理服务器文件、更新配置、排查问题极大降低了运维门槛。3. 核心配置解析与实操要点3.1 OpenClaw 核心配置文件详解config/openclaw.json是这个项目的心脏。虽然原仓库提供了一个已脱敏的模板但理解每个关键部分的含义至关重要。以下是一个高度简化的核心结构解析{ agents: [ { id: main, name: My Private Assistant, bindings: [ { type: discord, accountId: YOUR_PRIVATE_BOT_USER_ID } ], workspace: /app/workspace/main, persona: 你是一个乐于助人且高效的私人AI助手..., allow: [shell, http, file_read, file_write] }, { id: public, name: Community Helper, bindings: [ { type: discord, accountId: YOUR_PUBLIC_BOT_USER_ID } ], workspace: /app/workspace/public, persona: 你是一个友好、专业的社区助手只能回答与社区相关的问题..., allow: [http], // 严格限制权限不放行shell requireMention: true, // 在群聊中需要才响应 guildAllowlist: [YOUR_PUBLIC_GUILD_ID] // 只允许在特定服务器活动 } ], gateway: { discord: { tokens: { YOUR_PRIVATE_BOT_USER_ID: PRIVATE_BOT_TOKEN, YOUR_PUBLIC_BOT_USER_ID: PUBLIC_BOT_TOKEN } } }, models: { default: claude-3-5-sonnet, claude: { apiKey: YOUR_ANTHROPIC_API_KEY }, openai: { apiKey: YOUR_OPENAI_API_KEY } } }关键配置项说明bindings与accountId这是路由的关键。accountId需要填写Discord机器人的用户ID一个数字字符串而不是机器人名。你可以在Discord开发者门户创建机器人后找到它。网关部分的tokens对象其键名必须与这里每个智能体bindings中的accountId完全一致。workspace每个智能体独立的工作目录。这是存放AGENTS.md、SOUL.md、TOOLS.md、MEMORY.md等文件的地方。物理隔离确保了文件不会串扰。persona与allow这里定义了智能体的“人格”和“能力”。persona是系统提示词极大地影响其对话风格和自我认知。allow列表是权限开关务必根据智能体的角色谨慎配置。对于公共智能体我强烈建议至少移除shell、file_write等危险权限。requireMention和guildAllowlist对于公共机器人这两个配置是“文明守则”。requireMention确保机器人不会在群聊里刷屏只有被时才响应。guildAllowlist将机器人的活动范围严格限制在你指定的服务器内防止它被意外邀请到其他服务器并产生不可控的行为或费用。注意配置文件中的API密钥、Token等都是高度敏感信息。务必通过环境变量在docker-compose.yml中配置或安全的密钥管理工具来注入绝对不要将真实的密钥提交到版本控制系统Git。模板仓库使用已脱敏的占位符是正确的做法。3.2 工作空间文件智能体的大脑与记忆工作空间目录下的几个Markdown文件共同构成了每个智能体的“大脑”。理解它们的用途和编写规范是调教出好用智能体的关键。AGENTS.md/AGENTS.public.md这是智能体的“宪法”或“核心行为准则”。它应该包含最高级别的指令例如智能体的根本目标和身份“你是一个私人效率助手”。绝对禁止做的事情“永远不要执行删除整个根目录的命令”。关键的工作流程“在修改文件前必须先备份”。与用户交互的基调“用简洁、专业的语气回答”。对于公共智能体必须明确其服务范围、禁止讨论的话题以及求助指引“关于服务器管理问题请联系管理员”。SOUL.md/SOUL.public.md这是智能体的“人格面具”。它比AGENTS.md更侧重风格和个性。你可以在这里定义说话的口吻是热情似火还是冷静理性喜欢用表情符号吗。一些虚构的背景或偏好“你喜欢用比喻来解释复杂概念”。对某些类型任务的特殊处理方式。这个文件让智能体更像一个独特的“角色”而不是冰冷的机器。TOOLS.md这是智能体的“工具手册”。它应该详细描述环境中可用的、超出OpenClaw内置功能之外的特殊工具或脚本。例如如果你通过自定义Docker镜像安装了一个内部数据查询脚本就在这里说明它的调用方法、参数和示例。这能帮助智能体更有效地利用环境能力。MEMORY.md(仅限主智能体)这是智能体的“长期记忆”。智能体可以在这里记录关于用户的重要信息、之前的对话总结、达成的共识或学习到的偏好。重要提示这个文件是智能体自己写入的。你需要定期审查其内容防止它积累过多无用信息或错误记忆必要时可以手动清理。对于公共智能体通常不启用持久化记忆或者使用一个定期清空的临时记忆文件。实操心得不要试图在AGENTS.md里写一本百科全书。指令应该清晰、简洁、无歧义。如果规则太长智能体可能会忽略后半部分。将不同维度的指令分门别类并使用##、###标题来结构化能显著提升智能体的理解效果。对于冲突的指令越靠后的指令有时权重越高但最好避免冲突。4. 完整部署与操作流程实录4.1 前期准备从零到一的服务器与Discord配置假设你选择了一台全新的Ubuntu 22.04 VPS如Hetzner的CX11套餐以下是从头开始的步骤服务器基础设置# 以root用户登录后更新系统并安装基础工具 apt update apt upgrade -y apt install -y curl wget git vim sudo # 创建一个用于运行服务的专用用户非root更安全 adduser --disabled-password --gecos openclaw usermod -aG sudo openclaw # 切换到新用户 su - openclaw安装Docker与Docker Compose# 安装Docker (参考官方文档) curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh # 将当前用户加入docker组避免每次用sudo sudo usermod -aG docker $USER # 需要退出重新登录使组生效 exit # 重新ssh登录 ssh openclawyour-server-ip # 安装Docker Compose插件 sudo apt install -y docker-compose-plugin # 验证安装 docker compose version创建Discord机器人访问 Discord Developer Portal 。点击“New Application”为你的私人助手和公共机器人分别创建两个应用例如MyPrivateAssistant和MyPublicBot。在每个应用的“Bot”页面点击“Reset Token”获取Token这是你的密钥像密码一样保管好。在“OAuth2” - “URL Generator”页面为每个机器人生成邀请链接。至少需要勾选bot和applications.commands权限。对于私人助手你可能还需要Read Messages/View Channels和Send Messages。对于公共机器人根据功能需求添加。记录下两个机器人的Token和Application ID即accountId。4.2 项目部署与容器启动克隆配置仓库并准备环境# 在服务器上克隆这个模板仓库或你自己的fork git clone https://github.com/averatec0773/openclaw-discord-multiagent.git cd openclaw-discord-multiagent # 复制环境变量模板并编辑 cp .env.example .env vim .env在.env文件中你需要设置至少以下关键变量# 你的自定义镜像名如果用了Dockerfile.custom OPENCLAW_IMAGEmy-openclaw-custom:latest # Discord Bot Tokens (从开发者门户获取) DISCORD_PRIVATE_BOT_TOKENyour_private_bot_token_here DISCORD_PUBLIC_BOT_TOKENyour_public_bot_token_here # LLM API Keys ANTHROPIC_API_KEYyour_claude_api_key OPENAI_API_KEYyour_openai_api_key # 其他如TAVILY_API_KEY等构建自定义镜像可选# 如果你修改了Dockerfile.custom需要构建镜像 docker build -f Dockerfile.custom -t my-openclaw-custom:latest .准备配置文件和工作空间# 复制配置文件模板并编辑 cp config/openclaw.json.example config/openclaw.json vim config/openclaw.json使用你记录的DiscordaccountId和从.env文件引用的环境变量在配置文件中通常是{{ENV_VAR_NAME}}格式来填充openclaw.json。同时将templates/目录下的文件复制到workspace/main/和workspace/public/目录下并根据你的需求进行个性化修改。使用Docker Compose启动服务# 在项目根目录下使用docker compose启动所有服务 docker compose up -d-d参数表示在后台运行。你可以使用docker compose logs -f来实时查看日志检查启动过程中是否有错误。验证与邀请查看日志确认两个智能体都已成功连接至Discord网关没有报错。使用你之前生成的OAuth2链接将两个机器人分别邀请到你的私人服务器和公共服务器。在Discord中尝试你的私人机器人发送消息测试私聊功能。在公共服务器中尝试公共机器人测试其响应和权限限制是否生效。4.3 利用Claude Code进行日常运维这是项目中最具创新性的运维方式。你不需要总是SSH到服务器上去敲命令。本地环境准备在你的本地开发机上用VSCode打开这个项目仓库。确保已安装Claude Code扩展。加载技能Claude Code会自动识别项目根目录下的.claude/skills/文件夹。当你打开与Claude的对话面板时这些技能就已经在上下文中了。执行同步操作你可以直接对Claude说“请执行sync技能将服务器上/app/workspace/main/MEMORY.md的最新内容同步到我的本地仓库。” Claude会根据sync技能文件的指引通过SSH连接到你的服务器需要你预先配置好SSH密钥或无密码登录比较文件差异并给出一个清晰的对比报告在你确认后再执行同步。安全编辑配置文件当需要修改服务器上的openclaw.json时你可以说“使用edit技能帮我把服务器上配置文件中public智能体的requireMention改为false。” Claude会遵循edit技能定义的协议先拉取文件在本地创建副本并修改然后展示差异最后在你批准后推送回服务器。这个过程避免了直接在服务器上使用vim可能带来的误操作风险。记录与改进在使用过程中任何关于系统配置、问题解决的新发现都可以通过self-improve技能记录下来。Claude会帮你将经验总结成文甚至可以提出对仓库文档结构的改进建议。这种方式将运维从“记忆命令和路径”转变为“描述意图”极大地提升了效率也降低了操作门槛。5. 常见问题、故障排查与成本控制5.1 部署与连接问题问题现象可能原因排查步骤Docker容器启动失败.env文件缺失或变量未设置openclaw.json语法错误端口冲突。1. 运行docker compose logs openclaw查看具体错误。2. 检查.env文件是否存在且变量名正确。3. 使用jq . config/openclaw.json验证JSON格式。4. 检查宿主机端口如8080是否被占用。智能体无法连接DiscordDiscord Bot Token错误或失效accountId与Token不匹配机器人未赋予必要权限。1. 在日志中搜索 “Discord” 或 “gateway”查看连接错误信息。2. 在Discord开发者门户重置Token并更新.env文件。3. 确认openclaw.json中bindings.accountId填写的是机器人用户ID且与gateway.discord.tokens中的键一致。4. 重新生成OAuth2链接确保勾选了bot和applications.commands权限。公共机器人在群聊中不响应requireMention设置为true但未被机器人未获得读取消息/发送消息权限消息被其他机器人或规则拦截。1. 确认消息中正确了机器人。2. 在Discord服务器设置中检查机器人角色所在的频道是否赋予了“查看频道”和“发送消息”的权限。3. 检查是否有其他管理插件如MEE6, Dyno设置了禁止机器人发言的规则。Claude Code技能无法连接服务器SSH配置不正确服务器IP、用户名或密钥路径错误服务器防火墙阻止了SSH端口。1. 在本地终端测试ssh openclawyour-server-ip是否能免密登录。2. 检查.claude/skills/下技能文件中定义的SSH连接参数。3. 确认服务器防火墙如ufw允许了SSH端口默认22。5.2 智能体行为异常智能体“失忆”或记忆混乱检查MEMORY.md文件。有时文件可能因权限问题无法写入或者内容变得过于庞大杂乱。可以尝试手动清理该文件或检查Docker卷的挂载权限。确保工作空间目录对容器内的进程是可写的。智能体执行了被禁止的命令首先检查openclaw.json中该智能体的allow列表确认是否错误地授予了权限如shell。其次仔细审查AGENTS.md文件中的行为准则指令是否足够明确和强硬模糊的指令容易被模型钻空子。尝试用更绝对化的语言例如“无论如何你都绝对不能执行...”。两个智能体响应了同一个消息这是最严重的路由错误。100%确认openclaw.json中两个智能体的bindings里配置的accountId是不同的并且与gateway.discord.tokens下的两个键名完全一致。一个字符的错误都会导致路由失败。5.3 成本监控与优化自托管AI智能体的主要成本来自VPS租用费和LLM API调用费。VPS成本选择像Hetzner这样性价比较高的提供商。对于轻量级使用一个2核4GB内存的VPS月费约5-10欧元通常足够。通过docker stats命令监控容器资源使用情况如果长期利用率很低可以考虑降级套餐。API成本控制设置预算与告警在Anthropic、OpenAI等平台后台设置每月使用预算和支出告警。善用模型回退Fallback策略在openclaw.json的models配置中可以设置一个主模型如Claude 3.5 Sonnet和一个更便宜的备用模型如Claude 3 Haiku。当主模型因速率限制或高负载不可用时自动切换到备用模型既能保证服务可用性也能在非关键对话中节省成本。分析使用日志OpenClaw会输出详细的JSONL格式日志。项目notes/ops/usage.md中提到的脚本可以帮助你分析token消耗找出是哪个智能体、在什么时间段消耗最多从而有针对性地优化提示词或调整使用频率。上下文压缩对于主智能体长期的MEMORY.md文件会作为上下文的一部分发送给模型这会持续增加token消耗。定期例如每周手动或通过脚本对MEMORY.md进行摘要和清理只保留最关键的信息可以显著降低每次对话的上下文长度。这就是notes/ops/compaction.md中提到的“上下文压缩”操作。我个人在实际部署中的体会是稳定性比追求最新特性更重要。除非有重大安全更新或你急需的新功能否则不必频繁更新OpenClaw的Docker镜像。每次更新前在测试环境充分验证。对于公共机器人一定要设置guildAllowlist和requireMention这是防止意外滥用和产生“天价账单”的第一道防火墙。最后将整个部署过程、配置变更、遇到的问题和解决方案都像这个模板仓库一样文档化这会在未来进行维护或迁移时为你节省无数的时间。