去年我在 AI Agent 上烧的钱,够买一辆中档电动车了。不是买显卡烧的,是 API 调用、上下文越滚越大、模型选错、重试没设上限,这些杂七杂八的费用一年下来四五千块。最难受的不是花多少,而是很多钱属于“不花就学不会”的学费,交完钱还没人给你发票。
最开始我以为自己早懂了 AI Agent。毕竟聊天机器人、提示词工程我都玩过,Agent 不就是“多轮对话加几个函数调用”?直到我第一个正经项目上线,模型开始胡言乱语、重复调用工具、把用户信息张冠李戴时,我才意识到 Agent 真正难的不是“能说话”,而是“能在没人盯着的情况下,自己把事办对”。
所以我打算用这篇把一年学到的、试错出来的、账单里踩出来的东西一次讲完。如果你正准备入坑,或者已经入坑但总感觉钱烧得不明不白,这篇应该能给你省下不少试错成本。
1. 先搞清 AI Agent 到底是什么:一张三百块的账单教会我的
1.1 我原以为 Agent 就是“能调用函数的聊天机器人”
刚接触时我犯了一个典型错误:把 Agent 当成 prompt 工程的高级形态。我在代码里写了一个 while 循环,把用户问题拼进提示词,让模型输出 JSON,再解析 JSON 执行工具,再拼回去让模型回答。跑起来确实像模像样,十次里能对七八次,我当时觉得自己已经掌握了 Agent。
但直到我把它接入真实业务,问题全暴露了。用户问“帮我查一下上周的销售数据,然后对比前一周,找出异常”,我的“循环版智能体”开始循环:一会儿查错表,一会儿把一个中间结果当成最终答案发出去,最离谱的一次连续调用工具十几遍,把同一条用户消息反复解析,一个下午烧掉三百多块的 token 费用。
我这才意识到,Agent 不是“聊天框加函数”,而是三个东西的组合:模型提供决策能力,工具提供执行能力,流程提供控制能力。真正的 Agent 会自己判断“这一步要不要查数据库”“上一次查的结果够不够回答”“查不到要不要换一种问法”。而我的 while 循环没有这个判断能力,它只是在机械地重复“猜下一步,猜错了再猜”。
这个认知转变很关键。如果你现在也在用 for 循环模拟 Agent,趁早停手,因为后面的坑更深。
1.2 一句话版本:Agent = 大模型 + 工具 + 记忆 + 策略
我给身边人解释 Agent 时会用一句话:它像一个“有手有脑但经验不足的实习生”。
- 大模型是这个实习生的脑子,负责理解任务、拆解问题、判断该干什么。
- 工具是它的手脚,比如查天气的接口、操作数据库的 SQL、调用飞书发消息的服务。
- 记忆是它的工作笔记,记录用户说过什么、之前查过什么、哪些方案试过但失败了。
- 策略是工作流程,告诉它什么时候该用脑子做决定,什么时候该用工具去执行。
所以 Agent 做“查销售数据对比异常”这件事,大致是这样的:
- 理解任务:用户要销售数据,还要对比前一周,还要找出异常项。
- 拆解计划:先查本期数据,再查前一期,再算差异,再判断异常。
- 调用第一个工具:执行 SQL 查数据库,拿到本期数据。
- 判断结果够不够:不够,还缺前一周数据,继续调工具。
- 调用第二个工具:执行另一条 SQL,拿到对比数据。
- 综合分析:算出增长率、异常阈值,把结论组织成自然语言回复。
第三和第五步就是“工具调用”,第一二六步是“模型推理”,第四步是“策略控制”。你把这六步都写死在代码里,那叫工作流;你让模型自己决定怎么走,那叫 Agent。两者没有绝对好坏,但理解这个区别,你才能做出正确的架构决策。
1.3 别再把 RAG 和 Agent 混为一谈
很多人一聊 AI 应用就说什么“RAG 就是 Agent”,这其实是两类东西。RAG 解决的是“模型不知道某些知识、我帮它查完再回答”的问题,核心是检索加生成。Agent 解决的是“任务需要多步执行、可能要操作外部系统”的问题,核心是决策加行动。
当然,它们经常组合使用:Agent 发现用户问的是公司内部某个文档,于是调用一个“检索工具”,这个工具内部跑的就是 RAG 逻辑。但理解成“RAG 是 Agent 的一种工具”比理解成“RAG 就是 Agent”要准确得多。我一开始混淆这两个概念,导致项目设计阶段就想错了方向,后面改架构的成本比想象的贵得多。
2. 选型路上的真金白银:FastAPI、LangChain、LangGraph、Django 到底怎么选
2.1 我的主力组合:FastAPI + LangChain + LangGraph
这一年我最后沉淀下来的主力组合是 FastAPI 做服务层、LangChain 做模型和工具封装、LangGraph 做流程控制。这样的选择不是我拍脑袋决定的,而是基于两个真实需求。
第一个需求是异步并发。Agent 有一个麻烦特性:单次任务时间很长,动辄十几秒甚至几十秒,因为里面要串行多次模型调用。如果我用 Django 这种同步模型,一个请求挂住一个 worker,并发稍微上来一点,机器就卡死。FastAPI 的 async 原语可以让我在等待模型响应时让出事件循环,用更少的资源扛住更多请求。这不是说 Django 不行,而是 FastAPI 在这个场景下更顺手。
第二个需求是可视化流程。Agent 很容易出现“跑着跑着飘了”的情况:模型自己导出的执行步骤变得不可控。LangGraph 提供了状态图和节点机制,我可以在关键节点之间加条件边,比如“如果检索不到,就重新改写关键词再试一次”,也可以在最外层设一个最大步数,防止 Agent 陷入死循环。这些约束对生产环境很重要。
这是我最先跑通的一个 FastAPI Agent 接口的骨架:
from fastapi import FastAPI from langchain_openai import ChatOpenAI from langgraph.graph import StateGraph, START, END from typing import TypedDict, Annotated import operator class AgentState(TypedDict): messages: Annotated[list, operator.add] tool_results: list def build_graph(): llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) def call_llm(state: AgentState): # 这里会调用大模型,让它决定下一步做什么 response = llm.invoke(state["messages"]) return {"messages": [response]} def run_tool(state: AgentState): # 这里执行工具调用,比如查数据库或调接口 # 实际项目里我会根据模型返回的 tool_calls 分发 tool_result = {"工具名": "查天气", "结果": "晴,26度"} return {"tool_results": [tool_result]} builder = StateGraph(AgentState) builder.add_node("llm", call_llm) builder.add_node("tool", run_tool) builder.add_edge(START, "llm") builder.add_conditional_edge("llm", lambda state: "tool" if need_tool_call(state) else END) builder.add_edge("tool", "llm") return builder.compile()这只是一个演示结构,实际跑起来还需要处理模型返回里的 tool_calls、增加超时控制、维护会话状态。但这个结构的好处是,你一眼就能看出 Agent 的决策点在哪、执行点在哪。这个可视化比什么都重要,因为 Agent 最容易失控的地方就是“决策边界不清楚”。
2.2 什么时候用 Django 也不违和
我之前接过一个业务,对方现有系统就是 Django 写的,要求 AI Agent 直接嵌入到后台管理里。这种情况下硬推 FastAPI 重构,团队成本和风险都很大。我最后选择在 Django 项目里加一个独立的 Agent 服务,用 Celery 跑异步任务,Django 后台发起请求后立即返回“任务已排队”,Agent 服务跑完再回调写库。
这个方案的取舍你自己衡量:多一个服务就多一个部署单元,但好处是老系统不用动,Agent 的并发模型也不会被 Django 的同步 worker 拖垮。如果你做的是管理后台里的低频助手,把 Agent 逻辑直接写在 Django management command 里也没毛病;如果你的 Agent 要给 C 端用户实时出结果,那就别让它和 Web 主进程挤在一起。
2.3 Rust 和 Spring AI 的真实使用场景
热词里有人问“基于 Rust 的 AI Agent”和“Spring AI Agent”。我的看法是:你选这些不是因为它们更高级,而是因为你的业务有硬性约束。
Rust 的优势是内存安全和极高并发。如果你的 Agent 要跑在边缘设备上、要嵌入嵌入式系统,或者你确实对单位成本内的吞吐量有极致要求,Rust 值得研究。但它生态比 Python 落后一截,模型调用、工具注册、记忆管理这些在 Python 里一行的活,在 Rust 里可能要把底层 API 手势自己捋一遍。我个人不推荐新手用它入门 Agent,除非你本来就是一个熟练的 Rust 工程师。
Spring AI 则是 Java 生态的补齐。如果公司已经有大量 Java 基础服务,你在 Spring 项目里加 Spring AI 模块,能省掉跨语言调度的麻烦。我见过不少企业团队因为“全栈都是 Java、不想引入 Python 运维”而选择 Spring AI,这个理由很现实,也完全说得通。
反过来讲,如果你是个人做项目、想快速验证想法,Python 生态一定是投入产出比最高的。我这一年大多数项目都在 Python 里完成,只有遇到极高并发或跨语言集成时才会考虑别的选项。
2.4 低代码平台也值得看一眼
热词里提到扣子,也就是 Coze,这类低代码平台我也用过一段时间。它的优点是调试方便、组件全,很适合快速验证业务流程。比如你要搭一个“读取用户输入、联网搜索、生成摘要”的 Agent,在扣子里拖几个节点就完事了,不用写代码。
但它也有明显边界。到了需要对每个模型调用做精细的成本控制、需要自定义复杂的错误恢复策略、需要深度集成到自己业务系统时,低代码平台就会让你觉得束手束脚。我的建议是把它当学习和原型工具,别把它当终局方案。终局方案一定是你自己能完全掌控代码和成本的。
3. 从零到一搭一个能实际干活的 Agent
3.1 先规划目录:一个最小但完整的项目长什么样
很多教程教 Agent 只给一段代码,不教工程结构。我自己第一次搭的时候就是一段代码梭哈,结果后期要加记忆、加工具、加日志,改得生不如死。后来我总结出一套比较顺手的结构:
agent_project/ ├── main.py # FastAPI 入口 ├── agent/ │ ├── __init__.py │ ├── graph.py # LangGraph 流程定义 │ ├── nodes.py # 各个节点的业务逻辑 │ ├── tools.py # 工具注册表 │ └── memory.py # 记忆存取 ├── core/ │ ├── config.py # 各类配置项 │ └── logging.py # 统一日志 ├── services/ │ ├── llm.py # 模型客户端封装 │ └── app_service.py # 业务接口封装 └── tests/ └── test_agent.py这个结构不算复杂,但把“Agent 逻辑”“工具逻辑”“业务逻辑”分开了。我现在回头想,这个分层让我节省了大量调试时间。因为 Agent 的调试本质上就是“定位是哪一层出了问题”:是模型理解错了,是工具调用参数错了,还是流程分支选错了。如果你所有代码堆在同一个文件里,排查起来会特别痛苦。
3.2 工具链设计:把所有外部能力统一注册
工具是 Agent 的“手”,而工具注册表是这些手的通讯录。我在项目里会用 Pydantic 定义每个工具的输入参数结构,让模型知道工具需要什么字段,同时做参数校验:
from pydantic import BaseModel, Field from langchain_core.tools import tool class QuerySalesParams(BaseModel): start_date: str = Field(description="起始日期,格式YYYY-MM-DD") end_date: str = Field(description="结束日期,格式YYYY-MM-DD") product_id: str | None = Field(default=None, description="产品ID,不传则查全部") @tool(args_schema=QuerySalesParams) def query_sales(start_date: str, end_date: str, product_id: str | None = None): """查询指定时间范围内的销售数据""" # 这里调用你封装的数据库访问层 return get_sales_from_db(start_date, end_date, product_id)这里有两个心得。第一,工具的 description 一定不要懒,因为模型是靠这些描述来判断“该不该调这个工具”和“这个工具有什么用”的。第二,参数 schema 越严越好,否则模型会自由发挥,传一些根本查不了的数据,然后 Agent 就会开始胡编。
工具不是越多越好。工具越多,模型每次推理时要读的工具文档就越多,token 消耗就越大,选择错误的概率也可能越高。我会在保证功能的前提下控制工具数量,把相关操作合并成一个工具,用参数区分。
3.3 Token 是怎么烧掉的:记账逻辑要搞明白
“Token 是什么”这个问题,我花了大概四百块才真正理解。Token 不是字数,而是模型处理文本的最小单位。英文单词大概 1 到 2 个 token,中文一个汉字通常 1 到 2 个 token,具体要看模型。关键是,大模型的计费是按 token 算的,而 Agent 的 token 消耗比你想象的多得多。
我做个简化的成本拆解:
| 任务环节 | 消耗方向 | 大概 token 量(示例) |
|---|---|---|
| 系统提示词 | 每次请求都要读一遍 | 500-1000 |
| 聊天历史 | 多轮累积,越滚越多 | 1000-5000 |
| 工具定义文档 | 每个工具要传给模型 | 500-2000 |
| 模型输出 | 模型生成的回答 | 300-1000 |
| 函数结果回传 | 拿到的数据喂回给模型 | 500-3000 |
这不是最要紧的,最要紧的是 Agent 常常要跑好几轮。比如一个任务拆成四步,每步都要把上面的上下文重新传一遍,token 量就是单轮的四倍。我早期就吃过一个大亏:对话内容越聊越长,上下文里塞满了旧的内容,每次调用成本呈线性增长,最后一把就跑了个十几块的单子。
控制成本的核心方法就两个:一是精简上下文,旧的不需要的信息要裁剪或摘要;二是限制轮数,LangGraph 里设 max_iterations,绝对不让 Agent 无限循环。我用这两个方法之后,平均单次任务成本下降了百分之六十以上。
3.4 把 Agent 服务接上 FastAPI
现在把上面的东西串成一个接口。我一般会做两个版本:同步的适合内部调试,流式的适合 C 端体验。流式更复杂也更重要,因为 Agent 内部多次调用模型,总时长可能很长,如果让用户干等,体验会很差。流式输出可以让用户看到“Agent 正在调用工具”“Agent 正在查数据库”这些中间状态。
这需要你区分两种输出:最终答案要卖给用户看,过程状态要卖给前端展示。两者可以都走 WebSocket 或 SSE。我之前用 SSE 比较多,实现简单,一个逐字输出的生成器就能搞定,后端把 Agent 的中间状态也作为 event 发出去,前端根据 event type 决定展示样式。
有个细节踩过坑:Agent 内部调用工具时,如果工具逻辑抛异常,异常信息会经过模型处理,模型可能把“数据库连接失败”这种技术细节润色成“数据暂时无法获取”,听起来没什么,但对排查问题就是灾难。所以我建议工具异常要单独捕获,不要裸露地抛给模型。比如你在 tool 内部 try 一下,把错误转成结构化信息,Agent 的日志里直接记录这个信息,这样才能定位。
4. 并发、部署和运维:让 Agent 真的“活”在线上
4.1 “AI Agent 怎么扛并发”的答案不是加服务器
有人搜“AI Agent 怎么扛并发”,我估计他的项目一上线就卡死了。我的答案是:先别急着加机器,而是要把并发想成三个层面的问题。
第一个层面是模型接口的并发限制。你调的模型服务一般有 QPS 或 TPM 限制,超了会被拒绝。解决办法是加限流和排队,而不是直接打过去。我在服务里用一个简单的队列,任务进来先排队,再按速率分发给模型。
第二个层面是你的应用服务的线程模型。Agent 是长任务,如果你用同步线程处理,并发一高内存就爆。用 FastAPI 的 async 或异步任务队列(比如 Celery / RQ),让长任务后台跑,接口层只负责“接收请求、返回任务 ID、提供查询结果接口”,这样最稳。
第三个层面是相同请求的合并和缓存。Agent 很多任务是重复的,比如多个人问“今天天气怎么样”。如果每次都要现算,就很浪费。我在外部加了一层缓存,同样的输入在短时间内直接返回缓存结果,大幅降低 token 消耗和并发压力。
初期别一上来就上多机负载均衡。单机把异步队列、限流、缓存这几个基本功做好,很多项目其实够用了。
4.2 部署时别漏掉这几件事
我部署 Agent 服务时犯过的最蠢的错误是,在环境变量里直接写模型 API Key,结果有一次调试时不小心打印了日志,Key 就出现在日志平台上了。现在我把所有敏感配置放进独立的配置中心或 Kubernetes Secret,代码里永远不出现明文。
部署参数上也有几个关键项:
- 超时设置。给模型调用和工具调用分别设超时,模型超时设 30 到 60 秒,工具超时看具体业务,但一定不能让 Agent 无限等待。
- 最大重试次数。模型接口偶发报错很正常,重试两三次没毛病,但超过三次就要降级,别让一个故障用户请求把你整个服务的请求都拖死。
- 内存限制。Python 项目加上 LangChain 这种重量级依赖,启动后内存经常能到几百 MB。在 Docker 里设置合理的 memory limit,避免内存泄漏拖垮整台机器。
- 结构化日志。给每个用户请求分配一个 trace_id,Agent 每走一个节点就打一条日志,后面查问题会非常方便。
这些看起来跟 AI 没什么关系,但决定了一个 Agent 能不能在线上长期稳定跑。我的体会是,越到后期你越会发现,Agent 项目的难点不在模型怎么调,而在工程基础做没做扎实。
4.3 想用 Agent 操控社交平台?先看清楚边界
热词里有“让小红书自动发消息”,这确实是个很常见的需求。但我得说点泼冷水的话:任何社交平台的自动发布脚本,都必须先看平台规则。很多平台明确禁止未经授权的自动化操作,轻则限流,重则封号。
如果你做的是自己账号的辅助运营,最稳妥的方案是使用平台官方提供的开放接口。如果没有开放接口,也不要强行写脚本模拟真人操作。因为这里涉及的不仅仅是技术问题,还有账号安全和平台合规问题。我可以理解你想省事的初衷,但这部分的红线一定要守住。
我的建议是用 Agent 做“内容生产”的部分,比如自动生成文案、自动整理素材,然后用人工点击发布,或通过官方渠道去发布。这既满足了效率需求,又不会把自己置于风险里。这类项目里 Agent 的核心价值本来就不是“代替你点击”,而是“帮你把产出质量提上去”。
5. 场景复盘:AI Agent 到底能干哪些真活
5.1 案例一:给内容小编配了个 Agent 助理
一个比较实际的项目是帮一个内容团队做一个“选题助手”。需求很简单:每天早上自动抓取行业资讯,用 Agent 做摘要,再生成五条选题建议,最后推到飞书群里。
我在这个项目里的结构是:定时任务触发(用 APScheduler 或 GitHub Actions 之类),然后调用 Agent,Agent 内部有两个工具,一个是抓取新闻的接口,一个是写飞书消息的服务。Agent 先把任务拆成“抓取、筛选、摘要、提议、发送”几步,最后把结果发送出去。
这个项目让我真正体会到 Agent 和普通脚本的区别。普通脚本的逻辑是写死的,比如“抓第一页十篇文章、取前三条生成摘要”,但如果当天第一页全是广告,脚本就废了。Agent 会根据实际内容判断质量,选中的文章可能来自第二页,摘要的侧重也不一样。它不是预测了所有情况,而是遇到情况时能自己处理。
这类项目的另一个好处是成本可控。一次运行只调几十次模型,单次成本几分钱,一年下来可能也就几百块。比我第一个项目那种让模型无限循环烧掉几百块的情况健康得多。
5.2 案例二:给 Django 老项目加 Agent 功能
我给一个 Django 项目做过一个工单分类助手。用户在后台提交工单,系统先用 Agent 做意图识别和紧急度判断,再自动分配给对应部门。这里的 Agent 不需要超长对话,只需要一次“理解 + 决策”,所以非常轻量。
集成方式是在 Django 里写一个 management command,消费外部任务队列。Django 收到工单后,把工单内容推给队列,Agent 服务处理完再把结果写回数据库,Django 后台直接展示。哪怕 Agent 服务挂了,工单仍然能保存,只是暂时没有自动分类,后续人工处理。
这种做法对老项目够友好,你不用动已有的表结构,也不用改 Django 的请求链路。Agent 作为外围服务,故障隔离性反而更好。我在这个项目里踩到的一个小坑是,不同部门名称之间容易混淆,比如“售后”和“销售支持”,Agent 一次分类经常分错。后来我在系统提示词里把部门职责表加了进去,把容易混的部门做了明确的边界说明,准确率才提上来。这个经验说明,Agent 有时候不是模型不够聪明,而是你没有把业务规则“翻译”给它。
5.3 案例三:个人 AI Agent 做期货交易?我给的建议是先冷静
这是热词里一个危险又诱人的方向:“个人使用 AI Agent 可以做期货交易吗”。技术上说,当然可以,抓行情、算指标、自动下单都能通过程序实现。但这里说的“可以做”和“应该做”是两回事。
我认识几个真的在尝试的人,他们最大的共同点是把模拟盘当实盘做、把回测成绩当真实收益预期。等你真金白银进去就会发现,延迟、滑点、极端行情这些因素,回测的时候根本反映不出来。Agent 在市场行情太好或太坏时的表现,都可能是灾难。
我个人的建议是三件事:第一,合规第一,跟期货相关的东西先确认自己有没有资质,别碰灰色地带;第二,如果只是想学习,那就用模拟盘,用 Agent 做分析没毛病,但别让资金冒险;第三,别迷信自动交易能“躺赚”,世界上没有这种好事。Agent 能帮你的是收集数据、生成报告,真正做决策的那个人还是你自己。
这个领域真正适合 AI Agent 的是“投研助手”:自动整理基本面数据、新闻舆情、技术指标,输出一份相对完整的分析摘要。辅助判断没问题,全自动执行交易这件事,请务必谨慎。
5.4 案例四:一个成本失控到拉回来止损的教训
我不止一次遇到这种局面:项目开发时精度很高,一上生产就翻车。我做过一个客服 Agent,开发时我用的是干净的数据集,模型答得挺好;上线后面对真实用户五花八门的问题,模型开始兜不住。有人问“我在你家买的耳机坏了,你们能修吗”,模型一会儿说“稍等,我帮您查一下”,一会儿又跳回去问“您需要维修还是退款”,用户被绕晕。
排查后发现两个问题:一是整个对话历史太长,模型把新问题误判成旧问题的延续;二是工具返回的数据格式没有统一,模型难以理解。后来我在每次工具返回前加了一个 state 整理节点,把工具结果统一成“字段 + 状态 + 摘要”的结构,并且给对话历史加了滑动窗口,只保留最近几轮完整信息加更早的摘要。
这次长篇会话治理让我的成本下降了一截,正确率也回升了。Agent 不是不能做长对话,而是你必须在“全部历史”和“token 成本”之间找到平衡。只保留最近几轮加前面信息的摘要,是目前我试过最划算的方案。
6. 一年总结出的学习路线和成本控制清单
6.1 我的学习路径,按踩坑顺序排给你
如果让我重来一遍,我会这么安排学习顺序,每个阶段都能省下一笔冤枉钱:
- 先用现成的大模型聊天,理解 prompt 能做什么、不能做什么,以及 token 计费规则。
- 学函数调用的基本用法。这是 Agent 的地基,你需要搞清楚模型如何定义工具、如何返回工具调用参数。
- 自己手写一个最简单的“模型 + 工具”循环,感受一下不受控的循环有多可怕。
- 然后才上 LangGraph 这类框架。有了前面的教训,你会明白框架里的状态管理和条件分支是拿来干什么的。
- 做一个小而完整的项目,比如“自动生成周报 Agent”,把它部署上线,监控成本。
- 最后再考虑并发、缓存、多智能体架构、跨语言实现这些进阶话题。
这个顺序的核心逻辑是“先理解原理,再引入工具”。很多人一上来就学 LangChain,结果只会调用上层 API,底层逻辑完全不理解,出了问题连排查方向都找不到。我自己就是这种学习方式的受害者,只不过你们的学费可以更少。
6.2 这一年下来,我最值钱的五条实操建议
- 在 LangGraph 里给所有节点加总步数限制,铁律,没有例外。这一步能防住 90% 的失控循环。
- 系统提示词里少讲空话,直接写明“你有哪些工具、什么时候用什么工具、不应该做什么”。模型是通过提示词理解边界的。
- 工具的输出要精简。数据库查询结果动辄几十行,你要先在工具内做聚合,只把必要的部分交给模型,否则 token 会直线上升。
- 每个 Agent 任务都要有一个结构化日志,记录:用户问题、模型反应、工具调用、工具结果、最终响应。这是后期排查的唯一线索。
- 先定预算再开发。我给自己每个 Agent 任务设了一个上限,比如单次调用超过一块钱就自动熔断。听起来很粗暴,但能防止深夜调试时不知不觉烧掉几百块。
6.3 测试 Agent 的正确姿势
普通代码的单元测试对 Agent 来说不太够用,因为模型输出不确定性太大。我的做法是维护一个“回归测试集”,里面有几十条各种类型的用户问题,每次修改提示词或工具逻辑后,就批量跑一遍。我不期待每次结果一模一样,但我会把“关键工具是否被正确调用”“结果里是否包含必需字段”这些结构化指标检查一下。
这个方法比肉眼调式高效得多。有一次我改了工具描述里的一个词,肉眼感觉没问题,结果回归测试发现模型从此不再调用那个工具。这要放在线上,用户就会得到一堆含糊其辞的回答。
我还发现,测试 Agent 时要用“最刁钻的用户问题”来测。真实的用户不会按你的提示词请求格式说话,他们什么句式都有。把这个“脏数据”喂给 Agent,你才能真正看出系统的稳定性。
写在最后:一件比技术更重要的事
花了一年、烧了几千块之后,我最大的收获不是学会了 LangGraph,也不是搞懂了并发,而是终于认清了一个事实:AI Agent 真正的成本,大头不在模型调用上,而在“问题定义”和“预期管理”上。模型本身很便宜,但你要让模型干的事对不对、值不值得干,这可能比任何技术参数都重要。
我后来接项目有个习惯,先问三句话:你想要 Agent 解决什么问题?这个问题用规则能不能解决?Agent 解决比规则解决好在哪?问完之后,一半的项目从“Agent”降级成了“普通脚本”,另一半项目则真的从脚本升级成了 Agent。这个筛选动作,帮我省下了最多的钱。
如果你手里也有一个蠢蠢欲动的 Agent 想法,别急着买显卡写代码,先花一个下午把问题想清楚,把流程画明白,再打开你的编辑器。我吃过的亏你未必也要吃一遍。