门户首页
专题系列 · 第 1 期 · 专题讲解与实现

专题 1 · 最小化 Agent Loop:亲手造一个简化版 Code Agent

Claude Code、Cursor 这类产品看起来像魔法,拆开却是一个再朴素不过的循环。 本专题按「总 → 分 → 例 → 实」四篇展开:先用一张图把整个概念体系讲清楚(总),再逐个展开六个步骤(分),跟着一个真实开源任务(给 pytest 改进默认日志格式,改一行常量)看五轮消息流与本仓实测轨迹(例),最后给出一个约 100 行、4 个工具的最简完整实现(实)——例与实用的是同一个任务,概念版与代码版互为镜像。动手环节配有离线实验包(篇四 · 路径 A):Agent、任务仓库、Python 3.9 环境与判分材料打进一个 zip,下载解压即可在本机亲手跑通这道真题——零 GitHub 依赖,开箱即用。

生成时间:2026-09-13 · 版本 v0.2 · 生成 Agent:TraeWork · 载体:agentsoft-research-platform teaching-web-platform

概览

6
步骤
4
工具
5
轮预演走完任务
~100
行实现
项目说明
本页定位专题系列第 1 期 · 专题讲解与实现层——把六部分规格页的每个概念讲清并落成一个能跑的程序
前置知识会 Python 基础语法;读过 agent-minimal-six-parts.html(不读也行,本页概念是自包含的)
读完会什么能指着总框图讲清六个步骤各自干什么;能在本机(Win/Mac/Linux)构造环境亲手跑通一个真实开源任务的 Agent;能说清真实轨迹与教学预演的差距(口径:205 / 60 / 58 / 27)
三阶递进位置概念(三角色模型)→ 规格(六部分页)→ 动手(本页);往上还有工程层(agent-harness-loop.html)

篇一 · 总:一张图看懂整个概念体系

篇一 · 总(先建立整体,不展开任何细节)
一句话 + 一张图 + 一个类比。这张总图是全篇的地图——后面每讲一步,就回来点亮图上的一块。
总 · 1 定义 + 1 总图 + 1 类比

Agent 程序:让模型在"想 → 做 → 记"循环里干活的程序

一句话定义:Agent 程序本质上是一个循环调度系统——它让大模型能够调用外部工具、获取执行结果、并基于结果继续推理,直到任务完成。大模型自己只会"想"(生成文字或工具调用请求),不会"做"(碰不到你的文件系统);Agent 程序就是补上"做"和"记"的那层代码。

