LangChain Agent实战指南
2025-10-31 16:46:00
文章摘要
揭秘Agent系统:它为大模型装上工具,实现实时信息查询、复杂计算和外部API调用。文章详细解析高效率的Function Call模式和高透明度的ReAct 推理

我们有了强大的大语言模型,为什么还需要 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绝对值得一试。

声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。