大模型应用开发动手做 AI Agent:从调 API 到跑通任务的完整路径
简介《大模型应用开发 动手做AI Agent》是黄佳撰写的一本面向Agent技术学习者与开发者的实战电子书适合研究人员、开发人员、产品经理、企业负责人及高校相关专业师生阅读帮助读者从零理解Agent的设计思路并掌握落地方法。全书围绕GPT-4、OpenAI Assistants API、LangChain、LlamaIndex、MetaGPT等前沿技术展开通过7个可动手实现的Agent案例覆盖办公自动化、函数调用、ReAct推理、智能调度、检索增强生成RAG以及多Agent协作等典型场景并展望Agent的未来趋势。资源包为1个PDF文件大小约25.35MB内容完整、结构清晰便于按章节系统学习或按项目查阅。目前已有994人学习读者可借此建立Agent开发框架认知理解工具调用与数据交互方式并对照案例完成从概念到实践的完整闭环。1. 大模型应用开发动手做 AI Agent从调 API 到能跑通任务的完整路径很多人第一次接触 AI Agent是从一份流传很广的 PDF 讲义开始的标题里写着「大模型应用开发 动手做 AI Agent」。但真正动手时才发现卡住自己的不是概念而是「模型能聊天却不会自己查资料、调工具、记住上下文」这道坎。Agent 要解决的核心问题就一句话让大模型从「一问一答」变成「自己规划步骤、调用外部能力、根据结果决定下一步」。它适合已经会调大模型 API、想做出能自动完成多步任务的人比如自动查数据写报告、自动读文档回答问题、自动操作一组工具完成流程。这篇笔记不讲空泛概念直接按「最小可跑通 → 工具调用 → 记忆与规划 → 避坑 → 进阶验证」的顺序把每一步的命令、参数和翻车点写清楚新手能照着复现熟手能对照边界。2. 先把最小 Agent 跑起来模型、循环、工具三件套2.1 为什么 Agent 不等于「加个提示词」普通大模型调用是单轮的输入一段话输出一段话结束。Agent 的本质是一个循环模型输出一个动作程序执行这个动作把结果再喂回模型直到模型认为任务完成。这个循环里必须有三样东西——一个能理解指令的模型、一套可被调用的工具、一个控制循环次数的调度器。少了调度器模型可能无限循环少了工具模型只能空想少了结果回填模型不知道上一步做对没有。常见做法是用一个 while 循环包住「模型输出 → 解析动作 → 执行 → 拼接观察结果」这四步并设置最大轮数比如 8 到 12 轮超过就强制停止并返回当前结果。2.2 用 Python 写一个 40 行可运行的最小 Agent下面这段代码不依赖任何 Agent 框架只用最基础的模型调用接口目的是让你看清循环结构。实际运行时把call_llm替换成你手头可用的模型调用函数即可。import json # 模拟模型调用真实场景替换为你的大模型 API 调用 def call_llm(messages): # 这里返回一个固定格式的字符串真实模型会输出类似内容 return {action: search, args: {query: 今日天气}} # 工具注册表名称 - 函数 TOOLS { search: lambda query: f模拟搜索结果{query} 晴26 度, calc: lambda expr: str(eval(expr)), # 仅演示生产环境禁用 eval } def run_agent(user_input, max_turns8): messages [{role: user, content: user_input}] for turn in range(max_turns): raw call_llm(messages) # 1. 模型输出动作 try: action json.loads(raw) # 2. 解析 JSON except json.JSONDecodeError: return 模型输出不是合法 JSON终止 name action.get(action) args action.get(args, {}) if name finish: # 3. 模型主动结束 return args.get(answer, ) if name not in TOOLS: # 4. 未知工具处理 messages.append({role: user, content: f未知工具 {name}}) continue observation TOOLS[name](**args) # 5. 执行工具 messages.append({role: assistant, content: raw}) messages.append({role: user, content: f观察结果{observation}}) return 达到最大轮数未完成 print(run_agent(帮我查一下今天天气))逻辑说明messages是对话历史每轮把模型的原始输出和工具返回结果都追加进去模型下一轮就能看到自己上一步做了什么。参数说明max_turns控制循环上限太小任务做不完太大浪费调用次数TOOLS字典是工具注册表新增工具只需加一个键值对。注意eval只用于演示真实项目里必须换成安全的表达式解析否则就是给自己埋雷。2.3 工具描述怎么写模型才愿意调模型不会读你的函数签名它只看你给的工具描述文本。描述里必须写清三件事这个工具做什么、什么时候用、参数是什么格式。比如「search当需要查询实时信息或外部事实时使用参数 query 为字符串」。如果描述写成「搜索工具」模型经常在该调的时候不调或者把参数名写错。我一般会把工具描述单独放在一个列表里和函数实现分开维护改描述不用动代码逻辑。另一个血泪经验是参数尽量用扁平结构不要嵌套对象模型对嵌套 JSON 的生成准确率明显下降。3. 工具调用与结果回填让 Agent 真正能干活3.1 工具调用的三种常见实现方式第一种是纯文本 JSON 解析就是上一章的做法优点是简单可控缺点是模型偶尔输出多余文字导致解析失败。第二种是用模型厂商提供的函数调用能力模型直接返回结构化的调用请求解析稳定但绑定特定接口。第三种是用 Agent 框架内置的工具装饰器把函数自动转成工具描述省事但黑盒较多。选型建议如果只是做原型验证第一种足够如果要上生产且模型支持函数调用优先第二种框架适合快速堆功能但排错时要能看懂它底层在干什么否则出问题只能干瞪眼。3.2 结果回填的格式与截断策略工具返回的结果不能原样塞回给模型尤其是搜索结果、日志、网页正文这类长文本。常见做法是截断到固定长度比如 2000 字符并在开头保留关键信息。下面是一个回填前的处理函数def format_observation(text, max_len2000): if len(text) max_len: return text # 保留前 1500 和后 400 字符中间用省略标记 head text[:1500] tail text[-400:] return f{head}\n...[中间省略 {len(text)-1900} 字符]...\n{tail}参数说明max_len根据模型上下文窗口调整一般不超过窗口的十分之一给历史对话留空间。逻辑说明保留尾部是因为很多结果的关键结论在最后比如「综上答案是 X」。如果只截前段模型可能看不到结论。注意截断标记要写清楚否则模型会以为内容真的断了反复要求重新查询。3.3 多工具串联时的顺序控制当任务需要先查再算再写模型有时会跳步。解决办法是在系统提示里明确「每次只能输出一个动作等观察结果后再决定下一步」。另外可以在调度器里加一个简单校验如果模型连续两轮调用同一个工具且参数相同就强制插入一条提示「你已调用过该工具请基于已有结果继续或结束」。这个校验能挡掉大部分死循环。参数上连续重复阈值设为 2 比较合适设为 1 会误伤正常的重试。4. 记忆与规划Agent 从「能跑」到「好用」的分水岭4.1 短期记忆用对话历史长期记忆用外部存储短期记忆就是当前任务的 messages 列表任务结束就丢弃。长期记忆需要把关键信息写到外部比如向量库或简单的键值存储。常见做法是每轮结束后把「用户目标 已完成步骤 关键结论」压缩成一段摘要存进长期记忆下一轮开始时先检索相关摘要拼进系统提示。这样即使对话很长模型也不会忘记最初的目标。参数上摘要长度控制在 200 字以内检索返回条数 3 到 5 条太多会挤占上下文。4.2 规划提示的写法与任务拆解示例规划能力靠提示词引导。一个可用的规划提示模板是「你是一个任务规划器。把用户目标拆成不超过 5 个步骤每步一个动作。输出 JSON 数组每项包含 step 和 action。」下面是一个拆解示例的输入输出对照用户目标拆解步骤查某城市天气并判断是否适合跑步1. search 查天气2. 根据温度湿度判断3. finish 输出建议读一份文档并回答三个问题1. read 读文档2. 分别提取三个答案3. finish 汇总注意规划器不要和 executor 混在一个提示里分开两个角色规划质量会明显提升。我一般先让规划器输出步骤人工确认一遍再交给执行器原型阶段这一步能省掉很多无效调用。4.3 用最大轮数和超时做双重保险再好的规划也会遇到工具报错或模型跑偏。除了max_turns还要加一个总超时比如 60 秒。实现方式是在循环里记录开始时间每轮检查time.time() - start timeout就退出。参数建议简单任务 30 秒复杂任务 120 秒。超时后返回已完成的部分结果并附一句「任务未全部完成以下是已获取信息」比直接报错对用户友好。5. 避坑与排查Agent 开发中最容易翻车的 5 个点5.1 模型输出不是合法 JSON现象解析动作时抛异常Agent 直接中断。原因模型在 JSON 前后加了「好的我来帮你」这类文字。解决解析前先用正则提取第一个{到最后一个}之间的内容再尝试解析同时在提示里明确「只输出 JSON不要任何其他文字」。5.2 工具参数名对不上现象模型调用工具时参数名写成search_query而函数签名是query导致执行报错。原因工具描述里参数名和实际函数不一致。解决把工具描述和函数签名放在同一个地方生成改一处自动同步或者在调度器里做参数名映射容错常见变体。5.3 无限循环调用同一个工具现象模型反复查同一个关键词轮数耗尽。原因观察结果没有让模型获得新信息或者提示里没告诉它「已有结果可用」。解决在回填结果时加一句「这是该工具的最新结果请基于此继续」同时加重复调用检测连续两次相同就强制提示结束或换工具。5.4 上下文被长结果撑爆现象调用几轮后模型开始胡言乱语或报超长错误。原因工具返回的原始文本太长把对话历史挤满。解决所有工具输出统一走format_observation截断对话历史超过一定轮数时把早期轮次压缩成摘要只保留最近 3 轮原文。5.5 工具执行报错后 Agent 卡死现象某个工具抛异常整个循环崩溃。原因没有对工具执行做异常捕获。解决用 try/except 包住工具调用把异常信息作为观察结果回填比如「工具执行失败除零错误」模型看到后通常会换一种方式重试或结束。注意异常信息不要暴露敏感路径生产环境要过滤。6. 进阶验证怎么判断你的 Agent 是真的能用6.1 用固定任务集做回归测试不要只靠手动试几个问题就认为 Agent 没问题。准备一个 20 到 30 条的任务集每条包含用户输入和预期结果类型比如「查天气」预期返回包含温度「算表达式」预期返回数字。每次改提示或换模型后跑一遍任务集统计成功率和平均轮数。成功率低于 80% 就说明还有系统性问题不要急着加功能。参数上任务集要覆盖单工具、多工具串联、工具报错、超长输入四类场景。6.2 观察轮数和工具调用分布一个健康的 Agent简单任务 2 到 3 轮完成复杂任务 5 到 8 轮。如果平均轮数超过 10说明规划或提示有问题。工具调用分布也能看出毛病如果某个工具被调用次数远高于其他可能是描述太宽泛模型什么都往里塞。我一般会在日志里记录每轮的 action 和耗时跑完任务集后看一眼分布比逐条读日志快得多。6.3 边界测试空输入、超长输入、工具全挂空输入时 Agent 应该直接返回提示而不是崩溃超长输入要能截断或拒绝把所有工具都设成抛异常看 Agent 是否能优雅结束而不是死循环。这三个边界测试花不了十分钟但能挡掉上线后的大部分尴尬。下面是一个简单的边界测试脚本框架def test_edge_cases(): cases [ (, 应提示输入为空), (x * 10000, 应截断或拒绝), ] for user_input, desc in cases: result run_agent(user_input, max_turns3) print(f用例{desc}结果{result[:50]}) # 工具全挂测试 global TOOLS original TOOLS.copy() TOOLS {k: (lambda **kw: (_ for _ in ()).throw(Exception(模拟故障))) for k in original} print(run_agent(查天气, max_turns3)) TOOLS original逻辑说明前两个用例验证输入处理第三个用例把所有工具替换成抛异常验证容错。参数说明max_turns3是为了快速失败正式测试可以用默认值。注意测试完要恢复工具表否则影响后续调用。6.4 一个我常犯的错过早引入框架刚开始做 Agent 时我总想直接上重型框架结果排错时连请求发到哪里都看不清。后来改成先用 40 行原生循环跑通确认逻辑没问题再按需引入框架的某个模块。这个习惯帮我省了很多「后悔药」——框架能解决的是工程化问题不是逻辑问题逻辑没理清之前框架只会让黑匣子更黑。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

