如何使用 Claude 构建你的第一个 AI Agent:从首次 API 调用到自主系统

@0xRafy
英语3天前 · 2026年7月17日
146K
103
15
7
271

TL;DR

一份关于使用 Claude 构建自主 AI Agent 的综合指南,重点介绍了包含 API 层、工具、循环、记忆和验证门控的稳健架构。

Anthropic 90% 的代码是由 Claude Agent 编写的。 不是工程师在聊天窗口里打字。而是由自主 Agent 运行循环、调用工具并在团队睡觉时交付代码。

关注我的 Substack 获取最新 AI 动态:

movez.substack.com

这就是完整的设置。一步一步来。从第一次 API 调用到能够处理任何任务的可用 Agent。

本文涵盖:

1 - 为什么大多数人构建的 "Agent" 并不是真正的 Agent

2 - 每个可用 Agent 需要的 5 个部分

3 - 如何使用 Claude 和代码构建每个部分

4 - 在 Agent 交付之前就搞砸它的错误

收藏本文。下面的每个代码块都可用。

01. 大多数 "AI Agent" 并非真正的 Agent

我构建和破坏过的 Agent 比我能数清的还多。看着它们整夜燃烧 token 却毫无产出。看着它们重写同一个文件 30 次。看着它们通过删除测试来通过自己的测试。

0xRafy - inline image

每次失败都教会我同一个道理:模型不是问题,模型周围的架构才是。这份指南是我学到的所有东西,压缩成我能给你的最短路径。

以下是大多数人在说 "AI Agent" 时构建的东西:

python
1while True:
2 user_input = input("> ")
3 response = call_claude(user_input)
4 print(response)

那是聊天机器人。它等着你,它按你说的做,它会忘记会话之间的所有事情。当你关闭标签页时,它就停止了。

Agent 是一个不需要你坐在面前就能朝着目标工作的系统。它发现需要做什么,制定计划,执行,检查结果,如果没有完成——就再试一次。你设定方向,Agent 完成工作。

"Claude Code 从零起步,在几个月内达到了 4 亿美元的收入。它始于一个黑客马拉松项目。至今仍然只使用公开 API。" -

Boris Cherny,Claude Code 负责人

同样的 API,你现在就能访问。同样的模型。区别在于模型周围的架构。

0xRafy - inline image

02. 真正 Agent 的 5 个部分

每个可用的 Agent——Claude Code、Devin、Codex 或你自己构建的任何东西——都由五个部分组成。缺少一个,它就坏了。

0xRafy - inline image

03. API 层

一切从这里开始。你调用 Claude,Claude 响应。但调用方式决定了你得到的是聊天机器人还是 Agent。

0xRafy - inline image

三件事很重要:系统提示词、结构化输出和温度。

系统提示词不是问候语。它是 Agent 的操作手册。所有规则、约束和行为都放在这里。没有它,Claude 会猜测你想要什么。有了它,Claude 会遵循你的规范。

python
1import anthropic
2
3client = anthropic.Anthropic()
4
5response = client.messages.create(
6 model="claude-sonnet-4-6",
7 max_tokens=4096,
8 system="""你是一个代码审查 Agent。
9
10规则:
11- 阅读整个 diff 后再评论
12- 只标记真正的 bug,而不是风格偏好
13- 如果没有任何问题,回复 "LGTM" 并停止
14- 永远不要建议你没有在脑子里测试过的更改
15- 输出格式:{file, line, issue, fix} 的 JSON 数组""",
16 messages=[{"role": "user", "content": diff_content}]
17)

结构化输出让你的 Agent 的响应可被机器读取。如果 Claude 返回自由文本,你的代码必须解析它。如果 Claude 返回 JSON,你的代码可以直接使用它。

python
1# 强制 JSON 输出,告诉 Claude 确切的结构
2system = """只返回有效的 JSON。不要 Markdown。不要解释。
3Schema:
4{
5 "status": "pass" | "fail",
6 "issues": [{"file": str, "line": int, "issue": str}],
7 "summary": str
8}"""

温度。 对于确定性 Agent 设为 0。对于创造性工作设为 0.3-0.5。默认值(1.0)会增加你几乎从不想在 Agent 中看到的随机性。

04. 工具

没有工具的模型可以推理但不能行动。它可以告诉你该编辑哪个文件,但不能编辑它。它可以描述一个查询,但不能运行它。

0xRafy - inline image

Claude 的工具使用功能让你定义模型可以调用的函数。你描述函数,Claude 决定何时调用,你执行它并返回结果,Claude 使用结果继续推理。

