搜索引擎里关于 AI Agent 的教程很多,但大多数要么只讲概念,贴几张架构图就结束了;要么直接甩一堆框架代码,新手根本不知道为什么要这样写。真正从“是什么、怎么运作、如何动手”一路讲到工程落地、测试、面试的内容,确实比较少见。
本文就按照一条完整的学习链路来整理 AI Agent 智能体开发:先理解 Agent 和大模型的关系,再拆解 Agent 的运行逻辑,然后从零手写一个可调用工具的 Agent,最后补充工程化测试、常见坑点、进阶方向以及面试重点。整篇文章不依赖特定的付费课程,适合零基础入门,也适合有后端或 AI 基础、想系统掌握 Agent 开发的读者。
1. AI Agent 到底是什么:从 Chatbot 到智能体
1.1 通俗理解:Agent 不是“加强版问答机器人”
很多人第一次接触 AI Agent 时,容易把它理解成“更聪明的 ChatGPT”。这个理解对了一半。
普通的大模型对话应用,比如我们在网页里打开一个聊天窗口,它的工作方式是:用户输入问题 → 模型生成回答 → 结束。即使模型再强,它也只能“说”,不能“做”。
AI Agent 则不同。它最大的特点是:大模型不只是回答问题,而是作为一个“大脑”去规划任务、调用工具、观察结果、调整策略,最终把事情做完。
举个例子:
- 普通 Chatbot:用户问“今天北京适合穿什么衣服?”,模型回答:“建议穿薄外套,因为北京今天 18 到 24 度,多云。”
- AI Agent:同样的问题,Agent 会先调用天气查询工具获取实时温度,再调用空气质量工具获取 PM2.5 数据,结合当前季节给出穿衣建议,如果数据异常,它还能主动说明“数据来自哪个接口,更新时间是什么”。
所以可以这样记:大模型是“大脑”,Agent 是“大脑 + 手 + 眼睛 + 工具包”。
1.2 一个 Agent 的核心组成部分
从工程实现的角度看,一个完整的 AI Agent 通常包含以下几个部分:
| 组成部分 | 作用 | 例子 |
|---|---|---|
| 大模型(LLM) | 负责理解、规划、决策、生成 | GPT 系列、通义千问、DeepSeek、Llama |
| 提示词(Prompt) | 定义 Agent 的角色、规则、输出格式 | “你是客服助手,只能使用可用工具,不要编造信息” |
| 工具(Tool) | Agent 能调用的外部能力 | 天气查询、数据库查询、计算器、搜索、发邮件 |
| 记忆(Memory) | 保存对话历史和长期知识 | 短期对话上下文、向量数据库中的长期记忆 |
| 执行循环 | 让 Agent 不断思考-调用-观察-再思考 | ReAct 循环、Plan-and-Execute |
在真实项目中,这几个部分会被封装成 Agent 框架,比如 LangChain、LlamaIndex、AutoGen、CrewAI,或者自研的一套调度逻辑。但不管你用不用框架,理解这几个组件之间的配合关系才是关键。
1.3 AI Agent 的常见应用场景
当前 AI Agent 的落地场景已经非常广泛,常见的有:
- 智能客服 Agent:自动理解用户问题,查询订单库、退换货规则,必要时转人工。
- 数据分析 Agent:根据用户一句话,自动写 SQL、查询数据库、生成图表。
- 代码开发 Agent:读取仓库代码,定位 Bug,修改文件,运行测试。
- 个人知识库 Agent:连接 Obsidian、Notion、本地文档,基于 RAG 回答私人知识问题。
- 自动化办公 Agent:读取邮件、提取附件、写周报、安排日程。
- 多 Agent 协作系统:一个 Agent 负责拆解任务,其他 Agent 分别负责搜索、写作、校对。
可以看出,Agent 的价值不在于“聊天”,而在于把大模型接入到真实的工作流里。这也是为什么现在的开发者越来越重视 Agent 开发能力。
2. AI Agent 的运行逻辑:LLM 是如何“行动”的
2.1 核心循环:感知、规划、行动、观察
要理解 Agent,必须理解它的运行循环。目前大多数 Agent 本质上是下面这个循环:
用户请求 ↓ 理解意图(LLM) ↓ 制定计划:需要调用哪些工具 ↓ 调用工具(行动) ↓ 获取结果(观察) ↓ 判断任务是否完成 ↓ 如果未完成,继续规划下一步 ↓ 如果完成,生成最终回答这个过程在学术上通常被称为ReAct(Reason + Act)模式,也就是“推理 + 行动”交替进行。LLM 不是一次性给出答案,而是在每一轮里先“想”(Reason),再“做”(Act),然后根据“做”的结果继续“想”。
2.2 ReAct 模式
ReAct 模式的典型输出格式如下:
Thought: 我需要知道今天的天气才能回答用户。 Action: get_weather Action Input: {"city": "北京"} Observation: 北京 18-24 度,多云 Thought: 我已经获取到天气信息,可以生成最终回答。 Final Answer: 北京今天 18-24 度,多云,建议穿薄外套。这里每一行都有明确的含义:
Thought:模型展示自己的推理过程。Action:模型决定调用哪个工具。Action Input:给工具传入的参数。Observation:工具返回的实际结果。Final Answer:任务完成,给用户的最终回答。
在代码层面,Agent 框架要做的就是:
- 把上述格式写进系统提示词。
- 调用 LLM 拿到文本输出。
- 解析输出中的 Action 和 Action Input。
- 执行对应工具。
- 把 Observation 拼接回上下文。
- 再次调用 LLM。
这个循环会一直重复,直到模型输出Final Answer,或者达到最大轮数。
2.3 工具(Tool)是什么
工具是 Agent 与外部世界交互的接口。从代码角度看,工具就是一个函数,通常包含三部分信息:
- 工具名称:比如
get_weather。 - 工具描述:说明这个工具能做什么,LLM 会根据描述决定是否调用。
- 执行函数:真正运行的逻辑,比如调用天气 API、执行 SQL、运行代码。
工具描述非常重要。LLM 本身不会“猜”你的工具能做什么,它完全依赖描述来决策。描述写得模糊,Agent 就会频繁调用错误工具,甚至拒绝调用工具。
def get_weather(city: str) -> str: """ 查询指定城市的实时天气。 参数: city: 城市名称,例如 "北京"、"上海" 返回: 包含温度和天气状况的文本。 """ # 调用天气 API 的逻辑 return f"{city} 的天气:多云,18-24 度"在成熟框架里,工具还可以声明参数类型、是否必填、枚举值等,这些信息会被转换为 JSON Schema,帮助 LLM 更准确地生成调用参数。
3. 开发环境准备与工程结构
3.1 环境要求
在动手写代码之前,先把环境准备好。本文的实战部分以 Python 为例,版本需要根据你的项目实际情况调整,常见的稳定环境如下:
- 操作系统:Windows 10/11、macOS、Linux 都可以。
- Python 版本:建议 3.10 或更高。
- 大模型接口:使用 OpenAI 兼容接口,只要你有一个可用的 API Key 即可。
- IDE:推荐 VS Code 或 PyCharm。
如果你还没有大模型 API Key,也可以使用本地模型(比如 Ollama 部署的模型),但要注意本地模型的指令遵循能力可能不如云端模型,ReAct 格式解析的成功率会低一些。
3.2 安装依赖
创建一个项目目录,并在项目目录下创建虚拟环境:
mkdir ai-agent-tutorial cd ai-agent-tutorial python -m venv venv # Windows venv\Scripts\activate # macOS / Linux source venv/bin/activate然后安装 OpenAI SDK。这里以openai库为例,建议安装 1.x 版本:
pip install openai如果你计划使用 LangChain,可以一并安装:
pip install langchain langchain-openai但本文实战部分先不引入 LangChain,而是自己实现一个最小 ReAct 循环。这样你能更清楚地看到 Agent 的本质,而不是被框架封装的黑盒搞晕。
3.3 项目结构
实战部分我们用一个单文件即可跑通,后续工程化可以考虑拆分为:
ai-agent-tutorial/ ├── main.py # 核心 ReAct Agent 实现 ├── requirements.txt # 项目依赖 ├── tests/ │ └── test_agent.py # Agent 测试 └── README.md4. 手把手实战:从零实现一个可调用工具的 Agent
下面我们直接写一个最小可运行的 AI Agent。这个 Agent 会具备以下能力:
- 调用计算器工具计算数学表达式。
- 调用当前时间工具获取当前时间。
- 根据用户问题自动决定调用哪个工具。
完整代码如下,可以直接保存为main.py。这是一个核心实现示例,需要根据你的实际模型接口进行微调。
""" 文件路径:main.py 一个最小可运行的 ReAct Agent 示例 """ import os import re from datetime import datetime from openai import OpenAI # 使用环境变量读取 API Key client = OpenAI( api_key=os.environ.get("OPENAI_API_KEY", "your-api-key"), base_url=os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1") ) # ---------- 第 1 步:定义工具 ---------- def calculator(expression: str) -> str: """ 计算数学表达式。 参数: expression: 数学表达式字符串,例如 "1 + 2 * 3" 返回: 计算结果字符串 """ try: # 注意:eval 仅用于学习演示,生产环境必须使用安全解析方式 result = eval(expression, {"__builtins__": {}}, {}) return str(result) except Exception as e: return f"计算错误: {e}" def get_current_time(unused: str = "") -> str: """ 获取当前日期和时间。 返回: 当前日期时间字符串 """ return datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 工具注册表:Agent 只能调用这个字典里的工具 TOOLS = { "calculator": { "description": "用于计算数学表达式,输入示例:'1 + 2 * 3'", "execute": calculator, }, "get_current_time": { "description": "用于获取当前日期和时间,不需要输入参数", "execute": get_current_time, }, } # ---------- 第 2 步:构建系统提示词 ---------- SYSTEM_PROMPT = """你是一个智能助手,可以通过调用工具来完成任务。 可用工具: {} 请严格按照以下格式输出,不要输出额外内容: Thought: 你的思考过程 Action: 工具名称 Action Input: 工具输入 当你已经获得足够信息时,输出: Final Answer: 最终答案 注意: 1. 必须从可用工具中选择,不要编造工具名。 2. 如果没有必要的工具调用,可以直接输出 Final Answer。 """.format( "\n".join([f"- {name}: {info['description']}" for name, info in TOOLS.items()]) ) # ---------- 第 3 步:实现 ReAct 循环 ---------- def run_agent(user_input: str, max_steps: int = 5) -> str: messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_input}, ] for step in range(max_steps): print(f"\n===== Step {step + 1} =====") response = client.chat.completions.create( model=os.environ.get("OPENAI_MODEL", "gpt-4o-mini"), messages=messages, temperature=0, ) assistant_output = response.choices[0].message.content print("Agent 输出:") print(assistant_output) # 如果模型给出最终答案,直接返回 if "Final Answer:" in assistant_output: return assistant_output.split("Final Answer:")[-1].strip() # 解析 Action 和 Action Input action_match = re.search(r"Action: (\w+)", assistant_output) input_match = re.search(r"Action Input: (.+)", assistant_output) if not action_match or not input_match: messages.append({"role": "assistant", "content": assistant_output}) messages.append({ "role": "user", "content": "你的输出格式不正确,请严格按照 Thought / Action / Action Input 的格式输出。" }) continue tool_name = action_match.group(1) tool_input = input_match.group(1).strip() if tool_name not in TOOLS: observation = f"未知工具: {tool_name}" else: try: observation = TOOLS[tool_name]["execute"](tool_input) except Exception as e: observation = f"工具执行错误: {e}" print(f"工具观察结果:{observation}") # 把工具结果追加到对话中 messages.append({"role": "assistant", "content": assistant_output}) messages.append({"role": "user", "content": f"Observation: {observation}"}) return "达到最大步数,未能得到最终答案。" # ---------- 第 4 步:测试运行 ---------- if __name__ == "__main__": result = run_agent("帮我计算 (12 + 8) * 3 等于多少,并告诉我现在的北京时间") print("\n最终结果:", result)4.1 逐段解释关键代码
上面的代码虽然不长,但包含了 Agent 开发的几乎所有核心要素。我们逐个拆开看。
工具注册表的设计
TOOLS = { "calculator": { "description": "用于计算数学表达式,输入示例:'1 + 2 * 3'", "execute": calculator, }, ... }这里把工具描述和工具函数放在同一个字典中,目的是让程序在生成系统提示词时,可以直接遍历TOOLS生成工具列表。同时,执行时也可以通过工具名直接获取到对应的函数。
这种设计在实际项目中非常常见,后续如果需要增加工具,只需要往TOOLS里添加一项即可。
系统提示词的动态生成
SYSTEM_PROMPT = """...{}""".format( "\n".join([f"- {name}: {info['description']}" for name, info in TOOLS.items()]) )为什么要把工具列表动态拼进提示词?
因为 LLM 是不知道你的代码里有哪些工具的。你必须把工具名称和描述告诉它,它才知道“什么时候该调哪个工具”。工具越多,描述就要越精确,否则 LLM 很容易选错工具。
ReAct 循环的解析逻辑
action_match = re.search(r"Action: (\w+)", assistant_output) input_match = re.search(r"Action Input: (.+)", assistant_output)模型输出的是一段纯文本,程序需要用正则表达式从文本中提取出工具名和工具输入。这是 ReAct 模式在工程上最关键、也最容易出问题的地方。
要强调的是:这里用正则解析只是一个基础方案。在实际项目中,更好的做法是使用大模型的原生函数调用(Function Calling)能力,模型直接返回结构化的 JSON,而不是一段需要正则解析的文本。这个我们在后面框架部分会提到。
4.2 运行与验证
在命令行中运行:
export OPENAI_API_KEY="你的API Key" python main.py如果使用国内 OpenAI 兼容接口,可以同时设置:
export OPENAI_BASE_URL="你的兼容接口地址" export OPENAI_MODEL="你的模型名称" python main.py预期交互过程大致如下(具体文本会因模型不同而不同):
===== Step 1 ===== Agent 输出: Thought: 用户需要计算一个数学表达式,还需要当前时间,我需要先调用计算器工具。 Action: calculator Action Input: (12 + 8) * 3 工具观察结果:60 ===== Step 2 ===== Agent 输出: Thought: 计算完成,接下来需要获取当前时间。 Action: get_current_time Action Input: 工具观察结果:2026-01-12 15:30:22 ===== Step 3 ===== Agent 输出: Thought: 我已经获得了计算结果和当前时间,可以回答用户了。 Final Answer: (12 + 8) * 3 的结果是 60。现在的北京时间是 2026-01-12 15:30:22。 最终结果: (12 + 8) * 3 的结果是 60。现在的北京时间是 2026-01-12 15:30:22。到这里,你就拥有了一个真正“会干活”的 AI Agent。它不是你问一句、它答一句,而是会自己拆解任务、调用工具、观察结果、再生成最终答案。
4.3 这个 Agent 的局限性
这个最小实现当然有很多不完善的地方,理解它的局限性能帮你更好地理解后续工程化的必要性。
- 依赖正则解析输出,如果模型不按格式输出,循环容易卡住。
- 没有结构化函数调用,工具参数复杂时容易出错。
- 没有记忆管理,超过上下文长度后无法处理。
- 没有并发和异步能力,工具只能串行执行。
- 使用
eval计算表达式,存在安全风险,生产环境绝对不能用。
接下来,我们看看用成熟框架怎么解决这些问题。
5. 基于成熟框架开发:LangChain 等框架的接入思路
5.1 为什么使用框架
手写一个 ReAct 循环能帮你理解原理,但真实项目里,你需要处理很多工程细节:
- 工具参数的 JSON Schema 自动生成。
- 函数调用结果的格式化。
- 对话记忆的滑动窗口。
- 多工具并行的调度。
- 日志追踪和 Token 统计。
- 错误重试机制。
这些功能如果全部自己实现,工作量不小。成熟框架的价值就在这里。
5.2 LangChain 的接入思路
LangChain 是目前生态最丰富的 Agent 开发框架之一。它的接口变化比较快,下面只是一个思路示例,具体 API 需要根据你安装的版本来调整。
在 LangChain 中,定义一个 Agent 通常包含三部分:
# 文件路径:langchain_agent_demo.py # 这是一个接线层面的示例,实际运行时需要根据 LangChain 版本调整 API from langchain.agents import AgentExecutor, create_react_agent from langchain_openai import ChatOpenAI from langchain.tools import tool @tool def calculator(expression: str) -> str: """计算数学表达式,例如 '1 + 2 * 3'""" return str(eval(expression)) @tool def get_current_time(unused: str = "") -> str: """获取当前日期和时间""" from datetime import datetime return datetime.now().strftime("%Y-%m-%d %H:%M:%S") def create_agent(): llm = ChatOpenAI( model="gpt-4o-mini", temperature=0, ) tools = [calculator, get_current_time] prompt = """你是一个智能助手,可以调用工具解决问题。 请尽量使用工具获得真实信息,不要编造答案。 用户问题:{input} 你的思考过程:{agent_scratchpad}""" agent = create_react_agent(llm, tools, prompt) executor = AgentExecutor(agent=agent, tools=tools, verbose=True) return executor if __name__ == "__main__": executor = create_agent() result = executor.invoke({"input": "帮我计算 (12 + 8) * 3,并告诉我当前时间"}) print(result)可以看到,框架帮你处理了大部分模板代码。你只需要用@tool装饰器定义一个函数,框架会读取函数的名称、docstring 和参数类型,自动生成工具描述和参数 Schema。
在 LangChain 和类似框架中,更推荐的方式是使用模型的 Function Calling 能力。模型不再输出一段需要正则解析的文本,而是直接返回一个结构化的 JSON,比如:
{ "name": "calculator", "arguments": "{\"expression\": \"(12 + 8) * 3\"}" }这种方式解析更稳定,参数校验也更严格。
5.3 跨语言生态:Java 与 Spring AI
Python 是 AI Agent 开发的主流语言,但很多企业后端是 Java 技术栈。如果项目需要把 Agent 集成到 Spring Boot 服务中,可以关注 Spring AI、Spring AI Alibaba 等社区项目。
这类 Java 生态的 AI 框架一般提供了以下能力:
- ChatClient:统一封装了大模型对话调用。
- Tool / Function Calling:支持把 Java 方法暴露给 LLM 调用。
- Embedding 和向量存储:用于 RAG 知识库。
- Agent 编排:支持将多个工具组合成 Agent 执行流。
关于 Java 侧的 Agent 开发,核心思路和 Python 是一致的:仍然是“LLM + 工具 + 循环”。只是语言不同、框架 API 不同。本文不再展开,后续可以单独写一篇 Spring AI Agent 的实战笔记。
6. 测试与调试:AI Agent 的工程化关键
很多初学者写完 Agent 后在本地跑通了一次,就以为大功告成了。实际上,AI Agent 和传统程序最大的区别在于不确定性。
同样的输入,模型这次输出Action: get_time,下次可能输出Action: GetCurrentTime,大小写出错就会导致工具调用失败。所以 Agent 的测试和调试是工程化中必须认真对待的一环。
6.1 测试思路
在测试 AI Agent 时,可以分几个层次:
| 测试层次 | 测试内容 | 示例 |
|---|---|---|
| 单元测试 | 工具函数是否正常 | 计算器工具能否正确计算 |
| 提示词测试 | 系统提示词是否能让模型稳定输出指定格式 | 连续调用 10 次,格式解析成功率 |
| 工具选择测试 | 模型是否在需要时调用正确工具 | 问天气时是否调用天气工具 |
| 集成测试 | 完整流程是否得到正确最终结果 | 输入问题,断言最终答案包含关键数字 |
| 回归测试 | 修改提示词或工具后是否破坏已有能力 | 用历史 case 集跑一遍 |
6.2 一个简单的 pytest 示例
# 文件路径:tests/test_agent.py import pytest from main import calculator, get_current_time @pytest.mark.parametrize( "expression, expected", [ ("1 + 2", "3"), ("(12 + 8) * 3", "60"), ("2 ** 10", "1024"), ], ) def test_calculator(expression, expected): result = calculator(expression) assert result == expected, f"calculator({expression}) = {result}, expected {expected}" def test_get_current_time_format(): result = get_current_time() assert len(result) == 19, f"时间格式不正确: {result}" def test_invalid_expression_returns_error_message(): result = calculator("1 +") assert "错误" in result or "Error" in result运行测试:
pip install pytest pytest tests/ -v这套测试目前只覆盖了工具层。要测试 Agent 的整体行为,通常需要 mock 掉 LLM 接口,让模型返回预设的 ReAct 输出,从而验证解析逻辑和工具调度逻辑是否正确。
6.3 调试与可观测性
AI Agent 的调试比传统代码困难,因为问题可能出在链路中的任何一环:
- Prompt 写得不清楚,模型没理解该调哪个工具。
- 工具描述与实际行为不一致,模型误用了工具。
- 工具返回异常数据,模型没有正确处理。
- 上下文过长,模型遗漏了早期信息。
所以在开发阶段,建议做好以下三点:
- 打印完整中间过程:每一轮 Agent 的 Thought、Action、Observation 都要能输出。
- 记录 Token 消耗:Agent 循环次数越多,Token 成本越高,需要记录每一步的消耗。
- 沉淀测试用例集:每次遇到一个 Bad Case,就把它加入回归测试集,防止后续修改引入新问题。
7. 常见问题与排查思路
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 模型一直输出 Final Answer,不调用工具 | 系统提示词里工具描述不清晰;模型不擅长 Function Calling | 优化工具描述;换用支持 Function Calling 的模型;降低 temperature |
| 模型输出的 Action 格式无法解析 | 没有使用结构性输出;提示词约束不足 | 在提示词中增加格式示例;使用 JSON mode 或函数调用 |
| 工具调用成功但结果错误 | 工具函数本身有 Bug;参数传递错误 | 单独对工具函数做单元测试;打印 Action Input 实际值 |
| Agent 陷入死循环 | 最大步数设置太大;模型一直调用同一个工具 | 限制 max_steps;当连续调用同一工具时主动中断 |
| 上下文超长 | 工具返回内容太大;历史轮数太多 | 限制工具返回值长度;使用记忆压缩或滑动窗口 |
报错OpenAIConnectionError | API Key 无效;网络无法访问接口 | 检查环境变量;确认 base_url;确认模型名是否存在 |
eval表达式导致安全问题 | 使用了不安全的代码执行方式 | 生产环境用ast.literal_eval或专业计算库,禁止 eval |
一个通用排查顺序:
- 先检查工具函数本身:单独调用函数是否正常?
- 再检查提示词:把模型输出打出来,看它是如何理解任务的?
- 然后检查工具调度:Action 名称、Action Input 是否和预期一致?
- 最后检查结果处理:Observation 是否正确回传给了模型?
按照这个顺序,大部分问题都能定位到具体环节。
8. 进阶方向与学习路线
上面我们已经完成了一个最简 Agent,并对框架和测试有了基本认识。接下来,如果想把 AI Agent 开发学得更深入,建议按照以下路线推进。
8.1 从单 Agent 到多 Agent
单 Agent 解决的是简单线性任务。真实业务往往更复杂,所以多 Agent 协作成为进阶方向。
多 Agent 的典型模式有两种:
- 指挥官模式:一个主 Agent 负责拆解任务,把子任务分发给多个子 Agent,最后汇总结果。
- 流水线模式:多个 Agent 按顺序协作,比如“搜索 Agent 找资料 → 写作 Agent 写初稿 → 校对 Agent 检查错误”。
多 Agent 的优势是每个 Agent 的职责更单一,提示词更可控,系统整体能力更强;挑战是通信成本、任务调度、错误传导都变得更复杂。
8.2 结合 RAG 和知识库
Agent 本身的知识来源于训练数据,无法覆盖企业内部文档和最新资料。把 RAG(检索增强生成)接入 Agent,是知识库类应用的常见架构。
热词中提到的 Obsidian + AI Agent 知识库就是一个典型场景。思路很清晰:
- 把本地 Markdown 笔记切块、向量化。
- 存入向量数据库。
- Agent 在回答知识类问题时,先检索相关文档片段。
- 把检索结果作为上下文交给 LLM 生成回答。
RAG 给 Agent 补上了“长期记忆”和“私有知识”能力,是目前企业落地最多、性价比最高的方案之一。
8.3 2026 年 AI Agent 开发趋势
从当前技术演进来看,AI Agent 的发展有几个明显方向:
- 从 Demo 到生产:关注点不再是“能不能跑通”,而是稳定性、成本、安全和可维护性。
- 评测体系成熟化:Agent 效果不能靠感觉判断,需要一套自动评测集来衡量工具调用准确率、任务完成率。
- 成本治理常态化:Agent 比普通 Chatbot 消耗更多 Token,缓存、模型路由、轻量模型调度会越来越重要。
- 平台化与标准化:Agent 的开发逐渐从“自己写框架”走向基于平台的标准化配置。
对开发者而言,不需要追求每个新框架都跟一遍,核心能力仍然是:理解 LLM 的调用方式、掌握工具抽象、熟练处理循环与状态、做好结果评测。
8.4 面试和就业重点关注什么
如果你准备找 AI Agent 相关岗位,除了刷基础题,下面这些高频面试方向值得重点准备:
- 手撕一个 ReAct Agent:面试官会让你现场写一个最小实现。
- 工具调用的原理:什么是 Function Calling,和 ReAct 有什么区别。
- 如何解决 Agent 的幻觉问题:工具约束、提示词约束、结果校验。
- 如何设计一个客服 Agent:从意图识别、工具接入、兜底策略、人工接管全流程回答。
- 如何评估 Agent 效果:准备一组评测集,统计准确率和工具命中率。
9. 最佳实践与工程建议
最后,结合我个人的开发经验,整理一份 AI Agent 工程落地的建议清单。
9.1 工具侧规范
工具是 Agent 最容易出错的地方。建议遵循以下原则:
- 工具职责单一:一个工具只做一件事,不要在工具里塞太多逻辑。
- 描述要写使用场景:不止写“查询天气”,要写“当用户询问天气时使用,入参为城市名”。
- 参数要有默认值和范围:如果参数是可选项,在描述中说明。
- 返回结构要稳定:工具返回要能被 LLM 可靠理解,建议返回结构化文本或 JSON。
9.2 提示词侧规范
- 在系统提示词中明确“只能使用列出的工具,不要编造工具”。
- 给出动作链的示例,帮助模型理解预期输出。
- 重要内容放在靠前的位置,避免模型在长上下文中遗漏关键信息。
- 遇到 Bad Case 时先改提示词,再改代码逻辑。
9.3 安全与成本控制
- 工具必须做权限控制:Agent 能调用的接口,必须是业务上允许它调用的。
- 涉及代码执行、数据库更新、文件删除等危险操作,默认禁止或需要二次确认。
- 使用最大步数限制,防止死循环烧 Token。
- 定期统计 Token 消耗,对高频调用做缓存或模型降级。
- 不要把 API Key 硬编码在代码或前端,统一走环境变量或密钥管理服务。
9.4 生产环境注意
- Agent 的每一步执行都要有日志,方便事后回溯。
- 设置全局超时时间,避免工具卡死拖垮整个请求。
- 内部工具失败时,给模型返回明确的错误信息,让模型能自主修正。
- 对最终结果增加校验,比如“结果中是否包含关键数据”,不通过则重试或转人工。
最后再提醒一次:本文实战中的eval仅用于学习演示。真实项目计算数学表达式时,建议使用ast.literal_eval或专门的表达式解析库,避免代码注入风险。Agent 拿到了工具能力之后,安全性就变成了第一条红线。下一阶段建议你把文章里的 ReAct 循环用成熟框架重新实现一遍,然后在自己的知识库或业务接口上接一个真实工具。等你开始纠结“工具调用失败率怎么降下来”的时候,你基本就摸到 AI Agent 工程化的门槛了。