小程序接口签名绕过与纵深防御:从签名机制到验证落地

小程序接口签名绕过与纵深防御:从签名机制到验证落地

1. 从一次接口排查说起:为什么小程序签名如此重要这几年小程序生态渗透到了各个业务场景,从电商、生活服务到企业办公,几乎每个领域都离不开它。但我实际在做安全测试和接口联调时发现,很多开发团队把签名校验当成一个“加上就安心…

2026/10/13 7:15:59 阅读更多 →
CO-RE实战:一次编译到处运行,解决eBPF内核适配难题

CO-RE实战:一次编译到处运行,解决eBPF内核适配难题

1. 为什么要折腾 CO-RE:从一次内核升级说起如果你在服务器上跑过基于 BPF 的追踪工具,大概率遇到过一个既无奈又经典的报错:libbpf: failed to find valid kernel BTF或者更早以前,你辛辛苦苦在开发机上编译好的 BPF 程序&#xf…

2026/10/13 7:14:58 阅读更多 →
RNN文本生成实战:从LSTM复读到温度采样与避坑指南

RNN文本生成实战:从LSTM复读到温度采样与避坑指南

简介:一个RNN文本生成实战项目包,面向自然语言处理初学者与深度学习实践者,完整演示了基于循环神经网络的语言模型构建与自动文本生成流程。模型使用网上收集的周杰伦歌词作为训练语料,涵盖数据清洗、词汇表创建、序列填充、分词编…

