news 2026/9/8 3:06:24

AI Agent开发完全指南:从ReAct循环到工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent开发完全指南:从ReAct循环到工程实践

搜索引擎里关于 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 框架要做的就是:

  1. 把上述格式写进系统提示词。
  2. 调用 LLM 拿到文本输出。
  3. 解析输出中的 Action 和 Action Input。
  4. 执行对应工具。
  5. 把 Observation 拼接回上下文。
  6. 再次调用 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.md

4. 手把手实战:从零实现一个可调用工具的 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 写得不清楚,模型没理解该调哪个工具。
  • 工具描述与实际行为不一致,模型误用了工具。
  • 工具返回异常数据,模型没有正确处理。
  • 上下文过长,模型遗漏了早期信息。

所以在开发阶段,建议做好以下三点:

  1. 打印完整中间过程:每一轮 Agent 的 Thought、Action、Observation 都要能输出。
  2. 记录 Token 消耗:Agent 循环次数越多,Token 成本越高,需要记录每一步的消耗。
  3. 沉淀测试用例集:每次遇到一个 Bad Case,就把它加入回归测试集,防止后续修改引入新问题。

7. 常见问题与排查思路

问题现象常见原因解决思路
模型一直输出 Final Answer,不调用工具系统提示词里工具描述不清晰;模型不擅长 Function Calling优化工具描述;换用支持 Function Calling 的模型;降低 temperature
模型输出的 Action 格式无法解析没有使用结构性输出;提示词约束不足在提示词中增加格式示例;使用 JSON mode 或函数调用
工具调用成功但结果错误工具函数本身有 Bug;参数传递错误单独对工具函数做单元测试;打印 Action Input 实际值
Agent 陷入死循环最大步数设置太大;模型一直调用同一个工具限制 max_steps;当连续调用同一工具时主动中断
上下文超长工具返回内容太大;历史轮数太多限制工具返回值长度;使用记忆压缩或滑动窗口
报错OpenAIConnectionErrorAPI Key 无效;网络无法访问接口检查环境变量;确认 base_url;确认模型名是否存在
eval表达式导致安全问题使用了不安全的代码执行方式生产环境用ast.literal_eval或专业计算库,禁止 eval

一个通用排查顺序:

  1. 先检查工具函数本身:单独调用函数是否正常?
  2. 再检查提示词:把模型输出打出来,看它是如何理解任务的?
  3. 然后检查工具调度:Action 名称、Action Input 是否和预期一致?
  4. 最后检查结果处理: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 知识库就是一个典型场景。思路很清晰:

  1. 把本地 Markdown 笔记切块、向量化。
  2. 存入向量数据库。
  3. Agent 在回答知识类问题时,先检索相关文档片段。
  4. 把检索结果作为上下文交给 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 工程化的门槛了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 3:05:39

MODBUS RTU调试实战:从帧格式、CRC校验到RS485物理层,一文搞定

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

作者头像 李华
网站建设 2026/9/8 3:04:31

VEML6030环境光传感器I2C驱动开发与lux换算实战指南

简介:面向需要快速集成威世VEML6030环境光/紫外线传感器的嵌入式开发者,这套驱动程序包涵盖I2C驱动设计与典型应用示例,适合智能设备、健康监测或户外照明控制等场景。包内共2个文件,包含一个C源文件与一个头文件,分别…

作者头像 李华
网站建设 2026/9/8 3:02:23

雷电模拟器与ADB调试:基于uiautomator2的安卓自动化脚本实战

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

作者头像 李华
网站建设 2026/9/8 3:02:19

BusyBox与根文件系统构建:从零搭建嵌入式Linux最小系统

2. 核心细节解析与实操要点先别急着敲命令。很多教程一上来就让人make menuconfig,然后稀里糊涂编出一个busybox二进制,拷贝到板子上发现起不来,又回过头来查了一整天。我当初也这么干过。所以这篇文章换个思路:先把BusyBox这个“…

作者头像 李华
网站建设 2026/9/8 3:01:42

macOS 安装 mysqlclient 报错 -lssl 的完整解决方案

如果你也是在一台全新的 macOS 上跑pip install mysqlclient,结果刷了大半屏日志,最后看到一行ld: library not found for -lssl——恭喜,你遇上了 macOS 上 Python C 扩展编译最经典的翻车现场。这个报错不怪你代码,不怪 pip&…

作者头像 李华
网站建设 2026/9/8 3:01:23

Android属性服务PropertyService源码解析:从setprop到Binder全链路

1. PropertyService 是什么,为什么值得读源码先交代一个背景:PropertyService(属性服务)是 Android 系统里最“不起眼”却最核心的系统服务之一,运行在 system_server 进程中,通过 Binder 对外提供系统属性…

作者头像 李华