400行代码手搓迷你OpenClaw核心功能  

本文逐步演示如何用Python从零构建具备持久记忆、多平台同步、工具执行、权限控制、定时任务和多代理协作的AI私人助理,完整复现OpenClaw核心架构,附可运行代码与文件结构。  

你也能造出“AI私人管家”!直接上代码、上命令、上文件结构,一步一步从最简单的“会回消息的机器人”开始,慢慢给它加上记忆、性格、手脚(工具)、权限控制、多平台支持、自动任务、甚至多个“人格”!

最后你会发现:原来 OpenClaw 这种高大上的 AI 助手系统,核心原理居然这么简单!



一切从一条 Telegram 消息开始:让 AI 回你话

咱们先干最基础的事:写个程序,让它能在 Telegram 上收消息,然后用 AI 回复你。打开电脑,新建一个 Python 文件,敲下这几行代码:

python
import os
import anthropic
from telegram import Update
from telegram.ext import Application, MessageHandler, filters

client = anthropic.Anthropic()

async def handle_message(update: Update, context):
    user_message = update.message.text

    response = client.messages.create(
        model="claude-sonnet-4-5-20250929",
        max_tokens=1024,
        messages=[{"role": "user", "content": user_message}]
    )

    await update.message.reply_text(response.content[0].text)

app = Application.builder().token(os.getenv("TELEGRAM_BOT_TOKEN")).build()
app.add_handler(MessageHandler(filters.TEXT, handle_message))
app.run_polling()

跑起来之后,你在 Telegram 上给这个机器人发一句“你好吗?”,它就会用 AI 的声音回你。看起来挺酷,对吧?但问题来了:你要是接着问“我刚才说了啥?”,它肯定一脸懵——因为它根本没记性!每句话都是全新的对话,就像每次见面都把你当陌生人。这种 AI,顶多算个高级复读机,离“私人助理”差了十万八千里。



给 AI 装上“记忆硬盘”:聊天记录永久保存

怎么解决“金鱼记忆”?很简单:给它配个“记事本”。每次你说话,它就把对话一行一行写进一个文件里;下次你再说话,它先把之前的聊天记录全读出来,再结合新消息一起问 AI。这样,AI 就知道上下文了!

具体怎么做?用一种叫 JSONL 的格式——每行存一条消息,简单、安全、不怕程序突然崩溃。代码长这样:

python
import json
import os
import anthropic
from telegram import Update
from telegram.ext import Application, MessageHandler, filters

client = anthropic.Anthropic()
SESSIONS_DIR = "./sessions"
os.makedirs(SESSIONS_DIR, exist_ok=True)

def get_session_path(user_id):
    return os.path.join(SESSIONS_DIR, f"{user_id}.jsonl")

def load_session(user_id):
    path = get_session_path(user_id)
    messages = []
    if os.path.exists(path):
        with open(path, "r") as f:
            for line in f:
                if line.strip():
                    messages.append(json.loads(line))
    return messages

def append_to_session(user_id, message):
    path = get_session_path(user_id)
    with open(path, "a") as f:
        f.write(json.dumps(message) + "\n")

async def handle_message(update: Update, context):
    user_id = str(update.effective_user.id)
    user_message = update.message.text

    messages = load_session(user_id)
    user_msg = {"role": "user", "content": user_message}
    messages.append(user_msg)
    append_to_session(user_id, user_msg)

    response = client.messages.create(
        model="claude-sonnet-4-5-20250929",
        max_tokens=4096,
        messages=messages
    )

    assistant_msg = {"role": "assistant", "content": response.content[0].text}
    append_to_session(user_id, assistant_msg)

    await update.message.reply_text(response.content[0].text)

现在你试试:
> 你:我叫小明  
> 机器人:你好啊,小明!  
> (几小时后)  
> 你:我叫啥?  
> 机器人:你叫小明呀!