python
1tools = [{
2 "name": "run_sql",
3 "description": "对数据库执行只读 SQL 查询",
4 "input_schema": {
5 "type": "object",
6 "properties": {
7 "query": {
8 "type": "string",
9 "description": "要执行的 SQL SELECT 查询"
10 }
11 },
12 "required": ["query"]
13 }
14},
15{
16 "name": "write_file",
17 "description": "将内容写入磁盘上的文件",
18 "input_schema": {
19 "type": "object",
20 "properties": {
21 "path": {"type": "string"},
22 "content": {"type": "string"}
23 },
24 "required": ["path", "content"]
25 }
26}]

工具描述比你想象的重要。Claude 读取它来决定何时以及如何使用工具。模糊的描述导致错误的调用,精确的描述导致准确的调用。

从 3-5 个工具开始。读取文件、写入文件、运行命令、搜索,以及一个针对你用例的领域特定工具。这覆盖了 90% 的 Agent 任务。

0xRafy - inline image

05. 循环

这是将脚本变成 Agent 的部分。没有循环,你的代码调用一次 Claude 就停止。有了循环,你的代码调用 Claude,检查结果,再调用,直到工作完成。

0xRafy - inline image

三个组件:

  • 验证器。 检查输出是否良好的东西。测试套件、类型检查器、linter、带有严格标准的第二次 Claude 调用。没有这个,Agent 会不断跟自己达成一致。
  • 状态。 记录发生了什么。什么成功了,什么失败了,下一步该尝试什么。没有状态,Agent 每次循环都会犯同样的错误。
  • 停止条件。 目标达成,或者硬性限制说 "N 次尝试后停止并报告"。没有这个,循环会永远运行并耗尽你的账户。
python
1import json
2from pathlib import Path
3
4def run_agent(task: str, max_attempts: int = 5):
5 state = {"task": task, "attempts": [], "done": False}
6
7 for i in range(max_attempts):
8 # 从状态构建上下文
9 context = build_prompt(state)
10
11 # 使用工具调用 Claude
12 result = call_claude(context, tools)
13
14 # 执行任何工具调用
15 output = execute_tools(result)
16
17 # 验证结果
18 check = verify(output)
19
20 # 更新状态
21 state["attempts"].append({
22 "attempt": i + 1,
23 "action": result.summary,
24 "passed": check.passed,
25 "reason": check.reason
26 })
27
28 if check.passed:
29 state["done"] = True
30 break
31
32 # 为下一次运行保存状态
33 Path("state.json").write_text(json.dumps(state, indent=2))
34 return state

这就是完整的骨架。每个生产级 Agent 都是这个模式的变体。细节会变,形状不会。

06. 记忆

没有记忆,每次会话都会从零开始。Agent 重新发现你的项目结构,重新学习你的约定,重新犯昨天犯过的错误。

0xRafy - inline image

Claude Agent 使用三层记忆:

CLAUDE.md 是项目根目录下的一个 Markdown 文件。Claude Code 在每次会话开始时自动读取它。你的规则、技术栈、约定。写一次,永远读取。

markdown
1# CLAUDE.md
2
3## 项目
4任务管理 API。Python 3.12,FastAPI,PostgreSQL。
5
6## 规则
7- 所有响应:{data, error, meta} 模式
8- 每个新端点都需要测试
9- 提交信息:type(scope): description
10- 永远不要使用 print() 记录日志。使用 structlog。
11
12## 已知问题
13- Auth 中间件期望 x-auth-token,而不是 Authorization
14- 测试套件全量运行需要 45 秒。迭代时使用 --filter。

技能 捕捉整个工作流程。不仅仅是提示词——而是完整的形态:输入格式、步骤、输出格式、验证规则。第一次运行需要 20 分钟。回放只需 30 秒。

经验教训文件 是一个持续运行的错误日志。Agent 在每次会话后写入,下次会话时读取。错误会一直重复直到被写下来,然后它们就停止了。

markdown
1# learnings.md
2
3- 支付 API 期望幂等键在 header 中,而不是 body
4- PostgreSQL NOTIFY 需要在连接池中显式 LISTEN
5- 速率限制器按 key 计数,而不是按 IP。测试需要唯一的 key。

07. 验证门

门是最难构建的部分,也是最容易被跳过。大多数人跳过它。这就是为什么大多数 Agent 在生产环境中崩溃。

0xRafy - inline image

验证门是一种检查 Agent 工作成果的东西,而不让 Agent 给自己打分。编写代码的模型在给自己的作业打分时过于慷慨。你需要第二次检查。

三种有效的模式:

1. 自动化测试。 Agent 编写代码,测试套件运行。如果测试失败,Agent 获取错误输出并重试。这就是 Claude Code 内部的工作方式。

python
1def verify(output):
2 # 运行测试套件
3 result = subprocess.run(
4 ["pytest", "tests/", "-x", "--tb=short"],
5 capture_output=True, text=True
6 )
7 return {
8 "passed": result.returncode == 0,
9 "reason": result.stdout if result.returncode != 0 else "所有测试通过"
10 }

2. 类型检查器 / linter。 每次更改后运行 mypy、ruff 或 tsc --noEmit。无需编写任何测试就能捕获整个类别的错误。

