揭秘Agent系统:它为大模型装上工具,实现实时信息查询、复杂计算和外部API调用。文章详细解析高效率的Function Call模式和高透明度的ReAct 推
2025-12-29 10:43:21

我们有了强大的大语言模型,为什么还需要 Agent?

直到有一天,我试着让GPT帮我查询北京天气并规划行程,它能告诉我"作为AI模型,我无法获取实时信息"

这一刻我才恍然大悟,模型再聪明,缺少手脚也只能纸上谈兵。

而Agent,就是给AI装上手脚的那把钥匙。

一、 Agent的核心组件

一个完整的Agent系统通常包含以下"器官":

二、Agent的两种思考模式

在LangChain中,Agent有两种主流的决策模式,分别对应直觉型和分析型。

2.1 Function Call模式

工作原理:模型直接输出结构化的JSON,明确指定要调用哪个工具和参数。

{
"tool": "Search",
"args": {"query": "特斯拉最新股价"}
}

工具明确、任务清晰的场景

效率高:一步到位,无需多轮对话

出稳定:JSON格式便于程序解析

依赖模型:需要GPT-4等支持函数调用的高级模型

LangChain中的实现:

● AgentType.OPENAI_FUNCTIONS

● AgentType.OPENAI_MULTI_FUNCTIONS(支持并行调用多工具)

2.2 ReAct模式

ReAct = Reasoning(推理) + Acting(行动)

这种模式会让Agent像人类一样自言自语的分析问题:

问题:特斯拉股价比去年涨了多少?

思考:我需要先查到当前股价

行动:调用Search工具

观察:当前股价$323.63

思考:还需要去年同期的价格

行动:再次调用Search工具

观察:去年同期$298.26

思考:现在可以计算涨幅了

行动:调用Calculator工具

观察:涨幅8.51%

最终答案:特斯拉股价比去年上涨了8.51%

优势

过程透明:每一步推理都清晰可见

通用性强:不需要模型特别支持函数调用

自我纠错:可以根据观察结果调整策略

LangChain中的实现:

AgentType.ZERO_SHOT_REACT_DESCRIPTION(零样本推理)

AgentType.CONVERSATIONAL_REACT_DESCRIPTION(带记忆的对话)

2.3 两种模式该怎么选?

建议:如果你在做工作环境的应用,优先选Function Call模式(性能和成本都更优);如果是做研究或需要调试 Agent,ReAct模式的透明性会让你事半功倍。

三、 实战案例

这里以硅基流动的免费API为例。

案例1:文本长度分析工具

from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
import os
from typing import Literal

os.environ["OPENAI_API_KEY"] = "" # 替换为你的 SiliconFlow API Key

@tool
def text_length_analyzer(text: str) -> str:
"""
文本长度分析工具,用于计算给定字符串中的字符数量(包括空格、标点符号)。

参数:
text: 待分析的文本字符串。

返回:
一个包含原始文本和字符数量的结果字符串。
"""
# 增加日志输出,以便观察Agent是否正确调用了工具
print(f"[工具调用] 分析文本长度: '{text[:20]}...'")
length = len(text)
return f"原始文本字符数为: {length}。"


llm = ChatOpenAI(
model="Qwen/Qwen2.5-7B-Instruct", # 支持 function calling 的模型
api_key=os.environ.get("OPENAI_API_KEY", "YOUR_API_KEY"), # 从环境变量中获取
base_url=os.environ.get("SILICONFLOW_BASE_URL", "https://api.siliconflow.cn/v1"),
temperature=0
)


agent_executor = create_react_agent(
model=llm,
tools=[text_length_analyzer]
)


if __name__ == "__main__":
try:
# 测试1: 需要工具调用的情况
print("=== 测试1: 需要调用工具计算文本长度 ===")
# 提示词很明确地要求计算长度
result1 = agent_executor.invoke({
"messages": [("user", "请帮我计算一下'LangChain是一个非常强大的框架,专门用于构建大模型驱动的应用。'这句话有多少个字符。")]
})
print(f"最终回答: {result1['messages'][-1].content}\n")

