Claude 做 AI Agent 实战教程:从零搭建一个能自主执行任务的智能体(2026)

张开发
2026/4/11 21:20:03 15 分钟阅读

分享文章

Claude 做 AI Agent 实战教程:从零搭建一个能自主执行任务的智能体(2026)
上周我接了个私活甲方要求做一个能自己查资料、写报告、发邮件的自动化助手。说白了就是一个 AI Agent。我一开始想用 LangChain 那套搭到一半发现链路太长、调试痛苦后来干脆回归本质——直接用 Claude 的 Tool UseFunction Calling能力手搓了一个 Agent 框架。整个过程大概花了两天效果比我预期好不少。核心思路是利用 Claude Opus 4.6 / Sonnet 4.6 的 Tool Use 能力让模型在对话循环中自主决定调用哪些工具、按什么顺序执行直到任务完成。不需要复杂的框架一个 while 循环加几个工具函数就能跑起来。先说结论维度说明核心能力Claude 的 Tool UseFunction Calling适用模型Claude Opus 4.6 / Sonnet 4.6推荐 Sonnet性价比高框架依赖不需要 LangChain/CrewAI纯 SDK 就够代码量核心循环 100 行适用场景自动化报告、数据采集、多步骤任务编排Agent 到底是什么别被概念唬住热榜上天天说AI Agent这词被吹得有点虚。剥开来看Agent 就是一个循环决策系统接收用户指令模型决定要不要调用工具调用工具拿到结果把结果喂回模型让它决定下一步重复 2-4直到模型认为任务完成就这么简单。没有黑科技。是否用户输入任务Claude 分析任务需要调用工具选择工具 生成参数执行工具函数将结果返回 Claude输出最终结果环境准备pipinstallopenai httpx没错用的是 OpenAI SDK。Claude 的 API 兼容 OpenAI 协议用聚合接口的话一套代码就能跑不用装 anthropic 那个包当然你装也行。Python 版本我用的 3.113.10 都没问题。第一步定义工具ToolsAgent 的能力边界完全取决于你给它什么工具。这个项目需要三个搜索网页、读取文件、发送邮件。先定义工具的 schematools[{type:function,function:{name:search_web,description:搜索互联网获取最新信息返回搜索结果摘要,parameters:{type:object,properties:{query:{type:string,description:搜索关键词}},required:[query]}}},{type:function,function:{name:read_file,description:读取本地文件内容,parameters:{type:object,properties:{file_path:{type:string,description:文件路径}},required:[file_path]}}},{type:function,function:{name:send_email,description:发送邮件给指定收件人,parameters:{type:object,properties:{to:{type:string,description:收件人邮箱},subject:{type:string,description:邮件主题},body:{type:string,description:邮件正文支持 Markdown}},required:[to,subject,body]}}}]然后是工具的实际执行函数importjsonimporthttpximportsmtplibfromemail.mime.textimportMIMETextdefsearch_web(query:str)-str:用搜索 API 获取结果这里用 DuckDuckGo 的免费接口演示try:resphttpx.get(https://api.duckduckgo.com/,params{q:query,format:json,no_html:1},timeout10)dataresp.json()results[]fortopicindata.get(RelatedTopics,[])[:5]:ifTextintopic:results.append(topic[Text])return\n.join(results)ifresultselse未找到相关结果exceptExceptionase:returnf搜索出错:{str(e)}defread_file(file_path:str)-str:读取本地文件try:withopen(file_path,r,encodingutf-8)asf:contentf.read()# 截断太长的文件避免 token 爆炸iflen(content)8000:contentcontent[:8000]\n...[文件过长已截断]returncontentexceptFileNotFoundError:returnf文件不存在:{file_path}exceptExceptionase:returnf读取文件出错:{str(e)}defsend_email(to:str,subject:str,body:str)-str:发送邮件示例用 SMTP实际项目建议用 SendGrid/Resend# 这里只做演示实际使用请配置你的 SMTPprint(f[模拟发送邮件] 收件人:{to}, 主题:{subject})print(f正文预览:{body[:200]}...)returnf邮件已发送至{to}# 工具名到函数的映射tool_functions{search_web:search_web,read_file:read_file,send_email:send_email,}第二步搭建 Agent 核心循环这是整个 Agent 的灵魂部分。一个 while 循环不断让 Claude 决策直到它不再调用工具为止。fromopenaiimportOpenAI# ofox.ai 是一个 AI 模型聚合平台一个 API Key 可以调用 Claude、GPT-5、# Gemini 3 等 50 模型低延迟直连无需代理支持支付宝付款。clientOpenAI(api_keyyour-ofox-key,base_urlhttps://api.ofox.ai/v1)SYSTEM_PROMPT你是一个能自主执行任务的 AI Agent。你可以使用以下工具来完成用户的请求 - search_web: 搜索互联网获取信息 - read_file: 读取本地文件 - send_email: 发送邮件 工作原则 1. 先理解用户的完整需求拆解成步骤 2. 每一步选择最合适的工具执行 3. 根据工具返回的结果决定下一步行动 4. 所有步骤完成后给出最终总结 如果某个工具调用失败尝试换一种方式解决不要直接放弃。defrun_agent(user_task:str,max_turns:int10):运行 Agentmax_turns 防止无限循环messages[{role:system,content:SYSTEM_PROMPT},{role:user,content:user_task}]forturninrange(max_turns):print(f\n--- Agent 第{turn1}轮思考 ---)responseclient.chat.completions.create(modelclaude-sonnet-4-20250514,# Sonnet 4.6 性价比最高messagesmessages,toolstools,tool_choiceauto,# 让模型自己决定要不要用工具)msgresponse.choices[0].message messages.append(msg)# 把助手的回复加入历史# 如果模型没有调用工具说明任务完成了ifnotmsg.tool_calls:print(f\n✅ Agent 完成任务)print(f最终回复:\n{msg.content})returnmsg.content# 执行所有工具调用fortool_callinmsg.tool_calls:func_nametool_call.function.name func_argsjson.loads(tool_call.function.arguments)print(f 调用工具:{func_name}({func_args}))# 执行工具iffunc_nameintool_functions:resulttool_functions[func_name](**func_args)else:resultf未知工具:{func_name}print(f 工具返回:{result[:200]}...)# 把工具结果喂回对话messages.append({role:tool,tool_call_id:tool_call.id,content:str(result)})print(⚠️ 达到最大轮次限制)return任务未在限定轮次内完成第三步跑起来看效果if__name____main__:task 帮我完成以下任务 1. 搜索 2026年 Python Web框架 性能对比 的最新信息 2. 读取本地的 ./project_notes.txt 文件 3. 综合搜索结果和文件内容写一份技术选型报告 4. 把报告通过邮件发送给 teamexample.com resultrun_agent(task)实际跑起来的输出大概是这样的简化了一下--- Agent 第 1 轮思考 --- 调用工具: search_web({query: 2026年 Python Web框架 性能对比}) 工具返回: FastAPI continues to lead in async performance... --- Agent 第 2 轮思考 --- 调用工具: read_file({file_path: ./project_notes.txt}) 工具返回: 项目要求高并发、低延迟、团队熟悉 Flask... --- Agent 第 3 轮思考 --- 调用工具: send_email({to: teamexample.com, subject: 技术选型报告: Python Web框架, body: ## 技术选型报告\n\n### 背景\n...}) 工具返回: 邮件已发送至 teamexample.com --- Agent 第 4 轮思考 --- ✅ Agent 完成任务 最终回复: 任务已全部完成。我搜索了最新的框架对比信息结合你的项目笔记...四轮搞定。Claude 自己决定了执行顺序先搜索、再读文件、然后综合写报告发邮件。我没有硬编码任何流程。踩坑记录坑 1tool_call_id 不能丢一开始把工具结果返回给模型时忘了带tool_call_id直接报 400 错误。这个字段是必须的Claude 靠它来匹配哪个工具调用对应哪个结果。坑 2工具返回内容太长导致上下文爆炸有个文件 20 多万字符直接喂进去 token 就超限了。后来加了截断逻辑超过 8000 字符就截断。更好的做法是让 Agent 先读文件前 N 行判断需不需要继续读。坑 3Agent 陷入死循环有一次搜索工具返回未找到结果Claude 就反复换关键词搜索搜了 8 轮还在搜。所以max_turns这个限制很重要。后来在 system prompt 里加了一句如果连续两次搜索都没有结果就用已有信息作答问题就解决了。坑 4并行工具调用的处理Claude 有时候会在一轮里同时调用多个工具比如同时搜索两个关键词。msg.tool_calls是一个列表一定要遍历处理所有的不能只取第一个。我一开始就犯了这个错结果模型收到的工具结果对不上号回复就乱了。进阶加上重试和执行日志实际项目里我还做了两个增强importtimedefrun_agent_v2(user_task:str,max_turns:int10):增强版带重试和执行日志messages[{role:system,content:SYSTEM_PROMPT},{role:user,content:user_task}]execution_log[]# 记录每一步方便排查forturninrange(max_turns):try:responseclient.chat.completions.create(modelclaude-sonnet-4-20250514,messagesmessages,toolstools,tool_choiceauto,)exceptExceptionase:# API 调用失败等 2 秒重试一次print(f⚠️ API 调用失败:{e}2秒后重试...)time.sleep(2)try:responseclient.chat.completions.create(modelclaude-sonnet-4-20250514,messagesmessages,toolstools,tool_choiceauto,)exceptExceptionase2:execution_log.append({turn:turn,error:str(e2)})breakmsgresponse.choices[0].message messages.append(msg)ifnotmsg.tool_calls:execution_log.append({turn:turn,action:complete})return{result:msg.content,turns:turn1,log:execution_log}fortool_callinmsg.tool_calls:func_nametool_call.function.name func_argsjson.loads(tool_call.function.arguments)resulttool_functions.get(func_name,lambda**k:未知工具)(**func_args)execution_log.append({turn:turn,tool:func_name,args:func_args,result_preview:str(result)[:100]})messages.append({role:tool,tool_call_id:tool_call.id,content:str(result)})return{result:超出最大轮次,turns:max_turns,log:execution_log}小结用 Claude 做 Agent 没想象中那么复杂。核心就三件事定义工具的 JSON Schema告诉模型有哪些工具可用写一个 while 循环让模型自主决策调用工具把结果喂回去做好防护max_turns 防死循环、截断防 token 爆炸、重试防网络抖动不需要 LangChain不需要 CrewAI100 行代码就能跑一个能用的 Agent。如果要做多 Agent 协作、复杂的记忆系统、人工介入审批这些那确实需要更多工程化的东西。但先把单 Agent 跑通理解 Tool Use 的循环机制后面扩展就很自然了。模型选择上Sonnet 4.6 完全够用Opus 4.6 在复杂推理上更强但贵不少。我日常开发调试用 Sonnet上线跑重要任务才切 Opus。用聚合接口的话改个 model 参数就行不用折腾不同的 SDK。

更多文章