Hoomanity:基于ACP协议将AI编程助手无缝集成到Slack/Telegram
1. 项目概述:将你的AI编程助手接入日常聊天工具
如果你和我一样,日常开发工作流里已经离不开像 Cursor、Claude Code 这类 AI 编程助手,但又常常觉得在 IDE 和聊天软件之间来回切换很割裂,那么这个项目你一定会感兴趣。Hoomanity 本质上是一个“中继器”或“适配器”,它基于 Bun 运行时构建,核心使命是把你已经用顺手的、支持 ACP(Agent Client Protocol)协议的 AI 代理,无缝桥接到 Slack、Telegram 和 WhatsApp 这些团队日常沟通工具里。
想象一下,在 Slack 的某个技术讨论频道里,你直接 @ 一个机器人,就能让后台的 AI 代理帮你审查代码片段、解释错误日志,甚至生成一小段脚本,并且整个对话上下文是持久化的,下次在同一个聊天里提问,AI 还记得之前的讨论。更关键的是,当 AI 需要执行某些有风险的操作(比如写入文件、运行命令)时,审批请求会直接发回到聊天窗口等你点击确认,整个过程完全在团队熟悉的协作环境里完成,无需跳转到另一个网页或应用。这就是 Hoomanity 要解决的核心痛点:让强大的 AI 能力以最自然、最无感的方式,嵌入到现有的团队沟通和工作流中,而不是让团队去适应一个新的、孤立的 AI 工具。
这个项目适合两类开发者:一是已经在使用成熟 AI 编程工具(如 Cursor、Gemini Code、OpenCode)的团队或个人,希望将其能力暴露给更广泛的非技术或轻度技术成员;二是注重隐私和可控性,希望搭建完全本地化 AI 代理栈(例如使用 Ollama + 本地模型)的极客,并为其提供一个便捷的聊天前端。接下来,我会深入拆解它的设计思路、具体如何部署配置、以及在实际使用中积累的一些关键技巧和避坑指南。
2. 核心设计思路与架构解析
2.1 为什么选择 ACP 协议作为核心桥梁?
Hoomanity 没有尝试去自己实现一个 AI 代理,这是一个非常明智且务实的设计决策。它选择拥抱并充当 ACP(Agent Client Protocol)协议的“中继层”。ACP 是一个由 Anthropic 等公司推动的开放协议,旨在标准化 AI 代理与客户端(如 IDE、聊天界面)之间的通信方式。它定义了代理如何接收任务、执行思考、调用工具以及返回结果的标准 JSON-RPC 格式。
选择 ACP 意味着 Hoomanity 立即获得了与一个不断增长的生态系统的兼容性。你的“智能大脑”可以是任何实现了 ACP 的服务,无论是商业产品 Cursor 内置的代理,还是你基于hoomanjs这类开源库自己搭建的本地模型服务。Hoomanity 只关心三件事:1. 如何与这些 ACP 服务通信;2. 如何与 Slack 等聊天平台对接;3. 如何管理这两者之间的会话状态和审批流。这种关注点分离让项目保持了极致的轻量和可维护性。
从架构上看,Hoomanity 是一个典型的“消息路由与状态管理”中心。它启动后,会做两件事:首先,根据配置启动一个子进程来运行你指定的 ACP 代理命令,并通过标准输入输出(stdio)与之建立 JSON-RPC 通信。其次,它会初始化并连接你启用的聊天平台“监听器”。当一个聊天消息到来时,监听器将其转化为标准的内部事件,Hoomanity 的核心引擎会查找或创建一个与该聊天对应的“持久化会话”,然后将用户输入包装成 ACP 协议格式,转发给后端的 AI 代理。代理返回的文本、工具调用请求等,再被引擎转换回聊天平台支持的格式(如 Slack 的 Block Kit)发送回去。
2.2 本地优先与配置管理哲学
项目强调“Local-first”配置,所有设置默认存储在~/.hoomanity/config.json。这不仅仅是技术选择,更体现了一种控制权在用户手中的理念。你的聊天平台密钥、允许访问的频道列表、后端代理命令等敏感信息,都留在你自己的机器上,而不是某个云端服务商那里。你可以用HOOMANITY_CONFIG_PATH环境变量覆盖这个路径,这为在容器化部署或使用配置管理工具时提供了灵活性。
项目提供了一个基于 Ink 库构建的终端配置 UI(通过bunx hoomanity configure启动),这大大降低了配置门槛。Ink 允许在终端中渲染丰富的 React 组件,从而提供类似图形界面的交互体验,让你可以直观地填写表单、选择选项,而无需手动编辑 JSON 文件。这种对开发者体验的重视,在开源工具中难能可贵。
注意:虽然配置 UI 很方便,但了解底层 JSON 结构对于调试和自动化部署至关重要。建议在首次使用 UI 配置后,打开生成的
config.json看一眼,理解各个字段的对应关系。
3. 详细配置与多平台接入实战
3.1 基础环境准备与 ACP 代理连接
首先,你需要一个运行时环境。Hoomanity 基于 Bun,因此你需要先安装 Bun。如果你的系统没有,可以参照官方文档安装,通常就是一行 curl 命令的事。
# 安装 Bun (以 macOS/Linux 为例) curl -fsSL https://bun.sh/install | bash安装后,你可以选择全局安装 Hoomanity,但更推荐使用bunx(Bun 的 npx 等效物)直接运行,避免版本冲突。
# 启动交互式配置向导 bunx hoomanity configure配置向导会引导你完成最关键的一步:设置 ACP 代理命令。这里有两种主流路径:
路径一:连接现有商业/开源代理如果你在使用 Cursor IDE,并且开启了它的 AI Agent 功能,它通常会在本地启动一个支持 ACP 的服务。你需要找到这个服务的启动命令。例如,Cursor 可能暴露了一个命令行工具。你需要在acp.cmd配置项中填入类似cursor-agent --acp的命令。具体的命令需要查阅你所使用工具的文档。这个命令必须是一个能持续运行、通过 stdio 接受 ACP JSON-RPC 的可执行程序。
路径二:搭建本地代理栈(完全自主可控)这是更极客的玩法。你需要:
- 安装 Ollama 并拉取一个适合编程的模型,比如
gemma2:9b或qwen2.5:7b。 - 创建一个使用
hoomanjs库的简单 Node.js/Bun 脚本。hoomanjs是一个轻量级库,它能将 Ollama 的聊天 API “包装”成符合 ACP 协议的服务。 - 在配置中,将
acp.cmd指向你编写的这个脚本。
一个极简的hoomanjs代理脚本示例 (local-agent.js):
import { Hooman } from 'hoomanjs'; import { Ollama } from '@hoomanjs/provider-ollama'; const agent = new Hooman({ provider: new Ollama({ // 指向你的 Ollama 服务,默认是 localhost:11434 baseURL: 'http://localhost:11434', model: 'gemma2:9b', // 指定你要使用的模型 }), }); // 启动并监听 stdio,等待 ACP 协议消息 agent.start();然后在 Hoomanity 配置中设置acp.cmd为bun run /path/to/local-agent.js。这样,你就拥有了一个从模型、代理逻辑到聊天前端完全在自己掌控之下的 AI 助手。
3.2 Slack 监听器深度配置指南
Slack 的配置相对复杂,因为它涉及 Slack App 的创建和权限管理。Hoomanity 使用 Slack 的 Socket Mode,这意味着你的服务可以主动连接到 Slack 的网关接收事件,而无需一个公网可访问的 HTTPS 端点,非常适合本地开发或内网部署。
步骤 1:创建 Slack App访问 api.slack.com/apps ,点击 “Create New App”。选择 “From an app manifest”,然后根据你的需求,粘贴项目提供的 “User token manifest” 或 “Bot token manifest”。
关键抉择:User Token vs Bot Token
- User Token:以特定安装用户(通常是你自己)的身份操作。权限更高,可以访问该用户能访问的所有频道和历史消息。适合个人或小团队使用,机器人发言会显示为“你”(即安装用户)。
- Bot Token:以独立的机器人用户身份操作。需要将其邀请到频道中。发言显示为独立的机器人账号。更适合团队协作场景,权限范围更清晰可控。
对于大多数团队场景,我推荐使用Bot Token,因为它更符合权限最小化原则,也便于管理。将上面提供的 Bot token manifest 粘贴进去创建应用。
步骤 2:安装与获取 Token创建应用后,进入 “OAuth & Permissions” 页面,将应用安装到你的工作空间。安装成功后,你会得到两个关键令牌:
- Bot User OAuth Token:以
xoxb-开头。这个填入 Hoomanity 配置的slack.token。 - App-Level Token:你需要手动生成。在 “Basic Information” 页面,找到 “App-Level Tokens”,创建一个具有
connections:write权限的令牌。这个令牌以xapp-开头,填入 Hoomanity 配置的slack.app_token。这个令牌用于建立 Socket Mode 连接。
步骤 3:配置 Allowlist(允许列表)这是重要的安全控制项。在 Hoomanity 配置的slack.allowlist中,你可以指定哪些频道或用户能与机器人交互。格式可以是频道 ID(如C12345678)或用户 ID(如U12345678)。你可以通过 Slack 界面右键点击频道或用户,选择 “Copy link” 来获取 ID(链接末尾的那串字符)。如果不配置 allowlist,理论上任何能 @ 机器人的地方都能触发它,这可能带来安全或骚扰风险。
3.3 Telegram 与 WhatsApp 监听器配置要点
Telegram的配置简单许多。你只需要通过 @BotFather 创建一个新的 Bot,即可获得一个以数字:字母格式的 Bot Token。将此 Token 填入telegram.token即可。同样,telegram.allowlist可以用来限制可交互的聊天 ID(个人聊天、群组或频道)。
WhatsApp的配置则依赖于 WhatsApp Business Cloud API。你需要一个 Meta 开发者账号,创建一个 WhatsApp 应用,并关联一个电话号码。配置过程涉及设置 Webhook 回调 URL。由于 Hoomanity 是本地服务,你需要使用类似ngrok或cloudflared的工具将本地端口暴露为一个公网 HTTPS 地址,并将这个地址配置为 WhatsApp 的 Webhook。whatsapp.webhook_secret和whatsapp.verify_token等字段用于验证来自 Meta 服务器的请求。这是三者中配置最复杂的一环,通常用于更正式的业务集成场景。
实操心得:对于个人或小团队内部使用,优先考虑 Slack 或 Telegram。Slack 功能强大,集成度高;Telegram 配置极其简单,且对个人使用非常友好。WhatsApp 更适合已有 WhatsApp Business 生态或需要与客户直接通过 WhatsApp 沟通的场景。初次部署时,建议先只启用一个平台,成功跑通后再添加第二个。
4. 核心工作流程与高级功能实战
4.1 会话持久化与上下文管理机制
Hoomanity 的核心价值之一就是“持久化会话”。这意味着每个独立的聊天(例如,一个 Slack 频道、一个 Telegram 私聊窗口)都会对应一个唯一的 ACP 会话 ID。这个会话状态(包括对话历史、AI 的临时记忆)会在 Hoomanity 服务运行期间一直保持。
实现上,Hoomanity 内部维护了一个会话映射表。键是平台名:聊天ID(如slack:C024BE91L),值是对应的 ACP 会话句柄。当消息从某个聊天到来时,引擎会查找或创建会话,并将整个会话历史(可能经过摘要或截断以符合模型上下文长度限制)随着新问题一起发送给 ACP 代理。这确保了 AI 能理解对话的来龙去脉,实现连续、连贯的交流。
你可以通过聊天命令来管理会话:
reset chat或new chat:这会清空当前聊天对应的历史上下文,并创建一个全新的 ACP 会话。当你开始一个全新话题时,这非常有用。cancel或stop:这会中断 AI 代理当前正在进行的任务(例如一个长时间运行的思考或工具调用)。在 AI “卡住”或你改变主意时使用。
4.2 工具调用与审批流程详解
当你的 ACP 代理决定要调用一个工具(比如read_file,shell_execute)时,它会通过 ACP 协议发送一个ToolCall请求。Hoomanity 捕获到这个请求后,不会自动执行,而是会将其“暂停”,并生成一个用户友好的审批消息,发送回原始的聊天窗口。
以 Slack 为例,审批消息可能是一个包含按钮(“批准”、“拒绝”)的交互式组件。用户点击“批准”后,Slack 会发送一个交互载荷回 Hoomanity,Hoomanity 再通知 ACP 代理继续执行该工具调用,并将执行结果返回给 AI 进行后续处理。如果用户拒绝,则工具调用被取消,AI 会收到一个拒绝通知,并可能调整其后续计划。
这个设计将控制权牢牢握在用户手中,是安全使用具有强大工具调用能力 AI 代理的关键。你可以放心地让 AI 拥有读取文件、执行命令的“能力”,因为每一次潜在的危险操作都需要你手动点击确认。
4.3 媒体附件与文件处理
部分聊天平台支持发送文件。Hoomanity 的监听器(如 Slack)可以捕获这些附件。例如,在 Slack 中,你可以将一段代码的截图或一个package.json文件拖入聊天。Hoomanity 会下载这个文件,将其临时存储在本地,然后将文件路径或内容(取决于文件类型和大小)作为上下文信息附加到用户的消息中,再发送给 ACP 代理。
这意味着你可以对 AI 说:“看看我刚发的截图里的错误信息”,或者“分析一下我上传的日志文件”。AI 代理如果具备相应的工具(如读取图片的 OCR 工具、解析文本文件的工具),就能处理这些多媒体输入,极大地扩展了交互的实用性。
5. 开发、部署与运维实践
5.1 本地开发与代码贡献
项目代码结构清晰,便于二次开发。克隆仓库后,使用bun install安装依赖。主要的入口点是src/cli.ts。
# 克隆项目 git clone https://github.com/vaibhavpandeyvpz/hoomanity.git cd hoomanity # 安装依赖 bun install # 以开发模式运行配置向导(指向本地源码) bun run src/cli.ts configure # 以开发模式启动中继器 bun run src/cli.ts start如果你想为项目添加对新聊天平台的支持(比如 Discord),你需要创建一个新的“监听器”模块。核心工作是实现一个类,负责:1. 初始化平台 SDK 并建立连接;2. 将平台的原生消息事件转换为内部的标准化事件;3. 将内部的响应消息转换回平台支持的格式并发送。可以参照src/listeners/slack.ts或src/listeners/telegram.ts的实现。
5.2 生产环境部署考量
虽然 Hoomanity 设计为本地优先,但将其部署到一台长期运行的服务器上,可以让团队所有成员 24/7 访问。
部署方式:
- 直接运行:在服务器上安装 Bun,克隆配置好的项目,使用
bun run start并通过pm2或systemd守护进程。 - Docker 容器化:这是更优雅的方式。你需要编写 Dockerfile,将 Bun、项目代码、以及你的
config.json(或通过环境变量注入)打包进去。注意,如果 ACP 代理命令也是本地脚本(如hoomanjs + Ollama),你需要将其一并打包或通过卷挂载。
配置管理:生产环境不建议使用交互式configure命令。你应该在安全的环境中生成最终的config.json文件,然后通过 Docker 的 secret 管理、Kubernetes ConfigMap 或 HashiCorp Vault 等工具将其注入容器。确保令牌等敏感信息不会暴露在镜像层或日志中。
网络与安全:
- Slack Socket Mode:无需公网 IP,适合服务器在 NAT 或防火墙后。
- Telegram:通过长轮询或 Webhook 接收消息。如果使用 Webhook,服务器需要有公网 HTTPS 地址。
- WhatsApp:必须使用 Webhook,且必须是 HTTPS。你需要配置稳定的反向代理(如 Nginx + Let‘s Encrypt)或使用云厂商的 API 网关。
- Allowlist:务必在生产环境配置严格的 allowlist,防止机器人被意外拉入无关群组或受到恶意骚扰。
5.3 监控、日志与故障排查
一个稳定的 Hoomanity 服务需要基本的可观测性。
- 日志:Hoomanity 默认会输出日志到控制台。在生产环境中,你应该将 stdout/stderr 重定向到日志文件或像 Loki/ELK 这样的集中式日志系统。关注连接状态、消息收发错误和 ACP 通信异常。
- 进程健康:使用
pm2或systemd可以确保进程崩溃后自动重启。可以设置一个简单的健康检查端点(如果未来版本提供)或通过监控 Bun 进程是否存在来判断。 - 常见故障点:
- ACP 代理进程挂掉:表现为 AI 停止响应。检查代理进程的日志,可能是模型服务(Ollama)崩溃或命令路径错误。Hoomanity 应该具备重连机制,但需要关注日志。
- 聊天平台 Token 失效:Slack/Telegram Token 可能过期或被撤销。需要重新申请并更新配置。
- 会话内存泄漏:如果长期运行且聊天非常多,内存中的会话对象可能积累。关注 Node.js/Bun 进程的内存使用情况。目前会话是内存存储,重启服务会丢失所有会话上下文。未来可能会有基于磁盘的会话持久化方案。
6. 典型问题排查与优化技巧
在实际部署和使用 Hoomanity 的过程中,你可能会遇到一些典型问题。下面这个表格汇总了常见症状、可能原因和解决方案,可以帮助你快速定位问题。
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
运行bunx hoomanity start后立即退出或无响应 | 1. ACP 代理命令配置错误或无法执行。 2. 配置文件路径错误或格式无效。 3. 必要的环境变量缺失。 | 1. 使用bunx hoomanity configure重新检查acp.cmd,并手动在终端运行该命令,确认其能持续运行并接受输入。2. 检查 ~/.hoomanity/config.json文件是否存在,格式是否正确(可用jq . config.json验证)。3. 添加 DEBUG=*环境变量运行,查看详细启动日志。 |
| Slack 机器人收不到消息或无法回复 | 1. Socket Mode 连接失败。 2. slack.app_token或slack.token错误。3. Slack App 权限配置不全。 4. 机器人未被邀请到频道或 allowlist 限制。 | 1. 检查 Hoomanity 日志中是否有 Socket Mode 连接错误。 2. 在 Slack API 网站重新核对两个 Token,确保 App-Level Token 有 connections:write权限。3. 对照文档,检查 App Manifest 中的 scopes和event_subscriptions是否完整添加。4. 在 Slack 频道中 /invite @你的机器人,并检查allowlist配置是否包含该频道 ID。 |
| AI 回复没有上下文,每次都是新对话 | 会话持久化未正常工作。 | 1. 确认 Hoomanity 服务是持续运行的,没有频繁重启(每次重启会丢失内存中的会话)。 2. 检查日志,看是否为同一个聊天 ID 创建了新的会话。可能是聊天平台的消息 ID 或会话标识生成逻辑有误。 |
| 工具调用审批按钮点击后无反应 | 1. Slack Interactivity 未启用或 Request URL 未配置。 2. 本地服务无法被 Slack 公网访问(审批回调失败)。 | 1. 在 Slack App 配置的 “Interactivity & Shortcuts” 中,确保 “Interactivity” 是On,并且 “Request URL” 指向了正确的 Ngrok 或你的服务器公网地址(格式为https://your-url/slack/actions)。注意:Socket Mode 用于接收事件,但交互组件的回调仍需一个公网可访问的端点。这是 Slack 集成中最容易忽略的一点! |
| Telegram 机器人正常工作,但无法在群组中响应 | 1. 机器人未获取群组消息。 2. 隐私模式限制。 | 1. 将机器人添加到群组后,需要向它发送/start命令(有时需要)。2. 在 Telegram 中,私聊 @BotFather,选择你的机器人,进入 “Bot Settings” -> “Group Privacy”,将其设置为DISABLED,这样机器人才能看到群组中的所有消息。 |
| 使用本地 Ollama 代理时响应速度极慢 | 1. 模型太大,硬件资源不足。 2. Ollama 服务未优化。 | 1. 尝试更小的量化模型(如gemma2:7b-instruct-q4_K_M)。2. 确保 Ollama 运行在有 GPU 加速的环境中(如果支持)。检查 Ollama 日志确认是否使用了 GPU。 3. 在 hoomanjs配置中,调整生成参数,如降低max_tokens。 |
性能优化技巧:
- 会话上下文修剪:长时间的对话可能导致发送给模型的上下文过长,影响速度和成本。可以研究 ACP 代理是否支持上下文窗口管理,或者在 Hoomanity 层面实现一个简单的策略,例如只保留最近 N 轮对话或对历史进行摘要。
- 异步与队列:在高并发场景下,来自多个聊天窗口的请求可能同时到达。考虑在 Hoomanity 内部为每个会话实现一个简单的消息队列,避免同一个会话的请求被并发处理导致状态混乱。
- 资源隔离:如果你连接的是本地 Ollama,考虑为 Hoomanity 专用的代理服务设置资源限制(cgroups),防止其过度消耗 CPU/内存影响主机其他服务。
最后,这个项目的魅力在于它的“胶水”定位。它不试图取代你的 AI 代理,也不试图重建一个聊天应用,而是优雅地将两者连接起来。这种专注让它可以快速迭代,并充分利用现有生态系统的优势。如果你厌倦了在工具间切换,想让 AI 助手真正融入团队的沟通流,花上几个小时部署和配置 Hoomanity,将会显著提升你和团队的人机协作体验。