瞧,它真记住了!所有对话都存在 ./sessions/你的用户ID.jsonl 里,关机重启也不怕丢。这就是 OpenClaw 的核心记忆机制——每个用户一个文件,每条消息一行,稳如老狗。



赋予 AI “灵魂”:让它有性格、有原则、不像客服

光有记忆还不够。现在的 AI 回答太“标准”了,像个没有感情的客服机器人。能不能让它有点个性?比如说话干脆点、别老说“好问题!”、敢表达观点?

当然能!秘诀就是“系统提示词”——你可以把它理解成 AI 的“人设说明书”。在每次调用 AI 时,偷偷塞进去一段话,告诉它:“你叫贾维斯,是我的私人助理,要真诚、别啰嗦、该反对就反对”。

代码里加个变量就行:

python
SOUL = """
# 你是谁

名字: 贾维斯  
角色: 私人 AI 助理  

性格
- 真心帮忙,别装模作样
- 别说“好问题!”,直接帮
- 敢有观点,可以不同意我
- 该简洁就简洁,该详细就详细

底线
- 私事绝不外传
- 不确定的事,先问我再行动
- 别随便替我说话

记忆
记住重要细节,值得记的就写下来。
"""

然后在调用 AI 时加上 system=SOUL

python
response = client.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=4096,
    system=SOUL,
    messages=messages
)

瞬间,AI 就从“通用助手”变成了“你的专属贾维斯”。在 OpenClaw 里,这个人设文件就叫 SOUL.md,放在 ~/.openclaw/workspace/SOUL.md,你想怎么写都行——编个出身故事、定几条行为准则,AI 都会乖乖遵守。



给 AI 装上“手脚”:让它能操作电脑、读写文件、上网搜索

光会聊天太弱了。真正的私人助理得能干活!比如你发一句:“帮我写个打印‘Hello World’的 Python 文件,然后运行它。” 它就得真去创建文件、执行命令、告诉你结果。

怎么做到?靠“工具系统”。你先定义几个工具,比如“运行命令”、“读文件”、“写文件”、“上网搜”,每个工具都有名字、描述和输入格式。AI 看到这些工具后,就能在需要时主动调用。

工具定义长这样:

python
TOOLS = [
    {
        "name": "run_command",
        "description": "在你的电脑上运行命令",
        "input_schema": {
            "type": "object",
            "properties": {
                "command": {"type": "string", "description": "要运行的命令"}
            },
            "required": ["command"]
        }
    },
    {
        "name": "read_file",
        "description": "读取文件内容",
        "input_schema": {
            "type": "object",
            "properties": {
                "path": {"type": "string", "description": "文件路径"}
            },
            "required": ["path"]
        }
    },
    # ... 其他工具
]

然后写个“执行函数”,告诉程序每个工具具体怎么干:

python
def execute_tool(name, input):
    if name == "run_command":
        result = subprocess.run(
            input["command"], shell=True,
            capture_output=True, text=True, timeout=30
        )
        return result.stdout + result.stderr
    elif name == "read_file":
        with open(input["path"], "r") as f:
            return f.read()
    # ... 其他工具实现

最关键的是“代理循环”——AI 可能一次调用多个工具,程序得反复跑:问 AI → 执行工具 → 把结果喂回去 → 再问 AI → 直到它说“搞定了”。

python
def run_agent_turn(messages, system_prompt):
    while True:
        response = client.messages.create(
            model="claude-sonnet-4-5-20250929",
            max_tokens=4096,
            system=system_prompt,
            tools=TOOLS,
            messages=messages
        )

        if response.stop_reason == "end_turn":
            # 没工具要用了,返回最终回答
            return text, messages

        if response.stop_reason == "tool_use":
            # 有工具要执行,执行完再循环
            messages.append({"role": "assistant", "content": content})
            tool_results = []
            for block in response.content:
                if block.type == "tool_use":
                    result = execute_tool(block.name, block.input)
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": str(result)
                    })
            messages.append({"role": "user", "content": tool_results})

现在你发指令:“创建 hello.py 并运行”,它真会干!这才是真正的“智能助理”——不光嘴上说,手上也动。



安全第一!给危险命令上“保险锁”

等等!如果有人黑进你的 Telegram,让机器人执行 rm -rf /(删除整个系统),那不就完蛋了?必须加权限控制!

OpenClaw 的办法很聪明:建个“安全白名单”。常见安全命令(比如 lscat)直接放行;危险命令(比如 rmsudo)一律拦截,除非你手动批准过。

代码里加个检查函数:

python
SAFE_COMMANDS = {"ls", "cat", "head", "tail", "wc", "date", "whoami", "echo"}
DANGEROUS_PATTERNS = [r"\brm\b", r"\bsudo\b", r"\bchmod\b", r"\bcurl.*\|.*sh"]

APPROVALS_FILE = "./exec-approvals.json"

def check_command_safety(command):
    base_cmd = command.strip().split()[0] if command.strip() else ""
    if base_cmd in SAFE_COMMANDS:
        return "safe"

    approvals = load_approvals()
    if command in approvals["allowed"]:
        return "approved"

    for pattern in DANGEROUS_PATTERNS:
        if re.search(pattern, command):
            return "needs_approval"

    return "needs_approval"

执行命令前先检查:

python
if name == "run_command":
    cmd = input["command"]
    safety = check_command_safety(cmd)

    if safety == "needs_approval":
        return "权限不足。此命令需手动批准。"

    # 否则才执行

第一次遇到新命令,它会拒绝并记录。你可以在配置文件 exec-approvals.json 里手动加白名单,比如批准 git * 一整类命令。这样既安全又灵活,再也不怕误操作或被黑!



一仆多主:同一个 AI,同时在 Telegram、微信、Discord 上陪你

你肯定不只想在 Telegram 用它。要是它还能在 Discord、Slack、甚至微信上出现,而且记忆完全同步,那才叫爽!

秘诀是“网关模式”:把 AI 核心逻辑和聊天平台解耦。AI 只管处理“消息列表→回复文本”,不管消息从哪来。Telegram、HTTP、Discord 都只是“输入口”,背后共用同一套会话和记忆。

比如,我们再加个 HTTP 接口:

python
from flask import Flask, request, jsonify
import threading

flask_app = Flask(name)

@flask_app.route("/chat", methods=["POST"])
def chat():
    data = request.json
    user_id = data["user_id"]
    messages = load_session(user_id)
    messages.append({"role": "user", "content": data["message"]})

    response_text, messages = run_agent_turn(messages, SOUL)
    save_session(user_id, messages)
    return jsonify({"response": response_text})

threading.Thread(target=lambda: flask_app.run(port=5000), daemon=True).start()

现在你在 Telegram 告诉它“我叫小明”,然后用 curl 命令通过 HTTP 问“我叫啥?”,它照样答“小明”!因为两个接口用的是同一个用户 ID,读的是同一个 sessions/用户ID.jsonl 文件。

OpenClaw 更进一步:用一个配置文件定义所有平台,自动启动 Telegram、Discord、WhatsApp 等插件,全部共享记忆。你换平台聊天,AI 无缝衔接,就像它真的无处不在。



对付“话痨”:自动压缩超长聊天记录

聊了几个月后,聊天记录可能上万条,超过 AI 的“脑子容量”(上下文窗口)。怎么办?不能直接截断,会丢信息。

解决方案:自动“总结旧账”。当记录太长时,让 AI 自己把前半段对话浓缩成一段摘要,保留关键事实(你的名字、项目进度、待办事项),后半段保留原样。这样既省空间,又不丢重点。

代码实现:

python
def compact_session(user_id, messages):
    if estimate_tokens(messages) < 100_000:
        return messages

    split = len(messages) // 2
    old, recent = messages[:split], messages[split:]

    summary = client.messages.create(
        model="claude-sonnet-4-5-20250929",
        max_tokens=2000,
        messages=[{
            "role": "user",
            "content": (
                "请简洁总结这段对话。保留:\n"
                "- 用户的关键信息(姓名、偏好)\n"
                "- 重要决定\n"
                "- 未完成的任务\n\n"
                f"{json.dumps(old, indent=2)}"
            )
        }]
    )

    compacted = [{
        "role": "user",
        "content": f"[之前对话摘要]\n{summary.content[0].text}"
    }] + recent

    save_session(user_id, compacted)
    return compacted

在每次处理消息前调用它:

python
messages = load_session(user_id)
messages = compact_session(user_id, messages)  # 自动压缩

这样,哪怕聊一年,AI 也永远不会“记不住”。



永久记忆库:就算删聊天记录,AI 也记得你的喜好

会话记忆有个弱点:如果你重置聊天,所有记录就没了。但有些信息(比如“我最爱吃海底捞”)应该永远记住。

所以得建个“长期记忆库”——用文件单独存重要信息。AI 有两个新工具:“保存记忆”和“搜索记忆”。

python
{
    "name": "save_memory",
    "description": "把重要信息存入长期记忆",
    "input_schema": {
        "type": "object",
        "properties": {
            "key": {"type": "string", "description": "标签,如'用户偏好'"},
            "content": {"type": "string", "description": "要记住的内容"}
        },
        "required": ["key", "content"]
    }
},
{
    "name": "memory_search",
    "description": "从长期记忆中查找信息",
    "input_schema": {
        "type": "object",
        "properties": {
            "query": {"type": "string", "description": "搜索关键词"}
        },
        "required": ["query"]
    }
}

执行逻辑很简单:save_memory 把内容写进 ./memory/标签.mdmemory_search 遍历所有 .md 文件找关键词。

你告诉它:“记住我最爱吃海参座,喜欢晚上7点订位。” 它就存到 ./memory/user-preferences.md。就算你删了聊天记录,下次问“我爱去哪吃饭?”,它照样答“海参座,7点”。

OpenClaw 生产版用“向量搜索”——能理解“认证问题”和“登录 bug”是同一件事,比关键词更智能。但咱们这个简易版,够用了!



防止“打架”:多消息同时到达也不乱

如果 Telegram 和 HTTP 同时发消息,两个进程同时读写同一个会话文件,可能把文件搞坏(比如两条消息混在一起)。

解决办法:给每个用户的会话加“锁”。同一时间,只允许一个消息处理。不同用户之间互不影响。

代码加几行:

python
from collections import defaultdict
import threading

session_locks = defaultdict(threading.Lock)

async def handle_message(update: Update, context):
    user_id = str(update.effective_user.id)
    with session_locks[user_id]:  # 加锁
        # ... 处理会话

HTTP 接口也一样加锁。这样,再多消息也不怕乱,稳稳当当排队处理。



自动闹钟:AI 自己醒来干活

真正的助理不该等人叫。它得能自己定时做事,比如每天早上7:30发日报。

schedule 库加个“心跳任务”:

python
import schedule
import time

def setup_heartbeats():
    def morning_briefing():
        session_key = "cron:morning-briefing"  # 独立会话,不污染聊天
        with session_locks[session_key]:
            messages = load_session(session_key)
            messages.append({"role": "user", "content": "早上好!查今天日期,给我一句励志语录。"})
            response_text, messages = run_agent_turn(messages, SOUL)
            save_session(session_key, messages)
        print(f" {response_text}")

    schedule.every().day.at("07:30").do(morning_briefing)

    def scheduler_loop():
        while True:
            schedule.run_pending()
            time.sleep(60)
    threading.Thread(target=scheduler_loop, daemon=True).start()

