
AI Agent(智能体)的概念正在重塑我们使用大语言模型的方式。传统聊天机器人只能根据训练数据回答问题,而AI Agent能够根据目标自主拆解任务、选择工具、执行动作并观察结果,再动态调整下一步策略。这种从“静态生成”到“动态执行”的跨越,让模型从“知道什么”进化为“能做什么”。一个典型的AI Agent运行时会持续维护一个上下文窗口,其中不仅包括用户输入和历史对话,还包括工具调用记录、执行结果以及中间推理步骤。本文先厘清AI Agent的组成结构,再深入自主决策和工具调用的底层逻辑,最后给出一个最小可运行的实现示例。
AI Agent的组成结构:从模型到智能体的跃迁
一个完整的AI Agent通常包含四个核心模块:大脑(LLM)、规划器、记忆系统和工具集。大脑负责理解与生成,规划器负责将大目标分解为可执行的小步骤,记忆系统存储短期对话状态和长期知识,工具集则提供与外部世界交互的能力。与传统聊天应用的直接应答不同,AI Agent会在每次需要行动时输出一种特殊格式——通常是包含“思考”“行动”“观察”三部分的文本,或者直接输出函数调用所需的JSON结构。这种输出不再是面向用户的自然语言,而是面向运行框架的指令。
规划器是AI Agent区别于普通LLM应用的关键。它可以采用简单的链式思考(Chain of Thought),也可以使用更复杂的ReAct模式或树状搜索。简单来说,规划器的任务是在每一步决定:是继续生成最终答案,还是调用某个工具获取更多信息?这个决策过程可能包含自我反思,例如“当前信息不足,需要查询实时天气”。记忆系统则分为工作记忆(当前任务上下文)和外部记忆(向量数据库或键值存储),后者让Agent能够跨会话积累经验。
工具集的设计直接决定了Agent的能力边界。一个工具可以是一个Python函数、一个HTTP API、甚至是一个本地脚本。工具通常被描述为带名称、描述、参数schema的结构化元数据,这样LLM才能理解何时以及如何使用它。例如,一个计算器工具的描述可能是“计算数学表达式,输入字符串,输出数值结果”。当Agent判断需要计算时,会生成一个调用该工具的动作,框架执行后把结果追加回上下文,Agent再次推理。
自主决策:规划、反思与循环控制
自主决策是AI Agent的“大脑中枢”,它决定了Agent每一步要做什么。目前主流的决策模式是ReAct(Reasoning + Acting),其核心思想是交替进行推理和行动。在ReAct框架下,模型每次生成的内容分为“思考”和“行动”两部分。思考部分包含对当前状态的分析和对下一步的选择依据,行动部分则明确要调用的工具名称和参数。框架执行工具后,将结果以“观察”的形式回传给模型,模型继续下一轮思考。这种循环持续到模型输出最终答案为止。
为了让模型更好地进行自主决策,提示词工程(Prompt Engineering)至关重要。一个典型的ReAct提示词模板会先定义可用工具列表及其描述,然后引导模型按照固定格式输出。例如:
你是一个智能助手,可以使用以下工具: 1. search(query: str) -> str: 搜索互联网获取实时信息。 2. calculator(expression: str) -> float: 计算数学表达式。 请按照以下格式回复: 思考:你的推理过程 行动:工具名称[参数] 观察:工具返回结果 ...(重复) 最终答案:面向用户的回答
这种格式约束使得模型输出可被解析,从而驱动整个执行循环。除了ReAct,还有Plan-and-Execute模式,即先一次性生成完整计划,再逐步执行;以及Reflexion模式,在执行失败后加入自我批评环节以改进后续尝试。这些模式本质上都是通过结构化提示和上下文管理来增强模型的决策能力。
自主决策的另一个重要机制是“停止条件”。Agent不能无限循环下去,必须设定最大迭代次数、超时时间或特定终止信号。例如,当模型输出以“最终答案:”开头时,框架提取该部分作为返回结果并结束循环。此外,还需要处理模型幻觉——当模型虚构了一个不存在的工具时,框架应捕获异常并告知模型“工具不存在,请重新规划”,从而引导模型修正行为。
工具调用:意图识别与参数提取
工具调用是AI Agent与外部世界交互的桥梁。在底层实现上,大语言模型本身并不直接“调用”任何函数,它只是生成一段文本或JSON,由外部框架解析并执行对应的函数。因此,工具调用的第一步是意图识别:判断用户请求是否需要使用工具,以及使用哪个工具。这一步通常由模型在提示词的引导下完成,例如提示词中明确说明“如果问题涉及实时信息,请使用search工具”。更高级的做法是使用函数调用(Function Calling)API,模型可以返回一个结构化的函数调用对象,包含函数名和参数,避免了文本解析的脆弱性。
参数提取是工具调用的第二个关键环节。模型需要从自然语言中准确提取出工具所需的参数,并填充到schema中。例如用户问“北京今天天气怎么样?”,Agent识别出需要调用天气工具,参数为城市“北京”和日期“今天”。如果参数缺失或不明确,Agent可以反问用户进行澄清。参数类型校验也很重要,例如日期参数需要转换为标准格式,数值参数需要确保为数字而非字符串。一些框架支持将工具schema以JSON Schema格式提供给模型,模型返回的JSON对象可以直接用于函数调用。
工具执行后的结果需要回灌到上下文中。这个结果可能是一个短字符串、一段JSON或者一个错误信息。回灌的方式会影响模型的后续推理。通常框架会将工具输出包装成“观察:...”的形式,让模型看到执行结果后再决定下一步行动。如果工具执行失败(例如网络超时),错误信息也会回传给模型,模型可以尝试更换工具、修改参数或放弃工具直接回答。这种“执行-反馈”闭环是AI Agent能够处理复杂任务的核心原因。
实现一个最小可运行的AI Agent
下面通过一个Python示例展示如何构建一个简单的AI Agent,它能够调用搜索工具和计算器工具来回答用户问题。我们假设已经接入了一个大模型API(此处用伪代码表示),重点展示决策循环和工具调用的流程。整个Agent的核心是一个while循环,不断向模型发送上下文,解析模型输出,执行工具,直到得到最终答案。
import json
import re
# 工具定义
def search(query: str) -> str:
"""模拟搜索引擎,返回与查询相关的摘要信息"""
# 实际项目中可调用SerpAPI、Bing API等
fake_results = {
"北京天气": "北京今天晴,气温25摄氏度,湿度40%。",
"特斯拉股价": "特斯拉当前股价为245.30美元,较昨日上涨2.1%。",
}
return fake_results.get(query, f"未找到关于'{query}'的信息")
def calculator(expression: str) -> float:
"""安全地计算数学表达式"""
# 实际生产环境需使用更安全的解析器
return eval(expression)
# 工具元数据
tools = [
{
"name": "search",
"description": "搜索互联网获取实时信息,输入关键词字符串,输出摘要文本",
"parameters": {"query": "string"}
},
{
"name": "calculator",
"description": "计算数学表达式,输入如'2+3*4',输出数值",
"parameters": {"expression": "string"}
}
]
# 模拟大模型API(实际替换为OpenAI或本地模型)
def call_llm(messages):
# 此处用一个简化的规则引擎模拟ReAct输出,实际项目需调用真实LLM
last_user_input = messages[-1]["content"]
if "天气" in last_user_input:
return "思考:用户询问天气,需要实时信息。\n行动:search[北京天气]\n"
elif "计算" in last_user_input or "+" in last_user_input:
# 提取表达式(示例仅处理简单加法)
match = re.search(r'[-+]?\d+(?:\.\d+)?\s*\+\s*[-+]?\d+(?:\.\d+)?', last_user_input)
expr = match.group(0).replace(" ", "") if match else "1+1"
return f"思考:用户需要计算,使用计算器工具。\n行动:calculator[{expr}]\n"
else:
return "最终答案:我是AI助手,请告诉我需要什么帮助。"
def run_agent(user_query, max_iterations=5):
messages = [{"role": "user", "content": user_query}]
for _ in range(max_iterations):
response = call_llm(messages)
print(f"模型输出:\n{response}\n")
# 检查是否包含最终答案
if "最终答案:" in response:
final_answer = response.split("最终答案:", 1)[1].strip()
return final_answer
# 解析行动指令
action_match = re.search(r'行动:\s*(\w+)\[(.*?)\]\s*$', response, re.MULTILINE)
if not action_match:
# 没有解析到行动,视为最终答案
return response.strip()
tool_name = action_match.group(1)
tool_arg = action_match.group(2)
# 查找并执行工具
if tool_name == "search":
result = search(tool_arg)
elif tool_name == "calculator":
result = calculator(tool_arg)
else:
result = f"错误:工具{tool_name}不存在"
# 将观察结果追加到消息
observation = f"观察:{result}"
messages.append({"role": "assistant", "content": response})
messages.append({"role": "user", "content": observation})
return "达到最大迭代次数,任务未完成。"
if __name__ == "__main__":
print(run_agent("北京今天天气怎么样?"))
print("---")
print(run_agent("帮我计算12+34等于多少"))
上述代码演示了ReAct循环的骨架:模型输出“思考”和“行动”,框架解析行动字符串,执行对应函数,将“观察”回传。虽然示例中的call_llm是一个简化的模拟,但真实情况下只需将该函数替换为实际的大模型API调用即可。实际开发中推荐使用LangChain、Semantic Kernel等成熟框架,它们已经封装好了工具管理、记忆存储和多种决策模式。
构建AI Agent时还需要考虑一些工程实践:工具函数应当具有幂等性(多次调用无副作用)、超时控制、错误重试等特性;提示词必须明确工具使用的边界,防止模型滥用工具;上下文窗口的管理尤为重要,当对话过长时需要截断或摘要历史信息。此外,安全性不可忽视,工具执行可能涉及命令注入、越权访问等风险,必须对模型输出的参数进行严格校验。
AI Agent正在从概念走向大规模应用。理解自主决策和工具调用的工作原理,不仅有助于构建更智能的应用程序,也能帮助开发者诊断Agent行为异常的原因。随着多模态模型和更强大的规划算法的出现,AI Agent的能力边界还将持续扩展。对于想要入门的开发者,建议从调用带函数能力的模型API开始,逐步实现自己的第一个可运行Agent。