§03 让 Agent 自己读懂并修复一个 bug

去年带实习生做入门 demo,我想找个最直观的例子。效果要肉眼可见:行就行、崩就崩。文档里那个"让 Agent 自己修 bug"正好。我直接拿来用。

03.1 文档里的经典例子

文档给了一个特别好的入门例子。我直接拿来用。

你写一个 utils.py,故意埋两个会崩的 bug。然后让 Agent 自己读、自己修。你全程只看着。

这个方法好在哪?效果肉眼可见。修之前会崩,修之后不崩。一眼就知道 Agent 真干活了。

03.2 先埋两个 bug

# utils.py —— 故意写残的两个函数
def calculate_average(numbers):
    total = 0
    for num in numbers:
        total += num
    return total / len(numbers)   # bug:除数是 0 会崩

def get_user_name(user):
    return user["name"].upper()    # bug:user 是 None 会崩

这里两个 bug 都很典型:calculate_average([]) 除零,get_user_name(None) 类型错。

03.3 让 Agent 自己修

# fixer.py —— 会自己修 bug 的 Agent
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    async for message in query(
        # 这行是关键:告诉它要找会崩的 bug 并修复
        prompt="检查 utils.py 里会导致崩溃的 bug,把问题修掉。",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Edit", "Glob"],  # 给它读和改的权限
            permission_mode="acceptEdits",           # 自动批准文件修改
        ),
    ):
        # 打印它每个动作,看清它在干嘛
        if hasattr(message, "content"):
            for block in message.content:
                if hasattr(block, "text"):
                    print(block.text)                # 它的思考过程
                elif hasattr(block, "name"):
                    print(f"调用工具:{block.name}")   # 它调了哪个工具

asyncio.run(main())

预期结果:Agent 读了 utils.py,发现两个边界情况,自己加上错误处理。你没改过一行代码。

03.4 四种权限模式怎么选

permission_mode 决定 Agent 动手前要不要问你。

模式 行为 标叔的结论
acceptEdits 自动批准改文件 本地开发首选
bypassPermissions 全部跳过审批 只用在隔离环境
plan 先问再做 怕它乱改时用
default 靠回调决定 做自定义审批流

核心建议:本地练手用 acceptEdits

它会自动批准文件编辑,Agent 不用等你点确认。等你做需要人工把关的产品时,再换成 defaultcanUseTool 回调。

跑通一个会修 bug 的 Agent 了。但它是怎么"自己想、自己干"的?下一章拆开看。

深入 SDK 的发动机。每章一个核心概念,读完你能看懂 Agent 内部在发生什么。