基于Claude Agent SDK与MCP协议构建可定制AI助手:Kairo项目全解析
1. 项目概述:一个拥有“灵魂”的AI助手
如果你厌倦了那些只会机械回复的聊天机器人,想拥有一个能真正理解你、帮你处理日常琐事、甚至有点个性的数字伙伴,那么 Kairo 这个项目值得你花时间研究一下。它不是一个简单的问答脚本,而是一个构建在 Claude Agent SDK 之上的、功能强大的 AI 智能体,并且以 Telegram 作为主要交互界面。简单来说,你可以把它理解为你私人的、全能的 AI 助理,通过一个你熟悉的聊天应用来驱动。
Kairo 的核心魅力在于它的“可连接性”和“人格化”。它通过 MCP 协议,像给机器人安装“手”和“眼睛”一样,连接到了你的真实数字生活工具里,比如 Gmail、Notion、Spotify。这意味着你可以直接告诉它:“查一下我昨天收到的关于项目计划的邮件,把要点总结到 Notion 的周报页面里,然后放点放松的音乐。” 它就能理解并执行这一系列跨应用的操作。更酷的是,它的性格、说话方式、甚至价值观,都由一个名为SOUL.md的文件定义,你可以随意修改,让它变成你想要的任何角色——是严谨的秘书,还是幽默的朋友,全由你决定。
2. 核心架构与设计思路拆解
2.1 为什么选择 Claude Agent SDK + MCP 的组合?
市面上 AI 模型和框架很多,Kairo 选择 Claude Agent SDK 作为大脑,并用 MCP 来连接工具,这套组合拳背后有清晰的逻辑。
首先,Claude 模型在长上下文理解、复杂指令遵循和工具调用方面表现非常稳定。Claude Agent SDK 官方提供了构建智能体所需的核心框架,比如对话管理、工具调用流程,这比我们从零开始用 OpenAI API 封装要省心得多,也更能跟上 Anthropic 官方的最佳实践更新。
其次,MCP 是“模型上下文协议”的缩写。你可以把它想象成一套标准的“插座”规范。Gmail、Notion 这些外部服务,只要按照 MCP 规范做成一个“插头”,就能轻松“插入”到 Claude 这个“大脑”上。这样做的好处是解耦和可扩展性。Kairo 的核心代码不需要关心 Gmail API 的具体细节,它只负责启动和管理这些 MCP 服务器。当你想新增一个工具时,比如连接你的日历,你只需要找一个或自己写一个日历的 MCP 服务器,然后在配置里启用它即可,核心的机器人逻辑几乎不用改动。这种架构让 Kairo 从一个功能固定的 Bot,变成了一个工具平台。
2.2 对话记忆系统:不只是聊天记录
一个能进行长对话的 AI 助手,记忆管理是关键挑战。Kairo 没有简单地把所有历史消息都扔给模型,而是实现了一套基于 SQLite 的、带自动压缩的对话记忆系统。
它的工作流程是这样的:每次对话,系统都会维护一个“上下文窗口”。这个窗口有大小限制,由MAX_CONTEXT_TOKENS控制。当新的对话加入,使得总 token 数超过这个预算时,系统不会粗暴地丢弃最早的几条消息,而是会触发自动压缩。压缩的过程,可以理解为让 AI 对之前的对话历史进行一次“摘要总结”,然后将这个总结作为一条新的、浓缩过的消息放入上下文,替换掉大段的原始历史。这样既保留了对话的核心信息和连贯性,又极大地节省了宝贵的上下文 token。
这个设计解决了两个核心痛点:一是控制 API 调用成本,更长的上下文意味着更贵的请求;二是提升模型效率,无关紧要的细节被过滤,模型能更专注于当前对话的核心。SQLite 的选用则保证了数据的持久化,即使机器人重启,记忆也不会丢失,并且它轻量、无需额外服务,非常适合个人部署的项目。
3. 核心模块功能与实操要点
3.1 核心通信层:Telegram Bot 的搭建与优化
Telegram Bot 是 Kairo 的脸面,也是用户交互的入口。项目使用node-telegram-bot-api这类库来与 Telegram 服务器通信。这里有几个实操中容易踩坑的点:
Token 安全:BOT_TOKEN是最高机密,绝对不能提交到代码仓库。.env文件必须被加入.gitignore。在服务器上,可以考虑使用环境变量管理工具或 secrets 管理服务。
响应模式:Telegram 支持轮询和 Webhook 两种方式。对于个人部署,长轮询更简单,无需公网 IP 和 SSL 证书。但在index.ts的启动逻辑里,你需要处理好错误重试和断开重连。一个稳健的实践是添加一个setInterval健康检查,如果发现 bot 实例无响应,自动尝试重新初始化。
群组聊天:ENABLE_GROUPS这个开关要谨慎开启。在群组中,机器人可能会被大量无关消息 @,产生不必要的 API 调用和费用。一个更好的实践是,即使开启群组,也通过中间件判断消息是否以 bot 的名字或特定命令开头,再进行后续处理,避免无意义的触发。
3.2 灵魂文件:如何定制你的 AI 人格
SOUL.md是 Kairo 项目的精髓所在。它不是一个配置文件,而是一份用自然语言写给 AI 的“角色设定说明书”。Claude 系统提示词会加载这个文件的内容,从而塑造机器人的行为。
编写一个有效的SOUL.md需要技巧:
- 明确基础身份:开头就要定调。“你是一个名叫 Kairo 的 AI 助手,由 FujiwaraChoki 创造。你的核心目标是高效、贴心地协助用户管理数字生活。”
- 定义沟通风格:“你说话简洁、直接,但保持友好。避免使用过于夸张的网络用语。当用户提出模糊请求时,你会主动询问细节以澄清。”
- 设定能力和边界:“你可以访问用户的邮件、笔记和音乐来提供帮助。你绝对不能代替用户做出重要决定,如发送邮件确认合同条款。对于无法确认的信息,你应明确告知‘这个我不太确定’。”
- 注入价值观:“你尊重用户隐私,未经明确许可,不会主动提及其他聊天记录或文件内容。你鼓励高效的工作和健康的休息。”
你可以创建多个SOUL.md变体,比如SOUL_Professional.md、SOUL_Casual.md,然后在启动时通过环境变量SYSTEM_PROMPT_PATH指定加载哪一个,实现一键切换人格。
3.3 工具集成模块深度解析
Kairo 的强大体现在各个集成工具上。每个工具模块本质上都是一个独立的 MCP 服务器。
Gmail 模块:它封装了 Gmail API。你需要先在 Google Cloud Console 创建项目,启用 Gmail API,配置 OAuth 2.0 凭证,并将重定向 URI 设置为你的本地或服务器地址。Kairo 的gmail/目录下的代码会处理 OAuth 流程,获取并刷新access_token。安全方面,这些 token 需要和数据库对话记录一样被安全存储。该模块暴露的工具可能包括search_emails、read_email、send_email等,每个工具函数都需要仔细处理错误,比如 API 速率限制、邮件格式异常等。
Notion 模块:通过 Notion 官方 SDK 连接。你需要创建一个 Notion 集成,获取INTERNAL_TOKEN,并邀请该集成到你想要管理的页面或数据库。这里的关键是数据模型映射。Notion 数据库的属性是自定义的,你的 MCP 工具在“创建页面”时,需要能灵活地将用户指令(如“创建一个待办事项:买咖啡”)转换成对应数据库属性的结构化数据。通常,这需要你在配置中预设一些数据库的 ID 和属性映射关系。
Spotify 模块:这是最有趣的模块之一,因为它涉及播放控制。同样需要创建 Spotify App 获取CLIENT_ID和CLIENT_SECRET。OAuth 流程会要求用户授权,授权后机器人就能控制用户的播放设备。这里有一个重要细节:Spotify 的播放设备 ID 是动态的。一个健壮的工具实现,应该在执行“播放”命令前,先调用get_available_devices工具列出设备,让用户选择或自动选择上次使用的活动设备,而不是假设一个设备始终在线。
4. 从零开始的部署与配置实战
4.1 本地开发环境搭建
假设你已经在本地安装了 Node.js (>=20.6) 和 pnpm。我们不走一键安装脚本,而是手动走一遍流程,这能帮你理解每一个环节。
# 1. 克隆项目 git clone https://github.com/FujiwaraChoki/kairo.git cd kairo # 2. 安装依赖 pnpm install # 3. 复制并配置环境变量 cp .env.example .env现在,打开.env文件,这是配置的核心。我们逐一配置:
# 必须配置项 BOT_TOKEN=你的Telegram_Bot_Token # 从 @BotFather 那里获取 ANTHROPIC_API_KEY=你的Claude_API_Key # 从 Anthropic 控制台获取 # 可选但建议配置的项 BOT_NAME=我的助手 # 在聊天中显示的名字 MAX_CONTEXT_TOKENS=12000 # 根据你的预算调整,越小响应越快、越便宜 ENABLE_GROUPS=false # 初期建议关闭,在私聊中测试 # 工具集成配置(按需) EXA_API_KEY=你的Exa搜索Key # 用于实时网络搜索 # NOTION_TOKEN、SPOTIFY_CLIENT_ID 等暂时留空,后续逐步添加注意:
.env文件中的注释在真实环境中会被忽略,但示例文件里的说明非常重要。每个 API Key 的获取都需要你到对应平台的开发者后台进行操作,过程类似:创建项目、启用 API、生成凭证。请务必保管好这些 Key,它们等同于密码。
4.2 首次运行与基础测试
配置好最基本的 Telegram 和 Claude 密钥后,就可以启动了。
pnpm start如果一切正常,终端会显示启动日志,连接到 Telegram。现在,去 Telegram 找到你的 Bot,发送/start。你应该能收到回复。尝试进行一段多轮对话,比如:
- 你:“你好,介绍一下你自己。”
- Bot:(根据
SOUL.md内容回复) - 你:“我们刚才聊了什么?”
- Bot 应该能提及之前的对话内容,这说明对话记忆系统在工作。
实操心得:第一次运行时,最常见的错误是 Node.js 版本过低或 pnpm 未全局安装。请务必用node -v和pnpm -v确认版本。另一个常见问题是网络连接导致 Telegram API 调用失败,可以考虑在代码中为 bot 实例添加更详细的错误监听和重试逻辑。
4.3 逐步添加工具集成
建议一次只添加一个工具,测试稳定后再添加下一个。以Exa 网络搜索为例:
- 去 Exa.ai 官网注册,获取 API Key。
- 在
.env文件中填入EXA_API_KEY。 - 重启Kairo 进程。因为环境变量通常在启动时加载。
- 在 Telegram 中尝试:“搜索一下今天关于 SpaceX 星舰发射的最新新闻。”
- Kairo 应该会调用 Exa 搜索工具,获取结果并总结后回复你。
这个过程体现了 MCP 架构的优雅:你不需要修改任何核心代码,只需提供配置,对应的 MCP 服务器(在src/info/或相关模块中)会自动被加载,并向 Claude 注册新的工具。
添加 Gmail、Notion 等需要 OAuth 的工具会更复杂一些:
- 配置
.env。 - 启动 Kairo,它会提示你某个工具需要 OAuth 授权,并可能提供一个本地 URL。
- 用浏览器访问该 URL,登录你的 Google/Notion/Spotify 账号并授权。
- 授权后,凭证会被保存,后续即可正常使用。
5. 高级配置与性能调优
5.1 对话记忆系统的参数调优
MAX_CONTEXT_TOKENS是控制成本和性能的核心杠杆。Claude 不同模型有上下文窗口限制,你需要留出空间给系统提示词(SOUL.md)、工具返回结果和生成的回复。
一个实用的计算公式是:MAX_CONTEXT_TOKENS = 模型总窗口 - 系统提示词token数 - 预留缓冲(约1000)
例如,使用 Claude 3 Haiku(200k 窗口),你的SOUL.md经计算约 500 token,那么可以设置为200000 - 500 - 1000 = 198500。但实际中,为了响应速度和降低成本,你完全没必要用满。设置为 16000 或 32000 通常能在记忆长度和响应速度间取得很好平衡。
自动压缩策略在src/conversation/下的代码中定义。你可以调整触发压缩的阈值(比如达到MAX_CONTEXT_TOKENS的 90% 时触发),以及摘要的详细程度。更详细的摘要会占用更多 token,但保留更多信息;反之则更节省空间。
5.2 构建自定义 MCP 工具
当内置工具不满足需求时,你可以扩展 Kairo。假设你想添加一个“查询服务器状态”的工具。
- 创建工具模块:在
src/下新建system-status/目录。 - 实现工具函数:创建
index.ts,使用@modelcontextprotocol/sdk来定义 MCP 服务器。你需要定义一个工具,比如叫get_server_status,其执行函数里可以调用os、child_process模块获取负载、内存等信息。 - 暴露工具:确保该模块导出一个符合 MCP 标准的服务器实例。
- 集成到主程序:在
src/index.ts或类似的启动脚本中,导入你的新服务器实例,并像其他内置工具一样将其注册到 Claude Agent。 - 更新 SOUL.md:在
SOUL.md中告诉 Kairo 它现在多了一个新能力:“你可以使用get_server_status工具来检查我所运行系统的健康状况。”
这个过程需要一些 TypeScript 和 MCP 协议的基础知识,但模式是统一的。官方 Claude Agent SDK 文档和 MCP 示例是很好的学习资源。
5.3 部署到生产环境
本地运行没问题后,你可能会想把它部署到 24 小时在线的服务器上。
推荐方式:使用 PM2 进程管理
# 在服务器上全局安装 PM2 pnpm add -g pm2 # 使用 PM2 启动应用,并指定环境变量文件 pm2 start pnpm --name "kairo-bot" -- start # 设置开机自启 pm2 startup pm2 savePM2 能自动重启崩溃的进程,管理日志,非常方便。
环境变量管理:在服务器上,不建议直接使用.env文件。可以使用:
- Docker:在
docker run命令中使用-e标志传递,或使用 Docker secrets。 - 服务器环境变量:在
~/.bashrc或~/.profile中导出,但要注意安全。 - 云服务商提供的 Secrets 管理:如 AWS Secrets Manager, Google Secret Manager,这是最安全的方式。
网络考虑:如果你需要使用 Webhook 模式(对于高消息量更高效),你需要一个公网 IP 或域名,并配置 SSL 证书(Let‘s Encrypt 免费),然后在 Telegram Bot 配置中设置 Webhook URL。
6. 常见问题排查与维护技巧
6.1 启动与连接问题
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
启动时报Missing BOT_TOKEN | .env文件未配置或变量名错误 | 1. 检查.env文件是否存在且路径正确。2. 确认变量名与代码中读取的(如 process.env.BOT_TOKEN)完全一致。3. 重启终端或 IDE,确保环境变量已重新加载。 |
运行pnpm start后无任何反应或立即退出 | Node.js 版本过低或依赖安装失败 | 1. 运行node -v确认版本 ≥ 20.6。2. 删除 node_modules和pnpm-lock.yaml,重新运行pnpm install,观察安装过程有无报错。3. 查看 package.json中的scripts,确认start命令指向正确的入口文件(如dist/index.js或src/index.ts)。 |
| Bot 不回复消息 | Telegram Token 无效;网络问题;Bot 未启动 | 1. 在浏览器访问https://api.telegram.org/bot<你的BOT_TOKEN>/getMe,如果返回{"ok":false},说明 Token 错误。2. 检查服务器防火墙是否屏蔽了 Telegram API 的出口流量。 3. 查看应用日志,确认 bot 实例已成功创建并开始轮询。 |
6.2 工具集成故障
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 已配置 API Key,但工具调用失败(如搜索无结果) | API Key 未生效;模块未正确加载;工具参数错误 | 1.重启应用:环境变量变动通常需要重启才能生效。 2. 查看启动日志,确认对应工具的 MCP 服务器是否被加载(如 [INFO] WhatsApp MCP server started)。3. 在代码中临时添加日志,打印出工具被调用时的具体参数,检查是否符合 API 要求。 |
| OAuth 类工具(Gmail/Spotify)授权失败 | 回调 URL 配置错误;OAuth 凭证权限不足 | 1. 在 Google Cloud/Spotify Dev 后台,检查“已授权的重定向 URI”是否与工具启动时打印的本地 URL(如http://localhost:3000/oauth2callback)完全匹配。2. 确认 OAuth 凭证中申请的 API 范围(Scopes)包含了工具所需的所有权限。 3. 清除浏览器缓存或尝试无痕模式重新授权。 |
| 工具响应慢或超时 | 第三方 API 限速;网络延迟;工具逻辑复杂 | 1. 为工具调用添加超时设置(如 30 秒),超时后向用户返回友好提示。 2. 对于耗时的操作(如处理长邮件),考虑让工具先返回“正在处理”的中间状态,再异步完成。 3. 检查第三方服务的状态页面,确认是否有服务中断。 |
6.3 对话与记忆异常
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
| Bot 忘记之前的对话 | SQLite 数据库文件权限问题;对话压缩过于激进 | 1. 检查data/目录(或你配置的数据库路径)是否存在且应用有读写权限。2. 查看数据库文件大小,确认数据是否被写入。 3. 调整 conversation/模块中的压缩阈值和摘要长度,避免过早或过度压缩关键历史。 |
回复内容与SOUL.md设定不符 | 系统提示词未正确加载;环境变量覆盖 | 1. 确认SOUL.md文件路径正确,且内容格式为有效的 Markdown/纯文本。2. 检查 .env中是否设置了SYSTEM_PROMPT变量,它会直接覆盖SOUL.md的内容。3. 在日志中输出加载后的系统提示词前 200 个字符,确认其内容。 |
| Token 消耗过快 | MAX_CONTEXT_TOKENS设置过高;工具返回内容过长 | 1. 适当调低MAX_CONTEXT_TOKENS。2. 在工具实现中,对返回给模型的数据进行裁剪或总结。例如,搜索工具可以先总结前 3 条结果,而不是返回全部原始文本。 3. 监控 Claude API 的用量统计,分析异常高峰。 |
维护技巧:
- 日志是关键:使用
winston或pino等日志库,将不同级别的日志(INFO, ERROR, DEBUG)输出到文件和控制台。定期检查 ERROR 日志。 - 数据库备份:
conversation.db文件保存了所有记忆。定期备份这个文件。你可以编写一个简单的脚本,用sqlite3命令将其导出为 SQL 或 CSV 格式。 - 监控 API 成本:为你的 Anthropic API 密钥设置用量告警。可以在 Agent 的代码中集成一个简单的计数器,在每次调用 Claude 后记录 token 消耗,并定期报告。
- 保持更新:关注项目 GitHub 的更新,尤其是
SOUL.md的优化和新的工具集成。更新前,请在测试环境验证。