2026/10/13 7:14:58 阅读更多 →

最新新闻

SQL UNIQUE约束详解:原理、数据库差异与防重复设计实践

SQL UNIQUE约束详解:原理、数据库差异与防重复设计实践

1. UNIQUE约束到底是什么,为什么你需要它做数据库设计这些年,我见过太多因为“忘记加唯一约束”而崩溃的业务系统。最典型的场景:用户注册接口被脚本刷了一遍,username重复了;订单表里同一笔订单被回调程序insert了两次…

2026/10/13 7:55:19 阅读更多 →
Agent-Skills:智能体原子化能力的设计与工程实践

Agent-Skills:智能体原子化能力的设计与工程实践

1. “agent-skills”不是新词,而是智能体能力体系的命名共识 最近在多个技术社区、开源项目文档和内部架构评审会上,“agent-skills”这个组合词出现频率陡增——它既不指代某个具体开源库,也不是某家公司的私有协议,而是一类设计…

2026/10/13 7:55:19 阅读更多 →
Flink DataStream与Table API转换实战:Schema推导、时间属性与常见避坑指南

Flink DataStream与Table API转换实战:Schema推导、时间属性与常见避坑指南

做实时数据处理这几年,Flink的DataStream和Table API来回切换是我用得最频繁的操作之一。刚接触那会儿,总觉得这两套API是两套独立的体系,流上处理业务逻辑用DataStream,做统计查询用Table,中间隔着一道说不清的墙。后…

