第1课:用20行Python造出你的第一个AI Agent

张开发
2026/4/14 18:07:18 15 分钟阅读

分享文章

第1课:用20行Python造出你的第一个AI Agent
系列导读这是**《12课拆解Claude Code架构》**系列的第 1 课。整个系列用 12 个递进式 Python 课程从最小 Agent 循环出发逐步叠加工具注册、计划系统、子 Agent、技能加载、上下文压缩、任务持久化、后台执行、多 Agent 团队、自治协作一直到 Worktree 隔离执行——覆盖一个生产级 Agent Harness 的全部核心机制。第 1 课的格言“One loop Bash is all you need”—— 一个工具 一个循环 一个 Agent。后面 11 个课程循环本身一行不改。所有新机制都在循环之外叠加。所以这一课是地基中的地基。大模型的致命缺陷Claude、GPT、Gemini这些大模型能写代码、能分析 bug、能设计架构。但它们有一个致命缺陷碰不到真实世界。不能读文件。不能跑测试。不能看报错。不能创建目录。不能执行任何命令。你问它 “帮我创建一个 hello.py”它只能回复一段代码文本让你自己去复制粘贴。你问它 “这个测试为什么失败”它只能猜因为它看不到实际的报错信息。没有循环的时候你自己就是那个循环——手动把模型的输出粘贴到终端把终端的结果粘贴回模型来来回回直到任务完成。Agent Loop 解决的就是这个问题让模型自己完成这个循环。核心架构一张图说清楚-------- ------- --------- | User | --- | LLM | --- | Tool | | prompt | | | | execute | -------- ------ -------- ^ | | tool_result | ---------------- (循环直到模型不再调用工具)整个 Agent 的运转逻辑就这一张图1. 用户给一个任务 → 发送给大模型 2. 大模型思考后决定 要不要调用工具 3. 如果要调用 → 执行工具把结果喂回给模型 → 回到第 2 步 4. 如果不调用 → 任务完成返回最终回复 退出条件只有一个模型自己决定不再调用工具。这就是所有 AI Agent 的骨架。Claude Code 是这样Cursor 是这样Windsurf 也是这样。不同的只是循环之外叠加的 Harness 机制——工具多少、有无计划系统、能不能多 Agent 协作——但核心循环永远是这一个。四步拆解从空白到 Agent第一步用户输入变成消息messages[{role:user,content:query}]Anthropic Messages API 用一个列表管理对话。用户的输入是第一条消息。后面所有的助手回复、工具调用结果都会追加到这个列表里。这个列表就是 Agent 的全部记忆。第二步把消息和工具定义一起发给 LLMresponseclient.messages.create(modelMODEL,systemSYSTEM,messagesmessages,toolsTOOLS,max_tokens8000,)关键参数是tools。你告诉模型 “你有一个叫 bash 的工具可以执行 shell 命令”模型就知道自己有了一双手。工具定义长这样TOOLS[{name:bash,description:Run a shell command.,input_schema:{type:object,properties:{command:{type:string}},required:[command],},}]一个名字一段描述一个参数定义。这就是给模型的 “工具说明书”。模型读懂之后就知道怎么调用这个工具了。第三步检查模型要不要调工具messages.append({role:assistant,content:response.content})ifresponse.stop_reason!tool_use:return# 模型决定不调工具了任务完成Anthropic API 返回的stop_reason有两种关键值tool_use→ 模型想调用工具end_turn→ 模型觉得说完了这一个判断就是整个循环的退出条件。模型自己决定什么时候停。第四步执行工具把结果喂回去results[]forblockinresponse.content:ifblock.typetool_use:outputrun_bash(block.input[command])results.append({type:tool_result,tool_use_id:block.id,content:output,})messages.append({role:user,content:results})模型说 “我要执行cat hello.py”你就在本地跑这个命令把输出结果以tool_result的格式追加到消息列表里。然后回到第二步让模型看到结果后决定下一步。组装完整的 Agent Loop把四步拼在一起就是整个 Agentdefagent_loop(messages:list):whileTrue:# 发给模型responseclient.messages.create(modelMODEL,systemSYSTEM,messagesmessages,toolsTOOLS,max_tokens8000,)# 记录助手回复messages.append({role:assistant,content:response.content})# 退出条件模型不再调工具ifresponse.stop_reason!tool_use:return# 执行工具收集结果results[]forblockinresponse.content:ifblock.typetool_use:outputrun_bash(block.input[command])results.append({type:tool_result,tool_use_id:block.id,content:output,})messages.append({role:user,content:results})不到 20 行。这就是一个能操作真实世界的 AI Agent。后面 11 个课程——工具注册、计划系统、子 Agent、上下文压缩、任务持久化、多 Agent 团队——全部都在这个循环之外叠加。循环本身从第 1 课到第 12 课一行不改。实际运行Agent 是怎么思考的让我们看一个真实的执行过程。你给 Agent 一个任务“创建一个 hello.py打印 Hello, World!”Agent 的思考和行动链路用户: 创建一个 hello.py打印 Hello, World! ↓ 模型思考: 我需要创建一个文件用 bash 工具 ↓ 工具调用: bash → echo print(Hello, World!) hello.py ↓ 工具结果: (空输出表示成功) ↓ 模型思考: 文件创建了我验证一下 ↓ 工具调用: bash → cat hello.py ↓ 工具结果: print(Hello, World!) ↓ 模型思考: 内容正确任务完成不需要再调工具了 ↓ stop_reason end_turn → 循环退出 ↓ 最终回复: 已创建 hello.py可以用 python hello.py 运行。注意两个关键点模型自己决定要验证——没有人告诉它要cat文件检查它自己觉得应该验证。这就是 Agent 的自主性。模型自己决定停止——确认文件正确后它判断任务完成不再调用工具。循环自然退出。三个架构决策为什么这样设计决策一为什么只用 Bash 一个工具Bash 能读文件、写文件、执行程序、管理目录、安装依赖、跑测试、查看日志……几乎能做一切。任何专门的工具——read_file、write_file、http_request——都只是 Bash 已有能力的子集。在第 1 课加更多工具不会解锁新能力只会增加模型需要理解的接口数量。最小可行 Agent一个工具一个循环。这也让一个核心洞见变得显而易见一个 LLM 一个 Shell就已经是一个通用 Agent。后面的课程s02会加更多工具但那是为了效率和安全不是为了能力。决策二为什么没有规划框架没有 Planner没有 Task Queue没有状态机。系统提示词告诉模型如何处理问题模型根据对话历史自己决定下一步做什么。这是有意为之的。在这个阶段加规划层属于过早抽象。模型的思维链本身就是计划。Agent Loop 只是不断问模型 “下一步做什么”直到模型说 “做完了”。到第 3 课TodoWrite我们才会引入显式的规划系统。但第 1 课证明了很多任务隐式的模型推理就够了。决策三为什么退出条件这么简单整个循环只看一个值stop_reason ! tool_use。没有超时。没有最大轮次。没有错误计数器。因为在教学场景下简单就是正确。生产环境会加安全阈值超过 N 轮强制停止、检测到危险命令拒绝执行但核心退出逻辑永远是同一个模型决定不再调用工具。这个退出机制的优雅之处在于——你永远不需要预定义任务有几步。简单任务一步完成复杂任务十步完成都是同一个循环。模型自己判断。安全最小但必要的防护即使是教学代码也不能裸奔。run_bash函数做了最基本的防护defrun_bash(command:str)-str:dangerous[rm -rf /,sudo,shutdown,reboot, /dev/]ifany(dincommandfordindangerous):returnError: Dangerous command blockedtry:rsubprocess.run(command,shellTrue,cwdos.getcwd(),capture_outputTrue,textTrue,timeout120)out(r.stdoutr.stderr).strip()returnout[:50000]ifoutelse(no output)exceptsubprocess.TimeoutExpired:returnError: Timeout (120s)三层防护黑名单过滤拦截rm -rf /、sudo等危险命令超时控制120 秒没跑完强制终止输出截断最多返回 50000 字符防止上下文爆炸生产环境需要更完善的沙箱Docker 容器、文件系统权限隔离但原则是一样的让 Agent 能动手但不能乱来。五分钟跑起来# 克隆仓库gitclone https://github.com/shareAI-lab/learn-claude-codecdlearn-claude-code# 安装依赖pipinstall-rrequirements.txt# 配置 API Keycp.env.example .env# 编辑 .env填入你的 ANTHROPIC_API_KEY 和 MODEL_ID# 启动第一课python agents/s01_agent_loop.py启动后你会看到一个交互式终端提示符s01 可以直接输入任务。以下是真实的运行记录任务 1创建文件s01 Create a file called hello.py that prints Hello, World! $ cat hello.py EOF print(Hello, World!) EOF (no output) $ python3 hello.py Hello, World! hello.py has been created and works correctly — it prints Hello, World!.注意 Agent 不仅创建了文件还主动运行了一次验证——没有人让它这么做。任务 2探索环境s01 List all Python files in this directory $ find . -name *.py -type f ./hello.py ./tests/test_agents_smoke.py ./agents/s01_agent_loop.py ... A total of 21 Python files were found.任务 3获取系统信息s01 What is the current git branch? $ git branch --show-current main The current git branch is main.一轮调用就结束——Agent 判断信息已经足够不需要再调工具。任务 4多步操作s01 Create a directory called test_output and write 3 files in it $ mkdir -p test_output (no output) $ cat test_output/output1.txt EOF This is the first test output file. EOF cat test_output/output2.json EOF {name: test_output, file_number: 2, status: success} EOF cat test_output/output3.csv EOF id,name,value 1,alpha,100 2,beta,200 EOF (no output) $ ls -l test_output/ output1.txt output2.json output3.csv Done! Created the test_output directory with 3 files.Agent 自主决定了文件格式txt、json、csv自主验证了创建结果。你只给了目标没给步骤。每一个任务Agent 都会自主决定执行什么命令、要不要验证结果、什么时候停下来。你不需要告诉它步骤只需要告诉它目标。总结你刚造了什么组件之前之后Agent 循环无while Truestop_reason工具无bash单一工具消息管理无累积式消息列表退出机制无stop_reason ! tool_use代码量0~120 行含安全防护和交互界面核心代码不到 20 行但它已经是一个功能完整的 AI Agent能感知环境通过 bash 读取文件、查看状态能行动通过 bash 执行命令、创建文件能自主决策模型决定下一步、何时停止有记忆累积式消息列表保存完整上下文这四个能力——感知、行动、决策、记忆——就是 Agent 的定义。下一课预告第 1 课只有一个工具bash。虽然 bash 什么都能做但让模型每次都拼 shell 命令效率不高也不够安全。第 2 课Tool Use—— 从 1 个工具扩展到多个。核心模式是一个 dispatch map工具名映射到处理函数。新增工具只需注册循环不用碰。# 预告s02 的 dispatch mapTOOL_HANDLERS{bash:run_bash,read:read_file,write:write_file,edit:edit_file,}outputTOOL_HANDLERS[tool_name](**tool_input)加一个工具只加一个 handler。循环一行不改。这是《12课拆解Claude Code架构从零掌握Agent Harness工程》系列的第 1 课。关注Claw开发者不错过后续更新。完整代码和交互式学习平台github.com/shareAI-lab/learn-claude-code如果这篇文章对你有帮助欢迎转发给你的技术团队。系列目录第1课用20行Python造出你的第一个AI Agent本文第2课给Agent加工具 —— dispatch map模式详解第3课TodoWrite —— 让Agent先想后做规划系统第4课Subagent —— 拆解大任务上下文隔离第5课按需加载领域知识——Skill机制第6课无限对话——上下文压缩三层策略第7课任务持久化——文件级DAG任务图第8课后台执行——异步任务与通知队列第9课Agent Teams——多Agent协作团队与邮箱系统第10课团队协议——状态机驱动的协商第11课自治Agent——自组织任务认领第12课终极隔离——Worktree并行执行本文原始链接第1课用20行Python造出你的第一个AI Agent 更多 AI Agent 开发实战教程访问HuanCode

更多文章