图 1 · 总框图:六个步骤 + 一个循环(全篇地图)
flowchart TD U["👤 用户给出任务"] --> INIT["初始化:② 系统提示词 + 任务 → 写入 ③ 对话历史"] INIT --> LOOP{"⑥ 主循环
下一轮"} LOOP --> CALL["④ 模型调用器
把 ③ 历史 + ① 工具清单 发给模型"] CALL --> LLM["🟧 大模型 API
只会想,不会做"] LLM --> PARSE{"⑤ 解析调度
要调用工具吗?"} PARSE -->|"不要(纯文本)"| DONE["✅ 输出总结
循环结束"] PARSE -->|"要"| EXEC["① 执行工具
→ 🟩 文件世界被改变"] EXEC --> REC["③ 把执行结果
记回对话历史"] REC --> LOOP
图 1 · 总框图。①②③ 是"准备件",④⑤ 是"每轮的进出通道",⑥ 是唯一驱动者——所有箭头最终都回到 ⑥,由它决定继续还是停止。
一个类比:三个角色 + 一个代理
角色特点对应步骤
大脑会想,不会做,转身就忘④⑤(模型调用 + 解析)
手会做,不会想①(工具清单)
小本子不会思考,但记得一切③(对话历史)
代理替用户把任务办成——安排"想→做→记"循环,管何时停⑥(主循环)+ ②(给大脑的岗位说明书)

顺带一提:Agent 这个词的本义就是"代理"——它替你把任务办完,而办事的过程,就是 ⑥ 那个"想→做→记"循环。

读图要诀:判断你有没有"看懂总图",就看能否回答这两个问题——①大模型每轮能看到什么?(答案:只有 ③ 小本子上写的 + ① 工具清单);②循环什么时候停?(答案:⑤ 判定模型不再要工具时,或 ⑥ 的守门条件触发)。
地图:①②③准备件 / ④⑤通道 / ⑥驱动

篇二 · 分:六个步骤逐个展开(纯概念)

篇二 · 分(每步三问:干什么 / 为什么需要 / 没有它会怎样)
六张卡对应总图的六块。本篇只讲概念,一行代码都不出现——代码留给篇四。
步骤 1 / 6 · 总图左下块

① 工具清单:声明"能做什么"

干什么:列出模型可以调用的外部操作——每个工具有名字、说明和参数格式,并对应一个真正干活的本地函数。

为什么需要

大模型本身碰不到你的文件系统、执行不了命令——它只能"请求你替它做"。工具清单就是这份"可请求菜单"。

没有它会怎样

模型只能空谈。你问"帮我把端口改了",它回复一段"你可以这样修改……"的说明文字,而不是真的去改。

对应 API 字段:tools
步骤 2 / 6 · 总图入口块

② 系统提示词:约束"该怎么做"

干什么:一段预先写好的指令,规定模型的角色、做事规则和安全边界,作为对话的第一条消息。

为什么需要

模型的默认行为是"通用聊天助手"。同样是拿到改日志格式的任务,没有约束的模型可能反问你十个问题;有了"需要了解代码就先读、改完用 bash 验证、验证通过就总结并停止"的规矩,它才会按 Agent 的方式行动。

没有它会怎样

同一个模型、同一套工具,行为完全不可预期——系统提示词才是 Agent 真正的"岗位说明书",换一段提示词就是另一个 Agent。

对应位置:对话的第一条消息
步骤 3 / 6 · 总图中枢块

③ 对话历史:记住"做过什么"

干什么:维护一份按时间排列的消息列表——用户任务、模型每次的决策、每次工具的执行结果,全部追加在这里。

为什么需要

大模型 API 是"无状态"的:每次调用它都从零开始,不记得上一轮说过什么。它唯一能"看到"的世界,就是你每次发给它的这份历史。没写进历史的事,等于没发生过。

没有它会怎样

模型每轮失忆:读完文件忘了内容,改完文件不知道自己改过什么,同一个文件读十遍也完不成任务。

对应 API 字段:messages
步骤 4 / 6 · 总图出口块

④ 模型调用器:负责"怎么通信"

干什么:封装与大模型 API 的全部通信——组装请求(历史 + 工具清单)、身份认证、超时与重试。

为什么需要

每一轮循环都要"打包发给模型、收回回复",这坨脏活如果散落在循环各处,主循环就没法读了。单独封装后,主循环只需说"拿着这些消息问模型"。

没有它会怎样

网络抖动一次程序就崩;换一个模型供应商要改十处代码。它是最没"智能"却最不能省的一部。

对应概念:API client
步骤 5 / 6 · 总图判定块

⑤ 响应解析与调度:决定"下一步做什么"

干什么:拿到模型回复后做一次分类判定——回复是纯文本(任务完成,该停了)还是工具调用请求(该干活了)。若是后者,找到对应工具、执行、把结果写回历史。

为什么需要

模型的回复只有这两种形态需要区分处理,而"执行"永远发生在你的代码里——模型发出的只是一个结构化请求,真正动手的是你注册的本地函数。

没有它会怎样

把工具调用请求当普通文字打印出来,循环空转:模型以为你做了,你以为它说了,谁也没动文件。

对应字段:tool_calls
步骤 6 / 6 · 总图驱动块

⑥ 主循环:控制"何时停下来"

干什么:把前五步串成"想 → 做 → 记"的循环,反复执行,直到满足终止条件。

为什么需要

真实任务几乎不可能一轮完成——模型需要先看、再改、再确认。没有循环驱动,程序在第一轮后就结束了。

没有它会怎样

两个下场任选其一:一轮就退出(任务做不完),或者永不退出(一个死循环把预算烧光)。所以循环必须带守门条件:最大轮数、费用上限、超时——任何一条触发就强制停止。

对应概念:while 循环 + 守门条件

篇三 · 例:一个真实开源任务的五轮消息流

篇三 · 例(概念与代码之间的桥)
任务来自 SWE-bench Lite 数据集的真实条目 pytest-dev__pytest-5227(真实 GitHub issue + 真实修复,官方 patch 只改一行常量)。先看教学化预演(例 A,与篇四代码一一对应),再看本仓实验库的实测轨迹(例 B)——预演是骨架,真实是血肉。
例 A · 1 任务 + 5 轮预演(教学化构造)

任务实例:给 pytest 改进默认日志格式,循环转五圈

任务描述

任务背景(真实 issue 节译):pytest 的 --log-cli 实时日志默认只显示文件名(utils.py  114 DEBUG ...),排查问题时不知道是哪个模块,社区希望把模块名加进去。

交给 Agent 的任务指令:改进 pytest 的默认日志格式——把 src/_pytest/logging.py 中的常量 DEFAULT_LOG_FORMAT 改为 %(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s;完成后运行 python -c "from _pytest.logging import DEFAULT_LOG_FORMAT as f; print(f)" 验证新格式已生效。

环境背景:工作目录是 pytest 源码仓库(checkout 到修复前的 2051e30b),已做可编辑安装——Agent 改源码立即生效。官方修复正是这一行字符串常量的改写。

示例:五轮消息流([数字] = 六步骤编号)

把任务交给 Agent 后,小本子(③)上发生的事逐轮如下:

第 1 轮 · 找位置 ─────────────────────────
[②③] 岗位说明书 + 任务指令写入小本子(2 条消息)
[④]   把小本子 + 工具清单发给模型
[⑤]   模型回复:带工具调用 →
       bash("grep -n DEFAULT_LOG_FORMAT src/_pytest/logging.py")
[①]   执行:命中 src/_pytest/logging.py 第 18 行
[③]   grep 结果写回小本子(4 条)

第 2 轮 · 看上下文 ───────────────────────
[④⑤] 模型回复:带工具调用 → read_file("src/_pytest/logging.py")
[①]   读出源码
[③]   源码入列——模型"看得见"常量定义和引用它的测试(6 条)

第 3 轮 · 精准改 ─────────────────────────
[④⑤] 模型回复:带工具调用 → edit_file(
         path="src/_pytest/logging.py",
         old_string="%(filename)-25s %(lineno)4d ...(旧格式串全文)",
         new_string="%(levelname)-8s %(name)s:%(filename)s:%(lineno)d ...")
[①]   执行:old_string 在全文恰好匹配 1 处 → 替换
[③]   "已替换 1 处"写回小本子(8 条)

第 4 轮 · 验证 ───────────────────────────
[④⑤] 模型回复:带工具调用 →
       bash('python -c "from _pytest.logging import DEFAULT_LOG_FORMAT as f; print(f)"')
[①]   执行:打印出新格式串,exit 0
[③]   验证输出写回小本子(10 条)

第 5 轮 · 收工 ───────────────────────────
[④]   再次请求
[⑤]   模型回复:纯文本,无工具调用
       「已把 DEFAULT_LOG_FORMAT 改为含模块名的新格式,打印验证通过。」
[⑥]   主循环检测到纯文本 → 终止条件满足,输出总结,结束
三条观察(对照总图读)
  • 真正"改代码"只占第 3 轮里的一个动作——其余四轮都在找位置、看上下文、验证。循环的价值不在改那一行,而在环绕它的定位与验证(例 B 的真实轨迹会把这一点放大到极致)
  • 第 4 轮是玩具与真实 code agent 的分水岭:改完必须验证——没有这一轮,Agent 改错了也自称完成
  • 如果第 3 轮 edit_file 报错(比如 old_string 在全文出现多处),错误信息同样会写回小本子,下一轮模型会自己换更长的匹配串——错误也是观察,Agent 的自我修复就从这来
预演说明:按官方 issue 与修复逆向构造,与篇四代码一一对应 真实过程见下方例 B
例 B · 本仓实测轨迹(mimo agent · 任务已解决)

真实过程长什么样:58 次工具调用里,只有 1 次是修改

同一个任务,本仓实验平台真实跑过一次(mimo agent,2026-08-16,最终判定 resolved)。真实轨迹远比五轮预演"脏"——但正是这种"脏"揭示了 Agent 工作的真实结构。看真实数据:本任务在本仓实验平台有专属页面(任务详情 · 实验记录 · 完整轨迹逐事件浏览):http://116.62.126.90/platform/datasets/pytest-dev__pytest-5227

先对齐口径:同一份轨迹的四种数法
数字口径含义
205原始事件轨迹流文件总行数("录像带总帧数",含结构性标记)
60模型回合与大模型的 60 轮完整往返:58 轮动手 + 1 轮输出超长被截断 + 1 轮收工
58工具调用真实动手次数:bash 39 · read 9 · grep 5 · edit 2 · 网页搜索 3
27模型文本模型"说话"次数(思考、阶段说明、最终总结)

换算:205 = 120 条步骤哨兵标记 + 58 次工具调用 + 27 条文本。分析轨迹前必须先问口径——这就是为什么本仓要维护统一的轨迹元模型。

58 次工具调用的阶段折叠(真实命令节选)
阶段真实行为(节选)次数(约)
熟悉现场ls / cat 任务文件 / find 定位仓库与工作目录6
定位常量grep DEFAULT_LOG_FORMAT → 命中 logging.py1
读码与读测试read logging.py;grep + read 相关测试函数6
反复调试与验证反复跑 pytest 观察;用 python -c 做格式匹配实验;上网查文档43
最终修改edit 改写 DEFAULT_LOG_FORMAT1
收尾验证bash 跑测试确认后总结1
真实轨迹的两个教学点:
  • 改一行花 1 步,定位与验证花 57 步——"为什么 Agent 需要循环"的最好证据:循环的价值几乎全部在环绕修改的探索与验证上
  • 60 轮里有 1 轮因输出超长被截断而白跑(finish_reason=length)——我们的 mini_agent 没处理这种情况,真实产品必须处理(mini-swe-agent 专门有截断纠错提示)
在实验平台查看该任务的完整轨迹 → 来源:本仓实验库实测(pytest-dev__pytest-5227 · mimo · resolved) 轨迹格式说明:mimo 为 part 级流式方言;Claude Code 为消息级、mini-swe-agent 为步快照级——先问格式,再问口径

篇四 · 实:最简完整实现(4 个工具,约 100 行)

篇四 · 实(全部代码按 ①②④⑤⑥ 分段,对应篇二六卡)
工具四件套:read_file 看、edit_file 精准改、write_file 建新文件、bash 搜索与验证(逃生舱)——恰好映射工程师在终端做的一切。真实任务逼出了完整四件套:改一行常量只需 edit,但找到该改哪、确认改得对,离不开搜索与验证。
实 · 全部代码(含注释约 100 行)

mini_agent.py:把六个概念变成一个能跑的程序

读下面代码的方法:每段开头的圆圈编号对应篇二的六张卡——你可以随时跳回去对照概念。真正的循环逻辑(run_agent)仍然不到 20 行。

完整实现
"""mini_agent.py — 最小可用的 Agent Loop(教学版,4 工具)
安装:pip install openai
运行:export OPENAI_API_KEY=sk-...  &&  python mini_agent.py
兼容任意 OpenAI 兼容端点:把 OpenAI() 换成 OpenAI(base_url=..., api_key=...)
"""
import json
import os
import subprocess
from openai import OpenAI

# ── ① 工具清单:四个最基本的能力 ──────────────────────────
TOOLS = [
    {"type": "function", "function": {
        "name": "read_file",
        "description": "读取指定路径的文本文件内容",
        "parameters": {"type": "object",
            "properties": {"path": {"type": "string", "description": "文件路径"}},
            "required": ["path"]}}},
    {"type": "function", "function": {
        "name": "edit_file",
        "description": "精准替换:把文件中恰好出现一次的 old_string 替换为 new_string",
        "parameters": {"type": "object",
            "properties": {"path":        {"type": "string"},
                           "old_string":  {"type": "string", "description": "要被替换的原文"},
                           "new_string":  {"type": "string", "description": "替换后的新文"}},
            "required": ["path", "old_string", "new_string"]}}},
    {"type": "function", "function": {
        "name": "write_file",
        "description": "把内容写入指定路径的文本文件(覆盖写入,适合建新文件)",
        "parameters": {"type": "object",
            "properties": {"path":    {"type": "string"},
                           "content": {"type": "string"}},
            "required": ["path", "content"]}}},
    {"type": "function", "function": {
        "name": "bash",
        "description": "在 shell 中执行命令(搜索代码、跑测试、验证结果),60 秒超时",
        "parameters": {"type": "object",
            "properties": {"command": {"type": "string"}},
            "required": ["command"]}}},
]

# 工具名 → 真正干活的本地函数。模型只看到上面的"声明",执行永远发生在这里
def _read_file(path):
    return open(path, encoding="utf-8").read()

def _edit_file(path, old_string, new_string):
    text = open(path, encoding="utf-8").read()
    assert text.count(old_string) == 1, "old_string 必须在文件中恰好出现一次"
    open(path, "w", encoding="utf-8").write(text.replace(old_string, new_string))
    return "已替换 1 处"

def _write_file(path, content):
    open(path, "w", encoding="utf-8").write(content)
    return "已写入"

def _bash(command):
    out = subprocess.run(command, shell=True, capture_output=True,
                         text=True, timeout=60)
    output = (out.stdout + out.stderr)[:4000]     # 截断,防上下文爆炸
    return f"[exit {out.returncode}]\n{output}"

REGISTRY = {"read_file": _read_file, "edit_file": _edit_file,
            "write_file": _write_file, "bash": _bash}

# ── ② 系统提示词:岗位说明书 ────────────────────────────────
SYSTEM_PROMPT = (
    "你是一个代码修改助手,工作在当前目录的 pytest 源码仓库中。"
    "需要了解代码就先 read_file;修改一律用 edit_file 精准替换;"
    "改完必须用 bash 验证;验证通过后,用一段话总结修改并停止(不要再调用工具)。"
)

# ── ④ 模型调用器:封装通信 ──────────────────────────────────
client = OpenAI()          # 兼容端点:OpenAI(base_url="http://...", api_key="...")

def ask_llm(messages):
    """把 ③ 历史 + ① 工具清单发给模型,取回 message 对象"""
    return client.chat.completions.create(
        model=os.environ.get("MODEL_NAME", "gpt-4o-mini"),
        messages=messages,
        tools=TOOLS,
    ).choices[0].message

# ── ⑤ 响应解析与工具调度 ────────────────────────────────────
def execute_tool_calls(message, messages):
    """执行 message 里的工具调用,结果写回 ③ 历史"""
    messages.append(message)                      # assistant 消息(含 tool_calls)先入列
    for call in message.tool_calls:               # 一次多个调用就逐个回填
        try:
            result = REGISTRY[call.function.name](
                **json.loads(call.function.arguments))   # arguments 是 JSON 字符串!
        except Exception as e:
            result = f"Error: {e}"                # 错误也作为观察回传,模型下轮自纠
        messages.append({"role": "tool",
                         "tool_call_id": call.id,  # 关联"哪次调用的结果"
                         "content": str(result)})

# ── ⑥ 主循环:想 → 做 → 记,直到模型开口总结 ────────────────
def run_agent(task: str, max_turns: int = 15) -> str:
    messages = [{"role": "system", "content": SYSTEM_PROMPT},   # ② 岗位说明书
                {"role": "user",   "content": task}]            # 任务指令
    for turn in range(max_turns):                # 守门:最大轮数,防死循环
        response = ask_llm(messages)             # ④
        if not response.tool_calls:              # ⑤ 纯文本 → 任务完成
            return response.content
        execute_tool_calls(response, messages)   # ①⑤ 执行工具 + ③ 结果入列
        print(f"—— 第 {turn + 1} 轮结束,进入下一轮 ——")
    return "(达到最大轮数,任务未完成)"

TASK = (
    "改进 pytest 的默认日志格式:把 src/_pytest/logging.py 中的常量 "
    'DEFAULT_LOG_FORMAT 改为 "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s"。'
    '完成后运行 python -c "from _pytest.logging import DEFAULT_LOG_FORMAT as f; print(f)" 验证。'
)

if __name__ == "__main__":
    print(run_agent(TASK))
段落编号 ↔ 篇二六卡一一对应 ref: OpenAI Function Calling
实 · 跨平台环境准备 + 两级验证 + 三列对照

跑起来:先构造 Agent 工作的世界,再看它与真实产品的距离

先想清楚一件事:Agent 的工具箱在程序里,但 Agent 工作的世界(源码仓库 + Python 环境)需要你来构造——这正是 SWE-bench 官方要为每个任务预制环境规格的原因。本任务按官方规格锁定 Python 3.9(2019 年的 pytest 在新版 Python 上装不上——复现的第一敌人是环境漂移)。
路径 A · 离线实验包(课堂推荐:开箱即用)

课堂实操直接用老师预制的离线实验包:Agent、pytest 仓库(git bundle)、四平台 Python 3.9、全部依赖 wheel、判分材料、实测轨迹回放——全部装在一个 zip 里,不需要访问 GitHub、不需要安装 uv、不需要解析依赖,解压后一条命令离线拼装:

项目说明
下载http://116.62.126.90/swe5227-lab-kit-20260913.zip(143MB)
校验SHA256 95d67a264eeb8c232dff8dd51bc9a2b6e24d73e72590b7f348755b90af2dfc42
模型GLM-4.7-Flash(智谱,完全免费):open.bigmodel.cn 注册 → API Keys 页新建 → 只填 config 一行
# 0. Windows 同学仅做这一步平台操作:wsl --install -d Ubuntu(之后全在 Ubuntu 内)
# 1. 解压 + 离线拼装环境(1–2 分钟,结尾打印「环境就绪」)
unzip swe5227-lab-kit-20260913.zip && cd swe5227-lab-kit-20260913
./setup.sh
# 2. 唯一手工配置:把 open.bigmodel.cn 的 API Key 填进 agent/config.json 的 api_key
# 3. 跑 Agent + 两级判分
./run.sh
./verify.sh      # 5 项全 PASS = 按本仓实验平台同款 %Resolved 语义
# 跑砸了 ./reset.sh 一键复位重来;还没 Key?python3 replay/replay.py 先看实测轨迹回放

包内《README-学生版.md》与《FAQ.md》(14 条)覆盖全部细节。包里的 mini_agent.py 是本页篇四概念版的增强实现:同一个六部件骨架,多出 5 个来自真实轨迹(例 B)的健壮性细节——输出超长截断纠错、全工具输出截断、轨迹 JSONL 落盘、工作目录钉死、逐轮过程打印。

路径 B · 手动五步(理解「Agent 工作的世界」如何构造;Mac / Linux 原样,Windows 在 WSL 内执行)
# 0. Windows 学生先做且仅做这一步平台操作:wsl --install -d Ubuntu

# 1. 装 uv(单文件工具,自动管理多版本 Python;也可换 miniconda)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. 造 Python 3.9 隔离环境(不碰系统 Python)
uv python install 3.9
uv venv --python 3.9 && source .venv/bin/activate

# 3. 拿任务材料:checkout 到修复前的 commit,任务才成立
git clone https://github.com/pytest-dev/pytest && cd pytest
git checkout 2051e30b

# 4. 可编辑安装:Agent 改源码立即生效(PyPI 慢可加 -i 清华镜像)
pip install -e . && pip install openai

# 5. 冒烟自检——两条都对,环境就绪
pytest --version     # 显示 5.x.dev(本地源码版)
python -c "from _pytest.logging import DEFAULT_LOG_FORMAT as f; print(f)"
# 打印旧格式串(含 %(filename)-25s)——这就是 Agent 要改的那一行
运行与预期输出(对照篇三例 A)

设好 OPENAI_API_KEY 后运行 python mini_agent.py——终端逐轮打印,正是篇三预演那五轮(实际轮数可能略有出入,模型有时会多看一眼文件):

—— 第 1 轮结束,进入下一轮 ——
—— 第 2 轮结束,进入下一轮 ——
—— 第 3 轮结束,进入下一轮 ——
—— 第 4 轮结束,进入下一轮 ——
已把 DEFAULT_LOG_FORMAT 改为含模块名的新格式,打印验证通过。
复现成功的两级判定
  • 基础级:跑完后再打印一次常量,输出新格式串,且 git diff 与官方 patch 一致(就是那一行)
  • 进阶级(复刻 SWE-bench 判分语义):git apply 官方 test_patch 后跑 3 个 F2P 测试,全绿才算真解决——代码补丁 + 测试补丁,缺一不可,这正是 %Resolved 的本义(本仓评分链路 answer_evaluator 干的就是这件事)
三列对照:我们 vs Claude Code vs mini-swe-agent
维度本页 mini_agentClaude Codemini-swe-agent
工具协议function callingfunction calling + 权限门控不用协议,提示词里约定围栏
工具数量4(读 / 改 / 写 / bash)数十个 + MCP 扩展1(bash 包打天下)
历史管理线性追加自动压缩 + 子 Agent 隔离线性追加 + 输出截断
终止机制纯文本判定 + 轮数守门同类 + 人工确认分支魔法字符串 + 异常控制流
截断处理无(见例 B 教学点)内置专门的 finish_reason=length 纠错提示
代码量级约 100 行工业级产品核心约 100 行
安全提示与四道动手实验(按难度递进):
  • bash 是全能逃生舱也是双刃剑——本页假定可信环境;真实产品靠权限门控(对照表 Claude Code 列)把危险操作拦下来
  • 判分实验:手动 git apply 官方 test_patch,跑 3 个 F2P 测试——体验 SWE-bench 的 %Resolved 判分语义
  • 给它加第五个工具 list_dir(列目录),观察模型是否会在 grep 前先看目录结构——工具清单如何影响行为
  • 把终止机制改成 mini-swe-agent 式:约定模型改完就执行 bash("echo COMPLETE_TASK_AND_SUBMIT_FINAL_OUTPUT"),主循环看到即停——体验"协议上移到提示词"
  • 在每轮结束打印小本子的消息条数与累计字符数,跑完整个任务看它怎么膨胀——这就是为什么真实产品必须有上下文压缩