2026/10/13 7:55:19 阅读更多 →
LiteLLM:大模型API统一网关与智能路由实战指南

LiteLLM:大模型API统一网关与智能路由实战指南

1. LiteLLM不是另一个大模型,而是一把“万能适配器”最近在几个技术群和开源社区里,频繁看到有人发问:“LiteLLM到底是个啥?是又一个新模型吗?”“它和Ollama、LM Studio有什么区别?”——这种误解非常典型…

2026/10/13 7:55:19 阅读更多 →
LiteLLM:大模型API统一接入与智能路由实战指南

LiteLLM:大模型API统一接入与智能路由实战指南

1. 为什么“litellm”突然在开发者圈里被高频提及——它不是新模型,而是新范式最近两周,在多个技术社区、内部分享会和开源项目讨论区里,“litellm”这个词出现的频率明显升高。它不像Llama、Qwen或Claude那样代表一个具体的大语言模型&#…

2026/10/13 7:55:19 阅读更多 →
开源代码审查实战:流程设计、工具配置与团队落地方法

开源代码审查实战:流程设计、工具配置与团队落地方法

代码审查这事儿,我过去几年一直想好好聊一聊。初看上去,open-code-review 这个项目标题没什么特别,好像就是把自己团队做代码评审的过程、工具和规范整理出来,开源给社区用。但如果真这么理解,那就有点浪费了。代码审查…

2026/10/13 7:54:17 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →