88行代码跑通AI智能体:从消息流到工具调用的极简设计真相

👉 工具网址:https://claw-code.codes/

你可能听说过 Claude Code——Anthropic 推出的 AI 编程助手。但它的原始代码有 51万行 TypeScript,光是 QueryEngine 就占了 4.6 万行。别说读完,打开文件夹都卡顿。

可真相是:一个真正能工作的 AI 智能体(Agent),核心逻辑只需要 88 行代码

这不是夸张,而是真实发生的事——社区开发者 Sigrid Jin 用 Rust 重写了整个系统,把 51 万行压缩到 2 万行,并完整保留了所有关键能力:自动调用工具、权限控制、多轮对话、子智能体、MCP 协议支持……全部在线。

为什么能砍掉 96% 的代码?因为原始版本里塞满了工程细节(打包、兼容、监控、UI 渲染),而真正驱动 AI 工作的「心跳」,其实非常简单。

下面带你直击最硬核的部分:那个只有 88 行的 run_turn() 循环——它就是 AI 智能体的“心脏”。


🧠 核心思想:消息即状态(Messages = State)

传统程序要维护一堆变量:当前步骤、历史记录、工具权限、是否超时……
Claude Code(Rust 版)只留一样东西:

// AgentRuntime 结构体里,唯一需要持久化的状态就是:
session.messages: Vec<Message>  // 所有对话 + 工具结果都存在这里

✅ 用户输入 → 存为 UserMessage
✅ AI 回复 → 存为 AssistantMessage
✅ 工具执行结果 → 存为 ToolResult
✅ 权限拒绝提示 → 也存为 ToolResult(is_error: true)

没有状态机,没有流程图,没有全局变量。只要把这条消息链保存下来,整个对话过程就能随时恢复、调试、压缩、回放。

就像微信聊天记录——删掉 App,只要备份还在,你就没丢任何上下文。


⚙️ 看懂这 88 行:run_turn() 循环(Python 风格伪代码,已加中文注释)

def run_turn(user_input):
    # 1️⃣ 把用户问题加到消息队列末尾
    session.messages.append(UserMessage(user_input))

    # 2️⃣ 开始循环:让 AI 反复思考、调用工具、直到自己决定停下
    while True:
        # 防止死循环:最多执行 max_iterations 次
        if iterations > max_iterations:
            raise Error("AI 思考太多次,强制终止")

        # 3️⃣ 调用大模型(如 Claude),传入系统提示词 + 全部历史消息
        response = api_client.stream(system_prompt, session.messages)

        # 4️⃣ 解析模型返回的回复(可能是纯文字,也可能含工具调用指令)
        assistant_message = parse_response(response)
        session.messages.append(assistant_message)  # 记录 AI 的“发言”

        # 5️⃣ 提取 AI 想调用的工具(例如:bash、read_file、search_web)
        tool_calls = extract_tool_uses(assistant_message)

        # 6️⃣ 如果 AI 没想调工具 → 直接结束本轮,等待下一次用户输入
        if not tool_calls:
            break

        # 7️⃣ 否则,挨个执行每个工具调用
        for tool_name, input in tool_calls:
            # 先检查权限:这个工具,当前 AI 有没有资格用?
            permission = authorize(tool_name, input)

            if permission == Allow:
                # ✅ 有权限 → 执行工具(比如运行 shell 命令)
                result = tool_executor.execute(tool_name, input)
                session.messages.append(ToolResult(result))  # 把结果也记进消息流
            else:
                # ❌ 没权限 → 不报错、不中断,而是把“拒绝理由”当一条普通消息返回给 AI
                session.messages.append(
                    ToolResult(deny_reason, is_error=True)
                )

💡 关键洞察:
AI 自己决定什么时候停(不是程序员写 if 判断);
错误不中断流程,而是变成消息反馈给 AI → 它会立刻调整策略(比如换工具、改提问);
所有中间结果都留在消息里 → 下一轮调用模型时,自然就“记得刚才发生了什么”。


🔧 工具怎么加?3 步搞定(以 bash 命令为例)

  1. 定义工具长啥样(JSON Schema)——直接喂给 AI 看
{
  "name": "bash",
  "description": "执行 Linux/macOS 命令(如 ls -l, git status)",
  "input_schema": {
    "command": "string",      // 必填:要运行的命令
    "timeout": "number?"      // 可选:超时秒数,默认 30
  },
  "required_permission": "DangerFullAccess"  // 运行前必须获得高危权限
}
  1. 写一个执行函数(Rust 或 Python 都行)
fn run_bash(command: String, timeout: u64) -> Result<String, String> {
    // 实际调用 std::process::Command 执行命令
}
  1. 在调度器里加一行映射
match name {
    "bash" => run_bash(input),
    "read_file" => read_file(input),
    "search_web" => search_web(input),
    // ... 其他 15 个工具,每加一个只多 1 行
}

✅ 新工具上线:不用改模型、不用改循环、不用动权限系统——只加 3 处,5 分钟搞定。


🛡️ 权限系统:不是“开/关”,而是“问/等/拒”

它不搞一刀切。比如 AI 想运行 bash(高危操作),但当前只有 WorkspaceWrite 权限:

  • 权限差 1 级 → 弹窗问用户:“AI 想执行命令,允许吗?”
  • 权限差 2 级以上 → 直接拒绝,并把理由写进消息流(AI 看得见!)
  • 完全匹配 → 静默通过

这样既安全,又不打断思考流。

子智能体(sub-agent)也沿用同一套规则:它权限很高,但不能主动向用户要新权限——彻底堵住递归失控风险。


💡 一句话总结 Part 1 的硬核收获:

一个能干活的 AI 智能体,不需要框架、不需要状态机、不需要复杂配置。
它只需要:
– 一个循环(88 行)
– 一套工具接口(JSON Schema + 执行函数)
– 一个渐进式权限判断(5 级 + 人机确认)
– 和一个信念:消息流,就是全部状态

剩下的 50 万行?那是让它“更好用、更稳定、更易维护”的工程层——不是让它“能工作”的必要条件。

下一期我们拆解:AI 是怎么记住上下文的?Prompt 怎么拼?历史消息太多怎么自动压缩?哪些设计模式真正在项目里救过命?

直达网址:https://claw-code.codes/

作加

类似文章