3. 第二个模型作为审查者。 使用独立的 Claude 调用,带有只查找问题的严格系统提示词。编写者快速且便宜,审查者缓慢且严格。这种分离是质量的关键。

python
1# 审查者提示词 - 与构建者分离
2reviewer_system = """你是一个严格的代码审查者。
3你唯一的任务是发现问题。
4
5检查:
6- 代码是否符合规范?
7- 是否有未捕获的边界情况?
8- 所有测试是否真的测试了正确的东西?
9
10如果一切正确,回复:{"passed": true}
11如果有任何错误,回复:{"passed": false, "issues": [...]}
12
13不要提出改进建议。只标记真正的 bug。"""

编写者快速且便宜,审查者缓慢且严格。这种分离是质量的关键。

08. 整合在一起

这是一个完整的 Agent,它接受一个 GitHub issue URL,读取 issue,编写代码,运行测试,并打开一个 PR。五个部分协同工作。

python
1import anthropic, subprocess, json
2from pathlib import Path
3
4client = anthropic.Anthropic()
5CLAUDE_MD = Path("CLAUDE.md").read_text()
6LEARNINGS = Path("learnings.md").read_text()
7
8SYSTEM = f"""你是一个编码 Agent。
9阅读 issue,编写修复,运行测试。
10
11项目上下文:
12{CLAUDE_MD}
13
14已知问题:
15{LEARNINGS}
16
17规则:
18- 在更改任何内容之前阅读完整代码库
19- 为每次更改编写测试
20- 如果测试失败,修复代码,而不是测试
21- 当所有测试通过时停止"""
22
23TOOLS = [
24 read_file_tool,
25 write_file_tool,
26 run_command_tool,
27 search_codebase_tool,
28]
29
30def run(issue_text, max_attempts=5):
31 messages = [{"role": "user", "content": issue_text}]
32
33 for attempt in range(max_attempts):
34 # 调用 Claude
35 response = client.messages.create(
36 model="claude-sonnet-4-6",
37 max_tokens=8192,
38 system=SYSTEM,
39 tools=TOOLS,
40 messages=messages
41 )
42
43 # 执行工具调用
44 messages = handle_tool_use(response, messages)
45
46 # 验证:运行测试
47 test_result = subprocess.run(
48 ["pytest", "-x", "--tb=short"],
49 capture_output=True, text=True
50 )
51
52 if test_result.returncode == 0:
53 print(f"在 {attempt + 1} 次尝试后完成")
54 return True
55
56 # 将失败反馈到循环中
57 messages.append({
58 "role": "user",
59 "content": f"测试失败:\n{test_result.stdout}\n修复并重试。"
60 })
61
62 return False

这就是一个可用的 Agent。带有系统提示词和 CLAUDE.md 的 API 层。用于文件操作的工具。带有重试的循环。来自 learnings.md 的记忆。通过 pytest 的验证门。

不到 50 行。与 Claude Code 内部使用的架构相同。

**

09. 破坏每个 Agent 的 5 个错误

  1. 没有验证门。 Agent 给自己打分。它编写代码,说 "看起来不错",然后继续。输出看起来正确,但在生产环境中崩溃。
  2. 没有停止条件。 循环一直运行直到你的 API 账单达到 200 美元。没有硬性限制,Agent 会永远重试,重写同一个文件 40 次。始终设置 max_attempts。始终设置。
  3. 没有状态文件。 第 1 次尝试和第 50 次尝试犯同样的错误。Agent 不知道它已经尝试过什么,因为它连续三次提出同样的错误修复,没有记录失败。
  4. 工具太多。 你给 Claude 20 个工具,它选错了。一个有 5 个清晰工具的模型比一个有 20 个重叠工具的模型做出更好的选择。从小处着手。只有当 Agent 遇到瓶颈时才添加工具。
  5. 系统提示词模糊。 "做一个好的编码助手" 给你泛泛的输出。"所有响应必须是有效的 JSON,每次更改都需要测试,永远不要修改 /src 之外的文件" 给你一个行为可预测的 Agent。

结论:

可用的 Agent 不是更好的提示词。它是一个系统:API + 工具 + 循环 + 记忆 + 验证门。五个部分,缺少一个,它就坏了。

大多数人会阅读本文,收藏它,然后继续将 Claude 当作聊天机器人使用。他们会一次粘贴一个问题,手动将响应复制到代码库中。

那些构建了循环的人会在他们睡觉时交付工作。同样的模型,同样的 API,同样的价格,不同的架构。

上面的代码块都可用。复制它们,运行它们,针对你的用例进行修改。

本周构建一个 Agent。把它指向你每天做的任务。让它运行。

二次创作

使用 YouMind 创作爆款文章

收集素材、拆解爆点、生成视觉资产、撰写内容,并在一个 AI 工作空间里完成分发。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章