Skip to main content

添加平台适配器

本指南介绍如何向 Hermes 网关添加一个新的消息平台。平台适配器将 Hermes 与外部消息服务(如 Telegram、Discord、企业微信等)连接起来,使用户可以通过该服务与智能体进行交互。

tip

添加一个平台适配器会涉及代码、配置和文档中的 20 多个文件。请将本指南作为检查清单使用——适配器文件本身通常只占工作量的 40%。

架构概览

User ↔ Messaging Platform ↔ Platform Adapter ↔ Gateway Runner ↔ AIAgent

每个适配器都继承自 BasePlatformAdapter,并实现以下方法:

  • connect() — 建立连接(WebSocket、长轮询、HTTP 服务器等)
  • disconnect() — 正常关闭
  • send() — 向聊天发送文本消息
  • send_typing() — 显示输入状态(可选)
  • get_chat_info() — 返回聊天元数据

入站消息由适配器接收,并通过 self.handle_message(event) 转发给网关运行器,后者负责路由至主流程。

分步检查清单

1. 平台枚举

gateway/config.py 文件中,将你的平台添加到 Platform 枚举:

class Platform(str, Enum):
# ... existing platforms ...
NEWPLAT = "newplat"

2. 适配器文件

创建 gateway/platforms/newplat.py

from gateway.config import Platform, PlatformConfig
from gateway.platforms.base import (
BasePlatformAdapter, MessageEvent, MessageType, SendResult,
)

def check_newplat_requirements() -> bool:
"""Return True if dependencies are available."""
return SOME_SDK_AVAILABLE

class NewPlatAdapter(BasePlatformAdapter):
def __init__(self, config: PlatformConfig):
super().__init__(config, Platform.NEWPLAT)
# Read config from config.extra dict
extra = config.extra or {}
self._api_key = extra.get("api_key") or os.getenv("NEWPLAT_API_KEY", "")

async def connect(self) -> bool:
# Set up connection, start polling/webhook
self._mark_connected()
return True

async def disconnect(self) -> None:
self._running = False
self._mark_disconnected()

async def send(self, chat_id, content, reply_to=None, metadata=None):
# Send message via platform API
return SendResult(success=True, message_id="...")

async def get_chat_info(self, chat_id):
return {"name": chat_id, "type": "dm"}

对于入站消息,构建一个 MessageEvent 并调用 self.handle_message(event)

source = self.build_source(
chat_id=chat_id,
chat_name=name,
chat_type="dm", # or "group"
user_id=user_id,
user_name=user_name,
)
event = MessageEvent(
text=content,
message_type=MessageType.TEXT,
source=source,
message_id=msg_id,
)
await self.handle_message(event)