启动时调用 setup_heartbeats(),AI 就会准时干活。OpenClaw 支持完整 cron 表达式(比如 30 7 * * *),还能把任务结果推送到你的聊天窗口。



多人格切换:一个身体,多个专家

一个 AI 搞不定所有事。你需要一个“通用助理”+一个“研究专家”。

办法是“多代理路由”:根据消息开头的指令(比如 /research),切换到不同人设、不同会话。

定义多个代理:

python
AGENTS = {
    "main": {
        "name": "贾维斯",
        "soul": SOUL,
        "session_prefix": "agent:main",
    },
    "researcher": {
        "name": "侦察兵",
        "soul": """你是侦察兵,专攻研究。
任务:找信息、引来源。每句话都要有证据。
用工具收集数据,保存发现供他人参考。""",
        "session_prefix": "agent:researcher",
    },
}

路由函数:

python
def resolve_agent(message_text):
    if message_text.startswith("/research "):
        return "researcher", message_text[len("/research "):]
    return "main", message_text

处理消息时:

python
agent_id, message_text = resolve_agent(update.message.text)
agent = AGENTS[agent_id]
session_key = f"{agent['session_prefix']}:{user_id}"  # 不同会话

现在:
> 你:今天天气咋样?  
> [贾维斯] 晴天!  
> 你:/research Python 异步最佳实践?  
> [侦察兵] 找到了!1. 用 asyncio.gather...  
> 你:侦察兵找到啥了?  
> [贾维斯] 用 memory_search 查到:异步最佳实践是...

两个 AI 共享记忆库,完美协作!



终极整合:400 行代码,手搓迷你 OpenClaw

把上面所有功能揉进一个文件 mini-openclaw.py,不到 400 行,却包含:
- 会话记忆(JSONL)
- 人设系统(SOUL)
- 工具执行(命令、文件、搜索)
- 权限控制(白名单)
- 网关模式(Telegram + HTTP)
- 会话压缩
- 长期记忆(文件存储)
- 消息队列(加锁)
- 定时任务(心跳)
- 多代理路由

运行命令:

bash
uv run --with anthropic --with schedule python mini-openclaw.py

效果:
> 你:记住我爱海参座,7点订位  
> save_memory → 存入 memory/user-preferences.md  
> [贾维斯] 记住了!  
> 你:/new(重置会话)  
> 你:我爱去哪吃饭?  
> memory_search → 找到 user-preferences.md  
> [贾维斯] 海参座,7点!  
> 你:/research 2025 AI 趋势?  
> web_search → 保存 research-ai-agents.md  
> [侦察兵] 最新趋势是...

所有功能跑通,记忆持久,安全可控,多平台同步——这就是 OpenClaw 的灵魂!



OpenClaw 的生产级升级:从玩具到武器

咱们的迷你版已经很强大,但 OpenClaw 在此基础上还有狠活:

语义网页快照:不用截图(太大),而是用 Playwright 提取网页的“文字骨架”,带编号引用。AI 说“点 ref=1”,程序就知道点哪个按钮,精准又省 token。

会话作用域:支持 main(全局)、per-peer(每人一个)、per-channel-peer(每平台每人一个),还能手动合并不同平台的会话。

插件化通道:Telegram、Discord、WhatsApp 各是一个插件,新增平台只需写一个适配器,不碰核心逻辑。

向量记忆搜索:用 SQLite + 嵌入模型,实现“语义搜索”,“登录问题”能匹配“认证错误”。

子代理孵化:主 AI 能临时召唤一个“子专家”去深度研究,完成后汇报结果,实现复杂任务分解。



总结:你不需要魔法,只需要逻辑

从一条 Telegram 消息开始,一步步加上记忆、性格、手脚、安全锁、多平台、自动任务、多专家……每一个功能都源于一个真实痛点,每一个方案都简单直接。OpenClaw 不是魔法,而是一堆清晰逻辑的叠加。你完全能自己造一个,甚至比它更好!