
1. 项目概述从OpenClaw到“迷你版”的实践路径最近在AI智能体开发圈子里OpenClaw这个名字的热度一直居高不下。作为一个集成了Claude等大模型能力、旨在构建复杂工作流和自动化任务的智能体框架它确实代表了当前AI应用开发的一个前沿方向。然而对于大多数个人开发者、小团队或者只是想快速体验智能体魅力的朋友来说原版的OpenClaw框架可能显得有些“重”了。它的部署依赖复杂对计算资源有一定要求并且其完整的功能体系可能超出了快速验证一个想法或搭建一个轻量级助手的需求。这正是“打造迷你版OpenClaw”这个项目的出发点。我们不做功能全覆盖的“巨无霸”而是聚焦核心提取OpenClaw中最为精髓的“智能体”交互逻辑与任务编排思想用一个更轻量、更易上手的技术栈来实现。我们的目标很明确在个人电脑、一台轻量云服务器甚至一个容器里快速搭建一个能够理解自然语言指令、调用工具如搜索、计算、文件处理、并按照逻辑执行多步任务的AI助手。它应该能通过像Telegram这样普及的通讯工具与你对话背后则连接着Claude或类似的大模型作为“大脑”。这个迷你版的核心价值在于“降本提效”和“快速验证”。你不需要深入理解OpenClaw庞大的代码库和复杂的架构设计就能获得一个可运行、可定制、能解决实际问题的智能体原型。无论是想做一个自动整理会议纪要的机器人一个根据关键词爬取并总结资讯的助手还是一个帮你管理待办清单的智能管家都可以从这个迷你项目起步。它剥离了企业级部署的复杂性保留了智能体交互的灵魂是进入AI智能体开发世界一块极好的敲门砖。2. 核心架构设计与技术选型思路要打造一个“迷你版”关键在于界定“最小可行产品”MVP的边界并选择合适的技术组件。我们的架构核心可以概括为一个通讯接口、一个智能中枢、一套工具库、一个任务执行引擎。2.1 通讯接口层为什么选择Telegram Bot在众多通讯平台中Telegram Bot API以其功能强大、文档清晰、部署简单和全球可访问性脱颖而出成为个人项目和小型智能体的首选。低门槛与高灵活性注册一个Bot通过BotFather几分钟就能完成获取的Token就是通往Telegram海量用户的钥匙。其API支持发送富文本、图片、文件、按钮等多种消息格式完全能满足智能体丰富的交互需求。天然的隐私与上下文每个与Bot的对话都是一个独立的会话Chat这为我们管理用户对话上下文提供了便利。我们可以很容易地将对话ID与后端用户的会话状态绑定。无需处理底层网络相比自建WebSocket或HTTP服务器处理即时消息Telegram Bot通过长轮询getUpdates或更高效的Webhook方式推送消息让我们只需关注业务逻辑省去了大量底层通讯设施的建设工作。对于迷你版项目我们优先使用长轮询方式因为它不需要一个公网HTTPS服务器在本地开发调试时极其方便。2.2 智能中枢大脑大模型API的选型与考量智能体的“智力”来源于大语言模型。ClaudeAnthropic无疑是顶尖选择之一以其强大的推理能力和长上下文窗口著称。Claude API的接入直接使用Anthropic提供的官方API是最稳定的方式。你需要注册并获取API Key。在代码中我们将通过HTTP请求调用其/v1/messages端点。重点在于构建符合其格式要求的请求体包括model如claude-3-haiku-20240307成本较低响应快、max_tokens、messages历史对话数组以及可选的system提示词。备选方案与降级策略考虑到Claude API可能对新区用户受限如网络热词中提到的“not available to new users”或者出于成本控制必须准备备选方案。OpenAI的GPT系列API是直接的替代品其调用方式类似且生态工具更丰富。此外开源模型本地部署是一个更有挑战性但完全自主可控的方向例如使用Ollama本地运行Llama 3、Qwen或DeepSeek-Coder等模型。虽然效果可能略逊于顶级闭源模型但对于许多确定性任务和简单推理已经完全足够且实现了零API成本、数据完全私有。提示词Prompt工程这是智能体的“灵魂塑造”。我们需要精心设计system提示词来定义这个迷你OpenClaw的身份、能力边界和行为规范。例如“你是一个高效的任务执行助手。你可以调用工具来获取信息、处理数据或执行操作。请逐步思考并在需要时明确请求调用哪个工具。”2.3 工具库与任务引擎轻量级实现方案完整的OpenClaw有一套复杂的技能Skill和工作流Workflow定义系统。在迷你版中我们将其简化为“工具调用Function Calling”和“顺序任务链”。工具抽象与注册我们将每一项能力定义为一个“工具”例如search_web网络搜索、calculate计算器、get_weather获取天气、read_file读取文件。每个工具都有明确的名称、描述和参数JSON Schema。这个描述对于大模型理解何时、如何调用该工具至关重要。任务执行流接收用户消息Telegram Bot收到用户输入。调用大模型思考将用户消息、历史对话以及所有可用工具的描述发送给大模型如Claude。大模型会判断是否需要调用工具以及调用哪个工具并传入什么参数。解析与执行后端服务解析大模型的返回。如果返回中包含一个标准的工具调用请求如Claude的tool_use块则根据工具名找到对应的本地函数传入参数并执行。结果反馈与循环将工具执行的结果作为新的上下文再次发送给大模型让大模型生成面向用户的最终回答或决定下一步行动。这个过程形成一个循环直到大模型认为任务完成并输出最终答案。回复用户将最终答案通过Telegram Bot发送给用户。状态管理对于简单的单轮对话无需复杂状态管理。但对于多轮复杂任务需要在服务器内存或一个轻量数据库如SQLite中维护一个简单的会话状态记录当前对话的上下文历史、已执行步骤等确保任务链不会中断。技术栈总结后端语言Python是首选因其在AI和快速开发领域的绝对优势库生态丰富requests,openai,anthropic,python-telegram-bot等。依赖管理使用pip和requirements.txt。部署初期本地运行后期可轻松部署到任何支持Python的云服务器或容器Docker中。3. 一步步实现从零搭建你的迷你智能体下面我们进入具体的实操环节。请确保你的开发环境已安装Python 3.8。3.1 环境准备与依赖安装首先创建一个项目目录并初始化虚拟环境这能有效隔离项目依赖。mkdir mini-openclaw cd mini-openclaw python -m venv venv # Windows: venv\Scripts\activate # Linux/Mac: source venv/bin/activate接下来安装核心依赖库。我们将使用python-telegram-bot这个高级封装库来简化Telegram交互使用anthropic官方库调用Claude同时为可能用到的工具准备一些辅助库。pip install python-telegram-bot[ext] anthropic requests # 可选用于可能需要的工具函数 # pip install beautifulsoup4 lxml # 用于网页抓取 # pip install sqlite3 # Python内置无需安装用于状态存储创建项目基础文件结构mini-openclaw/ ├── main.py # 主程序入口 ├── bot.py # Telegram Bot处理逻辑 ├── agent.py # 智能体核心模型调用、工具执行 ├── tools.py # 工具函数定义 ├── config.py # 配置文件API密钥等 ├── requirements.txt └── .env # 环境变量文件切勿提交至Git3.2 配置管理与密钥安全永远不要将API密钥硬编码在代码中。我们使用.env文件和环境变量来管理。创建.env文件TELEGRAM_BOT_TOKEN你的Telegram_Bot_Token ANTHROPIC_API_KEY你的Claude_API_Key # OPENAI_API_KEY你的OpenAI_API_Key 备用创建config.py来读取配置import os from dotenv import load_dotenv load_dotenv() # 加载 .env 文件中的变量 class Config: TELEGRAM_TOKEN os.getenv(TELEGRAM_BOT_TOKEN) ANTHROPIC_API_KEY os.getenv(ANTHROPIC_API_KEY) # OPENAI_API_KEY os.getenv(OPENAI_API_KEY) # 模型配置 CLAUDE_MODEL claude-3-haiku-20240307 # 根据成本和速度选择如claude-3-sonnet-20240229 # GPT_MODEL gpt-4o-mini # 备用模型 # 其他配置 MAX_HISTORY_LENGTH 10 # 保留的对话历史轮数 config Config()3.3 实现工具库tools.py工具是智能体的手脚。这里我们实现几个示例工具。import requests import json import math def search_web(query: str, max_results: int 3) - str: 模拟网络搜索实际项目中可接入Serper、Google Custom Search等API 参数: query: 搜索关键词 max_results: 返回的最大结果数 返回: 格式化的搜索结果字符串 # 注意这是一个模拟函数。真实接入需要注册搜索API并处理认证。 # 此处返回模拟数据用于演示。 print(f[工具调用] 搜索网络: {query}) # 假设的搜索结果 mock_results [ {title: f关于 {query} 的百科介绍, snippet: f这里是一些关于{query}的摘要信息...}, {title: f{query} 的最新动态, snippet: 近期相关动态的简述...}, {title: f深入探讨 {query}, snippet: 更多深度内容的描述...} ] result_str f针对“{query}”的搜索结果模拟:\n\n for i, res in enumerate(mock_results[:max_results], 1): result_str f{i}. **{res[title]}**\n {res[snippet]}\n\n return result_str.strip() def calculate(expression: str) - str: 计算数学表达式。 参数: expression: 数学表达式如 2 3 * (sqrt(16) - 1) 返回: 计算结果或错误信息。 print(f[工具调用] 计算: {expression}) # 安全警告在生产环境中直接eval是危险的应使用更安全的表达式解析器如 ast.literal_eval 或 numexpr。 # 此处为演示简化处理仅支持基本数学运算和少量安全函数。 allowed_names {k: v for k, v in math.__dict__.items() if not k.startswith(_)} allowed_names.update({abs: abs, round: round}) try: # 非常基础的沙箱环境实际应用需更严谨 result eval(expression, {__builtins__: {}}, allowed_names) return f计算结果: {expression} {result} except Exception as e: return f计算表达式“{expression}”时出错: {str(e)} def get_weather(city: str) - str: 获取城市天气模拟。 参数: city: 城市名 返回: 天气信息字符串。 print(f[工具调用] 获取天气: {city}) # 模拟API调用 # 真实情况可接入和风天气、OpenWeatherMap等 weather_data { 北京: {temp: 22°C, condition: 晴, humidity: 40%}, 上海: {temp: 25°C, condition: 多云, humidity: 65%}, 深圳: {temp: 28°C, condition: 阵雨, humidity: 80%}, } info weather_data.get(city, None) if info: return f{city}的天气温度{info[temp]}{info[condition]}湿度{info[humidity]}。 else: return f未找到{city}的天气信息请检查城市名称。 # 工具注册表供智能体查询 TOOLS [ { name: search_web, description: 在互联网上搜索信息。当用户询问需要最新、外部知识或广泛信息的问题时使用。, parameters: { type: object, properties: { query: {type: string, description: 搜索关键词。}, max_results: {type: integer, description: 返回结果的最大数量默认3。} }, required: [query] } }, { name: calculate, description: 计算一个数学表达式的结果。支持加减乘除、括号及常见数学函数如sqrt, sin, cos等。, parameters: { type: object, properties: { expression: {type: string, description: 要计算的数学表达式。} }, required: [expression] } }, { name: get_weather, description: 获取指定城市的当前天气情况。, parameters: { type: object, properties: { city: {type: string, description: 城市名称例如‘北京’、‘上海’。} }, required: [city] } } ]3.4 实现智能体核心agent.py这是项目的大脑负责与大模型对话、管理工具调用循环。import json from typing import List, Dict, Any, Optional import config from anthropic import Anthropic # import openai # 备用 from tools import TOOLS, search_web, calculate, get_weather class MiniClawAgent: def __init__(self): self.client Anthropic(api_keyconfig.config.ANTHROPIC_API_KEY) self.model config.config.CLAUDE_MODEL # 简单的内存会话存储键为chat_id值为消息历史列表 self.conversation_history: Dict[int, List[Dict]] {} def _get_history(self, chat_id: int) - List[Dict]: 获取或初始化指定聊天ID的历史记录。 if chat_id not in self.conversation_history: self.conversation_history[chat_id] [] return self.conversation_history[chat_id] def _truncate_history(self, history: List[Dict], max_length: int config.config.MAX_HISTORY_LENGTH): 截断过长的历史记录保留最近的对话。 if len(history) max_length * 2: # 乘以2因为每条记录包含user和assistant # 保留系统消息如果有和最近的对话 system_msg [msg for msg in history if msg.get(role) system] recent_msgs history[-(max_length*2):] history.clear() history.extend(system_msg recent_msgs) def _execute_tool(self, tool_name: str, tool_input: Dict) - str: 根据工具名称和输入参数执行对应的工具函数。 tool_mapping { search_web: search_web, calculate: calculate, get_weather: get_weather, } func tool_mapping.get(tool_name) if not func: return f错误未知的工具 {tool_name}。 try: # 将参数字典解包传递给函数 result func(**tool_input) return str(result) except Exception as e: return f执行工具 {tool_name} 时发生错误: {str(e)} def process_message(self, user_input: str, chat_id: int) - str: 处理用户输入的核心循环。 返回最终要发送给用户的文本。 history self._get_history(chat_id) # 1. 构建系统提示词定义助手身份和能力 system_prompt f你是一个名为MiniClaw的智能助手是OpenClaw框架的轻量级实现。你可以调用工具来帮助用户解决问题。 你可以使用的工具如下 {json.dumps(TOOLS, indent2, ensure_asciiFalse)} 请遵循以下规则 1. 仔细分析用户请求判断是否需要调用工具。 2. 如果需要调用工具请严格按照工具定义的参数格式生成一个包含“tool_name”和“tool_input”的JSON对象。 3. 如果不需要工具或工具结果已足够回答问题请直接给出友好、清晰的回答。 4. 一次只调用一个工具。 现在开始与用户对话。 # 如果是新会话初始化历史 if not history: history.append({role: system, content: system_prompt}) # 2. 将用户输入加入历史 history.append({role: user, content: user_input}) # 3. 与大模型交互的循环 final_response max_turns 5 # 防止无限循环 for turn in range(max_turns): # 准备发送给Claude的消息包含全部历史 messages_for_api history.copy() try: response self.client.messages.create( modelself.model, max_tokens1024, messagesmessages_for_api, toolsTOOLS # 将工具定义传给Claude ) except Exception as e: # 处理API错误例如网络问题、额度不足 error_msg f调用AI模型时出错: {str(e)} print(error_msg) history.append({role: assistant, content: error_msg}) return 抱歉智能大脑暂时无法访问请稍后再试。 # 4. 解析Claude的响应 response_content_blocks response.content tool_use_block None text_response for block in response_content_blocks: if block.type text: text_response block.text elif block.type tool_use: tool_use_block block # 我们假设一次只处理一个工具调用 break # 5. 处理工具调用 if tool_use_block: tool_name tool_use_block.name tool_input tool_use_block.input print(f[Agent] 模型请求调用工具: {tool_name}, 输入: {tool_input}) # 将工具调用记录到历史 history.append({ role: assistant, content: [{type: tool_use, **tool_use_block.dict()}] }) # 执行工具 tool_result self._execute_tool(tool_name, tool_input) print(f[Agent] 工具执行结果: {tool_result[:100]}...) # 将工具结果作为新的用户消息实际上是工具返回的消息加入历史 history.append({ role: user, content: [{ type: tool_result, tool_use_id: tool_use_block.id, content: tool_result }] }) # 继续循环让模型基于工具结果生成回答 continue else: # 6. 没有工具调用生成最终回答 final_response text_response.strip() # 将助手的最终回答加入历史 history.append({role: assistant, content: final_response}) break # 7. 清理历史防止过长 self._truncate_history(history) self.conversation_history[chat_id] history if not final_response and turn max_turns - 1: final_response 任务似乎过于复杂已超出最大处理轮数。请尝试简化您的问题。 return final_response3.5 实现Telegram机器人bot.py这部分负责与Telegram平台对接接收和发送消息。import logging from telegram import Update from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes import config from agent import MiniClawAgent # 启用日志便于调试 logging.basicConfig( format%(asctime)s - %(name)s - %(levelname)s - %(message)s, levellogging.INFO ) logger logging.getLogger(__name__) # 初始化智能体 agent MiniClawAgent() async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): 处理 /start 命令。 user update.effective_user welcome_text ( f你好{user.first_name}\n\n 我是 MiniClaw一个轻量级的智能任务助手。\n 我可以帮你搜索信息、计算数学表达式、查询天气等。\n 直接对我说你想做什么吧例如\n • ‘北京今天的天气怎么样’\n • ‘计算一下 15的平方加上sin(30度) 等于多少’\n • ‘搜索一下最近关于人工智能的新闻’模拟 ) await update.message.reply_text(welcome_text) async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE): 处理 /help 命令。 help_text ( **可用命令**:\n /start - 开始使用并查看介绍\n /help - 显示此帮助信息\n /clear - 清除当前对话的历史记录\n\n **我能做什么**:\n • 回答一般性问题\n • 调用工具执行任务如计算、查询天气模拟、搜索模拟\n • 进行多轮对话以完成复杂指令\n\n 直接输入你的问题或指令即可。 ) await update.message.reply_text(help_text, parse_modeMarkdown) async def clear_history(update: Update, context: ContextTypes.DEFAULT_TYPE): 处理 /clear 命令清除当前对话的上下文。 chat_id update.effective_chat.id if chat_id in agent.conversation_history: del agent.conversation_history[chat_id] await update.message.reply_text(对话历史已清除。我们可以重新开始了。) async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE): 处理用户发送的文本消息。 chat_id update.effective_chat.id user_message update.message.text if not user_message.strip(): await update.message.reply_text(请输入一些内容。) return # 发送“正在思考”的提示异步不阻塞 thinking_msg await update.message.reply_text( 正在思考...) try: # 调用智能体处理消息 bot_reply agent.process_message(user_message, chat_id) # 删除“正在思考”提示 await thinking_msg.delete() # 发送最终回复 await update.message.reply_text(bot_reply) except Exception as e: logger.error(f处理消息时出错: {e}, exc_infoTrue) await thinking_msg.delete() await update.message.reply_text(抱歉处理你的请求时出现了内部错误。) def main(): 启动机器人。 if not config.config.TELEGRAM_TOKEN: logger.error(未设置 TELEGRAM_BOT_TOKEN请在 .env 文件中配置。) return # 创建Application实例 application Application.builder().token(config.config.TELEGRAM_TOKEN).build() # 注册命令和消息处理器 application.add_handler(CommandHandler(start, start)) application.add_handler(CommandHandler(help, help_command)) application.add_handler(CommandHandler(clear, clear_history)) application.add_handler(MessageHandler(filters.TEXT ~filters.COMMAND, handle_message)) # 启动机器人使用长轮询适合开发和没有公网IP的环境 logger.info(MiniClaw 机器人已启动正在轮询消息...) application.run_polling(allowed_updatesUpdate.ALL_TYPES) if __name__ __main__: main()3.6 主程序入口与启动main.py这个文件很简单就是启动Bot。from bot import main if __name__ __main__: main()3.7 运行你的迷你OpenClaw获取并配置密钥在Telegram中搜索BotFather按指示创建新Bot获得TELEGRAM_BOT_TOKEN。访问Anthropic官网注册并获取ANTHROPIC_API_KEY。将这两个密钥填入项目根目录的.env文件中。安装依赖并运行pip install -r requirements.txt # 如果已安装可跳过 python main.py测试 打开Telegram找到你的Bot发送/start然后尝试以下指令“北京和上海的天气差多少”它会依次调用get_weather工具“计算一下半径为5的圆的面积。”“搜索关于机器学习的最新趋势。”调用模拟搜索观察控制台日志你会看到智能体思考、调用工具、返回结果的完整过程。4. 部署、优化与问题排查4.1 从本地到服务器部署本地运行成功后你可能希望让它7x24小时在线。部署到云服务器是标准做法。传统服务器部署购买一台轻量应用服务器如腾讯云Lighthouse、AWS Lightsail。通过SSH将代码上传至服务器。在服务器上同样配置Python环境、安装依赖、设置.env。使用tmux或screen会话运行python main.py或者更好的是配置为系统服务systemd。容器化部署Docker 这是更优雅、可移植的方式。在项目根目录创建DockerfileFROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [python, main.py]构建并运行镜像docker build -t mini-openclaw . docker run -d --name mini-claw-bot --env-file .env mini-openclaw这会将你的整个环境打包在任何支持Docker的地方一键运行。4.2 性能与功能优化方向基础版本跑通后可以考虑以下优化会话状态持久化当前会话历史存储在内存中服务器重启即丢失。可以集成SQLite或Redis将会话历史持久化存储。异步处理python-telegram-bot本身支持异步。对于耗时的工具调用如真实网络请求应使用asyncio避免阻塞主线程提升机器人响应能力。增加更多工具根据你的需求集成更多实用工具如send_email发送邮件。query_database查询内部数据库。create_chart用Matplotlib生成图表。接入真实的搜索API、天气API。引入工作流当前是简单的“思考-行动”循环。可以定义更复杂的工作流例如“收集需求-规划步骤-并行执行工具-汇总报告”这需要扩展agent.py中的状态机逻辑。前端界面除了Telegram可以增加一个简单的Web界面使用FastAPI或Flask构建提供另一种交互方式。4.3 常见问题与排查技巧在开发和运行过程中你可能会遇到以下问题问题一运行python main.py后立刻报错或没有任何反应。排查首先检查.env文件中的TELEGRAM_BOT_TOKEN格式是否正确是否有空格或换行。使用print(config.config.TELEGRAM_TOKEN)在代码中打印确认是否成功加载。解决确保Token以字符串形式正确配置。如果使用Docker确认--env-file参数指向了正确的文件。问题二Bot能收到/start命令但回复普通消息时长时间无响应或报错。排查查看控制台日志。最常见的原因是Claude API调用失败。网络问题服务器是否能访问api.anthropic.com尝试curl测试。API密钥无效或额度不足登录Anthropic控制台检查密钥状态和用量。模型不可用如遇热词中提到的“Claude is not available to new users”需等待或使用备选模型如GPT。在agent.py中快速切换为OpenAI API是很好的降级方案。解决确保网络通畅API密钥有效且有额度。在代码中加入更详细的错误捕获和日志明确失败原因。问题三智能体不调用工具总是直接回答。排查提示词Prompt问题检查system_prompt中是否清晰说明了工具的存在和使用规则。描述是否足够详细工具描述问题tools.py中每个工具的description是否准确描述了其用途和适用场景大模型依赖这个描述来做判断。用户指令模糊对于“今天热吗”这种问题模型可能直接根据知识回答。更明确的指令如“调用天气工具查一下北京今天温度”更容易触发工具调用。解决优化提示词和工具描述。在system_prompt中强调“当你需要最新信息、计算或执行特定操作时必须调用工具”。可以要求模型在思考过程中先输出其推理链Chain-of-Thought这有助于调试。问题四工具调用参数错误或执行失败。排查查看控制台打印的tool_input。模型生成的参数是否符合工具函数定义的参数类型如字符串、整数是否缺少必需参数解决在工具函数的description和parameters中更严格地定义参数。在_execute_tool函数中加入更完善的参数验证和类型转换逻辑。对于复杂的参数可以在提示词中给出更具体的示例。问题五对话历史混乱上下文丢失或过长导致API开销大。排查检查_truncate_history函数是否正常工作。过长的历史会导致API调用token数激增成本上升且可能超出模型上下文窗口。解决优化历史管理策略。例如不是简单截断而是进行摘要Summarization将很旧的对话内容总结成一段简短的背景信息再附上最近的几条完整对话。这需要额外的处理逻辑但能有效平衡上下文长度和成本。这个迷你版OpenClaw项目就像一个乐高积木的基础底板。你已经拥有了一个能听Telegram、能想Claude、能做工具的智能体核心。接下来如何扩展它的能力、优化它的表现、将它应用到具体的业务场景中就完全取决于你的想象力和实际需求了。从自动回复客服到个人知识管理从自动化数据报表到智能家居控制这个小小的框架足以支撑起一片广阔的AI应用试验田。