# 测试2: 不需要工具调用,只进行知识问答(考验Agent的决策能力)
print("=== 测试2: 简单知识问答 ===")
# 提示词是一个简单的问答,Agent应该判断出不需要使用工具
result2 = agent_executor.invoke({
"messages": [("user", "什么是LangChain?")]
})
print(f"最终回答: {result2['messages'][-1].content}\n")
# 测试3: 包含英文和标点符号的复杂文本
print("=== 测试3: 复杂文本长度分析 ===")
result3 = agent_executor.invoke({
"messages": [("user", "请计算一下文本 'Hello, AI! 你好,世界。' 的字符数。")]
})
print(f"最终回答: {result3['messages'][-1].content}\n")


except Exception as e:
print(f"运行发生错误: {e}")
import traceback
traceback.print_exc()

执行日志:

案例2:平方计算器(灵活实用)

from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
import os

# 确保设置了 SiliconFlow API Key
os.environ["OPENAI_API_KEY"] = "" # 替换为你的 SiliconFlow API Key


# 1. 使用 @tool 装饰器定义工具
@tool
def simple_calculator(expression: str) -> str:
"""
数学计算工具,用于执行数学表达式计算。

参数:
expression: 数学表达式,例如 '3**2', '10+5', '100/4'

返回:
计算结果的字符串形式
"""
print(f"[工具调用] 计算: {expression}")
try:
result = eval(expression)
return str(result)
except Exception as e:
return f"计算错误: {str(e)}"


# 2. 创建 LLM 实例(使用 SiliconFlow 的 API,并切换到支持工具调用的模型)
llm = ChatOpenAI(
model="Qwen/Qwen2.5-7B-Instruct", # 支持 function calling 的模型
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.siliconflow.cn/v1",
temperature=0
)

# 3. 创建 Agent
agent_executor = create_react_agent(
model=llm,
tools=[simple_calculator]
)

# 4. 测试 Agent
if __name__ == "__main__":
try:
# 测试1
print("=== 测试1: 计算 3 的平方 ===")
result = agent_executor.invoke({
"messages": [("user", "计算3的平方")]
})
print(f"最终回答: {result['messages'][-1].content}\n")

# 测试2
print("=== 测试2: 复杂计算 ===")
result = agent_executor.invoke({
"messages": [("user", "帮我计算 (15 + 25) * 2 的结果")]
})
print(f"最终回答: {result['messages'][-1].content}\n")

except Exception as e:
print(f"错误: {e}")
import traceback

traceback.print_exc()

执行日志:

四、避坑指南

4.1 提示词工程的艺术

Agent的表现80%取决于提示词质量。一个好的提示词应该包含:

template = """
你是{角色定位},擅长{核心能力}。

你可以使用以下工具:
{tools}

【重要规则】
1. 必须先思考再行动
2. 每次只调用一个工具
3. 如果工具返回错误,尝试修改参数重试
4. 最多尝试3次后报告失败

【输出格式】
Thought: [你的分析]
Action: [工具名称]
Action Input: [工具参数]
"""

4.2 常见错误与解决方法

4.3 性能优化建议

缓存搜索结果:相同查询不要重复搜索

工具描述精简:每次调用都会传给LLM,太长浪费tokens

限制工具数量:超过10个工具会让Agent"选择困难"

使用流式输出:提升用户体验

# 流式输出示例
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
stream_runnable=True # 关键参数
)

for chunk in agent_executor.stream({"input": "查询天气"}):
print(chunk, end="", flush=True)

小总结:从目前来看,Agent不是万能的,但在特定场景下确实能解放生产力。它最适合的场景是:

需要调用多个外部API

任务流程不固定,需要动态决策

要处理实时信息或复杂计算

但也要清醒认识到它的局限:

成本比传统编程高(每次推理都要调LLM)

结果不稳定(大模型的通病)

调试困难(尤其是Function Call模式)

如果一个简单的 if-else能解决的问题,就别用Agent;但如果你在构建真正需要智能决策系统,Agent绝对值得一试。


声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。
标签:
量子 AI
智能体(Agent)
Function Call模式
ReAct模式
外部API调用
实时信息查询
复杂计算