3. 网关配置(gateway/config.py

三个修改点:

  1. get_connected_platforms() — 为你的平台所需凭证添加校验逻辑
  2. load_gateway_config() — 在 token 环境变量映射中添加条目:Platform.NEWPLAT: "NEWPLAT_TOKEN"
  3. _apply_env_overrides() — 将所有 NEWPLAT_* 环境变量映射到配置项

4. 网关运行器(gateway/run.py

五个修改点:

  1. _create_adapter() — 添加一个 elif platform == Platform.NEWPLAT: 分支
  2. _is_user_authorized() allowed_users mapPlatform.NEWPLAT: "NEWPLAT_ALLOWED_USERS"
  3. _is_user_authorized() allow_all mapPlatform.NEWPLAT: "NEWPLAT_ALLOW_ALL_USERS"
  4. 早期环境检查 _any_allowlist tuple — 添加 "NEWPLAT_ALLOWED_USERS"
  5. 早期环境检查 _allow_all tuple — 添加 "NEWPLAT_ALLOW_ALL_USERS"
  6. _UPDATE_ALLOWED_PLATFORMS frozenset — 添加 Platform.NEWPLAT

5. 跨平台投递

  1. gateway/platforms/webhook.py — 将 "newplat" 添加到投递类型元组中
  2. cron/scheduler.py — 添加到 _KNOWN_DELIVERY_PLATFORMS frozenset 和 _deliver_result() 平台映射中

6. CLI 集成

  1. hermes_cli/config.py — 将所有 NEWPLAT_* 变量添加到 _EXTRA_ENV_KEYS
  2. hermes_cli/gateway.py — 在 _PLATFORMS 列表中添加条目,包含 key、label、emoji、token_var、setup_instructions 和 vars
  3. hermes_cli/platforms.py — 添加 PlatformInfo 条目,包含 label 和 default_toolset(供 skills_configtools_config TUI 使用)
  4. hermes_cli/setup.py — 添加 _setup_newplat() 函数(可委托给 gateway.py),并将元组加入消息平台列表
  5. hermes_cli/status.py — 添加平台检测条目:"NewPlat": ("NEWPLAT_TOKEN", "NEWPLAT_HOME_CHANNEL")
  6. hermes_cli/dump.py — 在平台检测字典中添加 "newplat": "NEWPLAT_TOKEN"

7. 工具支持

  1. tools/send_message_tool.py — 将 "newplat": Platform.NEWPLAT 添加到平台映射中
  2. tools/cronjob_tools.py — 将 newplat 添加到投递目标描述字符串中

8. 工具集

  1. toolsets.py — 添加 "hermes-newplat" 工具集定义,包含 _HERMES_CORE_TOOLS
  2. toolsets.py — 将 "hermes-newplat" 添加到 "hermes-gateway" includes 列表中

9. 可选:平台提示

agent/prompt_builder.py — 如果你的平台有特定渲染限制(如不支持 Markdown、消息长度限制等),请在 _PLATFORM_HINTS 字典中添加条目。这会将平台特定建议注入系统提示中:

_PLATFORM_HINTS = {
# ...
"newplat": (
"You are chatting via NewPlat. It supports markdown formatting "
"but has a 4000-character message limit."
),
}

并非所有平台都需要提示——仅当智能体行为应有所区别时才添加。

10. 测试

创建 tests/gateway/test_newplat.py,覆盖以下内容:

  • 从配置构造适配器
  • 消息事件构建
  • send 方法(模拟外部 API)
  • 平台特有功能(加密、路由等)

11. 文档

文件应添加内容
website/docs/user-guide/messaging/newplat.md完整的平台设置页面
website/docs/user-guide/messaging/index.md平台对比表格、架构图、工具集表、安全章节、下一步链接
website/docs/reference/environment-variables.md所有 NEWPLAT_* 环境变量
website/docs/reference/toolsets-reference.mdhermes-newplat 工具集
website/docs/integrations/index.md平台链接
website/sidebars.ts文档页侧边栏条目
website/docs/developer-guide/architecture.md适配器数量 + 列表
website/docs/developer-guide/gateway-internals.md适配器文件列表

功能对齐审计

在标记新平台 PR 为完成前,请与已建立的平台进行对齐审计:

# Find every .py file mentioning the reference platform
search_files "bluebubbles" output_mode="files_only" file_glob="*.py"

# Find every .py file mentioning the new platform
search_files "newplat" output_mode="files_only" file_glob="*.py"

# Any file in the first set but not the second is a potential gap

.md.ts 文件重复此操作。调查每一处差异——是平台枚举缺失(需更新)还是平台特定引用(可跳过)?

常见模式

长轮询适配器

如果平台使用长轮询(如 Telegram 或微信),请使用轮询任务循环:

async def connect(self):
self._poll_task = asyncio.create_task(self._poll_loop())
self._mark_connected()

async def _poll_loop(self):
while self._running:
messages = await self._fetch_updates()
for msg in messages:
await self.handle_message(self._build_event(msg))

回调/Webhook 适配器

如果平台将消息推送到你的端点(如企业微信回调),请运行 HTTP 服务器:

async def connect(self):
self._app = web.Application()
self._app.router.add_post("/callback", self._handle_callback)
# ... start aiohttp server
self._mark_connected()

async def _handle_callback(self, request):
event = self._build_event(await request.text())
await self._message_queue.put(event)
return web.Response(text="success") # Acknowledge immediately

对于响应时间要求严格的平台(如企业微信的 5 秒限制),必须立即确认接收,并通过 API 异步主动发送智能体回复。智能体会话持续 3–30 分钟——在回调响应窗口内直接返回完整回复不可行。

Token 锁机制

如果适配器持有与唯一凭证相关的持久连接,请添加作用域锁以防止两个配置文件共用同一凭证:

from gateway.status import acquire_scoped_lock, release_scoped_lock

async def connect(self):
if not acquire_scoped_lock("newplat", self._token):
logger.error("Token already in use by another profile")
return False
# ... connect

async def disconnect(self):
release_scoped_lock("newplat", self._token)

参考实现

适配器模式复杂度适合参考的内容
bluebubbles.pyREST + webhook中等简单 REST API 集成
weixin.py长轮询 + CDN媒体处理、加密
wecom_callback.py回调/webhook中等HTTP 服务器、AES 加密、多应用支持
telegram.py长轮询 + Bot API支持群组、线程的完整功能适配器