将一个命令行界面(CLI)开发者工具转变为在树莓派上运行的、功能完备的个人智能体。
想象一下:你每天都在用的 AI 工具,不需要额外支付 SaaS 订阅费,就能成为你的专属个人助理,这会是什么体验?
我一直想要一个能通过手机、笔记本或任何设备随时控制的 AI 助理。市面上有很多专业的自动化智能体,比如 N8N 或 OpenClaw,它们确实很出色,但都有同一个问题:成本高、使用复杂。
而我已经在使用 Claude Code—— 这是 Anthropic 推出的、功能强大的编程命令行工具。我突然想到:为什么不直接用好我已经拥有的工具呢?
这就是我的故事:我把 Claude Code,一款基于 Shell 的开发者工具,改造成了 Telegram 机器人,并托管在我客厅的树莓派上。
“传统”自动化工具存在的问题
N8N、Make 这类平台功能非常强大,拥有美观的可视化界面,集成起来很方便。但对于独立开发者来说,它们也存在明显短板:
API成本:大多数工具都要求你提供自己的API密钥。通过API调用大语言模型(LLM)的费用累积得非常快。
托管:要可靠地运行这些工具,要么需要付费的云计划,要么需要维护一个庞大的Docker堆栈。
开销:对于个人使用而言,设置时间往往超过了带来的收益。
我的需求很简单:不想重复付费。
我的 Claude Code 订阅,已经覆盖了我高强度的编程使用场景。但问题来了:Claude Code 是命令行工具,只能通过终端调用,而不是 API 接口或 Webhook。
这就成了一个工程挑战:如何把终端命令,变成可用的 API 服务?
架构:将Shell作为后端
claude code提供了一个强大的标志选项:-p,用于非交互式的“打印”模式。结合--output-format json选项,它就可以通过脚本进行控制。
claude -p "Summarize this article" --output-format json
该命令会输出结构化的JSON数据,其中包含响应内容和会话ID(session_id)。
会话ID是关键所在。这意味着我们可以通过在后续调用中简单传递--resume <session_id>来实现有状态、多轮次的对话。
完整的系统由三个简单的层级构成:
1.Telegram机器人:界面(可从任何设备访问)。
3.claude code:作为子进程调用的“大脑”。
代码:将各部分连接起来
1.从Python调用克劳德
我们不使用软件开发工具包(SDK),而是使用Python的subprocess模块来封装二进制文件。
import subprocessimport json
def execute_claude(prompt: str, session_id: str | None = None) -> tuple[str, str]:# Construct the CLI commandcmd = ["claude", "-p", prompt, "--output-format", "json"]# If we have history, resume the sessionif session_id:cmd.extend(["--resume", session_id])# Run the command and capture stdoutresult = subprocess.run(cmd, capture_output=True, text=True, timeout=None)# Parse the JSON outputresponse = json.loads(result.stdout)result_text = response.get("result", "")new_session_id = response.get("session_id", "")return result_text, new_session_id
实现非常简洁:不需要 API 密钥,不需要 HTTP 客户端,只需要一次子进程调用。
2. 管理对话状态
Telegram 机器人的一个难点是:每条消息都是独立事件。想要保持连贯对话,需要把 Telegram 的 user_id 和 Claude 的 session_id 对应起来。
# Simple in-memory storage (can be replaced with Redis/SQLite)_sessions: dict[int, str] = {}
def get_session(user_id: int) -> str | None:return _sessions.get(user_id)def save_session(user_id: int, session_id: str) -> None:_sessions[user_id] = session_id
当消息到达时,先查找用户的会话,传给 Claude 处理,再保存返回的新会话 ID。
3. Telegram机器人逻辑
我选用 aiogram 作为机器人框架,它现代化、支持异步、使用简单。
from aiogram import types
async def handle_message(message: types.Message):# Security check: This is a personal tool, not a public serviceif not is_authorized(message):await message.answer("⛔ Unauthorized access.")return# User feedback is crucial for UXawait message.answer("Claude is thinking... 🧠")# Retrieve session and executesession_id = get_session(message.from_user.id)result_text, new_session_id = execute_claude(message.text, session_id)# Update session stateif new_session_id:save_session(message.from_user.id, new_session_id)# Clean up CLI artifacts (ANSI colors) and sendclean_output = remove_ansi_codes(result_text)# Telegram has a 4096 char limit, so we chunk the responsefor chunk in split_long_message(clean_output):await message.answer(chunk)
关于清理的说明:claude code的输出包含为终端显示设计的ANSI颜色代码。在Telegram中,这些代码显示为乱码字符。在发送消息之前,你必须用正则表达式将其去除。
基础设施:为何树莓派是最佳选择
我也考虑过免费 VPS 平台(比如 Oracle、谷歌云、Mikr.us),但我家里正好有一台树莓派 5。
对于这样的个人项目而言,树莓派具有明显优势:
零月成本:它使用的电力是我已经在支付的。
无“冷启动”:与无服务器函数不同,机器人始终在内存中监听。
完全控制:我可以通过安全外壳协议(SSH)登录,查看日志并手动重启它。
机器人作为systemd服务运行。如果树莓派重新启动,机器人会自动重新上线。
为何选择Telegram?
我研究过短信(费用高昂)、WhatsApp(糟糕的API)以及构建自定义应用程序(太费精力)。
Telegram是最佳选择:
1.免费API:BotFather能在几秒钟内为你提供一个令牌。
2.跨平台:在我的iPhone、iPad、Mac和Linux桌面上都能无缝使用。
3.Python支持:aiogram库使用起来非常愉快。
经验教训
1.非传统工具可能是合适的工具。
claude code并非用于自动化。但它具备我所需的精确功能:非交互模式和JSON输出。有时,最佳解决方案是“误用”你已有的工具。
2.简单的基础设施胜过巧妙的基础设施。
一台运行Python脚本的树莓派很无趣。但它也可靠、可调试且免费。对于一个只服务一个用户的聊天机器人而言,我并不需要Kubernetes。
3.用户体验细节很重要。
处理ANSI代码、分割长消息以及添加“思考中……”指示器并非人工智能问题。但它们是让一个脚本和一个感觉良好的产品之间产生差异的关键所在。
接下来做什么?
该机器人目前能处理一般对话和编程问题。我最近添加了定时任务——每周新闻通讯摘要和实时简讯(RSS)摘要,这些内容会直接推送到我的聊天中。
如果你已经在为claude code(或类似工具)付费,并且有一台闲置的树莓派,不妨尝试用Python将其封装起来。你可能会发现,你根本不再需要那款昂贵的SaaS自动化工具。
你是否尝试过将命令行界面工具用作其他应用程序的后端?请在评论区告诉我——我很好奇还有哪些其他“另类”架构存在。
官方网站:https://edatec.cn/zh/cm0
淘宝店铺:https://edatec.taobao.com/
309