LangChain 中创建 Agent(智能体)方法

create_react_agentcreate_tool_calling_agent 是 LangChain 中用于创建 Agent(智能体) 的两个不同函数,它们代表了 两种不同的 Agent 架构和运行机制。以下是它们的核心区别:

一、根本区别概览

特性 create_react_agent create_tool_calling_agent
底层原理 基于 ReAct(Reason + Act)推理框架 基于 LLM 原生 函数调用(Function Calling / Tool Calling) 能力
适用模型 任何 LLM(包括不支持 function calling 的) 仅支持原生函数调用的 ChatModel(如 GPT-4, Claude 3, Qwen-Max, GLM-4 等)
提示词结构 需要复杂 prompt 模拟 ReAct 循环 利用模型内置的 tool calling 协议
输出格式 文本中解析 Action: xxx\nAction Input: yyy 直接返回结构化 tool_calls 对象
可靠性 依赖 prompt 工程,可能解析失败 更可靠、更高效(由模型原生支持)
LangChain 推荐度 旧方案(兼容性用途) 新推荐方案(v0.1+ 主流)

示例一:create_react_agent

'''

react_prompt = PromptTemplate.from_template("""

你是一个智能助手,必须严格按照以下格式进行推理和回答。你可以使用以下工具:

{tools}

可用工具名称:{tool_names}

请严格使用以下格式(注意:每一步必须换行,关键字后跟冒号和空格):

Question: 用户的问题

Thought: 我需要思考该做什么

Action: 要调用的工具名称,必须是 [{tool_names}] 中的一个

Action Input: 传递给工具的参数,工具的输入

Observation: 工具返回的结果

...(可以重复多次 Thought/Action/Action Input/Observation)

Thought: 我现在知道最终答案了

Final Answer: 对用户问题的最终答案

对话历史:

{chat_history}

现在开始!

Question: {input}

Thought: {agent_scratchpad}

""")

复制代码
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory


model = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434")

# 定义工具
@tool
def get_weather(city: str):
    """
    获取指定城市的天气信息。输入必须是城市名称(如 '北京'),不要包含其他文字。
    """
    weather = {
        "北京": "晴天30度",
        "成都": "晴天32度",
    }
    return weather.get(city, f'{city}天气未知')


@tool
def cal(expression: str):
    """
    计算数学表达式
    """
    try:
        result = eval(expression)
        return f'计算结果:{result}'
    except Exception as e:
        return f"计算错误:{e}"


# ReAct 提示词模板
# 提示词中的这些参数名字固定不能更改,并且系统自动填入不需要传参数
react_prompt = PromptTemplate.from_template("""
你是一个智能助手。必须严格按照以下格式进行推理和回答。你可以使用以下工具:

{tools}

工具名称:{tool_names}

使用以下格式回答:

Question: 用户的问题
Thought: 你应该思考要做什么
Action: 要使用的工具,必须是[{tool_names}]中的一个
Action Input: 工具的输入
observation: 工具返回的结果
...(可以重复 Thought/Action/Action Input/observation 多次)
Thought: 我现在知道最终答案了
Final Answer: 对原始问题的最终答案
对话历史:
{chat_history}

开始!

Question: {input}
Thought:{agent_scratchpad}
""")

# 创建ReAct Agent
tools = [get_weather, cal]
agent = create_react_agent(model, tools, react_prompt)

memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=False,
    input_key="input",
    output_key="output"
)

agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, memory=memory,
                               handle_parsing_errors=True,
                               max_iterations=3,  # 防止无限循环
                               early_stopping_method="generate"  # 到达最大步数时生成答案
                               )

result = agent_executor.invoke({"input": "北京天气如何?如果温度是30度,转成华氏度是多少?"})
print(result["output"])


# 多轮对话测试
# result =agent_executor.invoke({"input": "北京天气如何?"})
# print(result["output"])
#
# result = agent_executor.invoke({"input": "那温度转成华氏度是多少?"}) # 会记住30度
# print(result["output"])

输出结果:

Thought: 我需要先获取北京的天气信息,然后计算30度 Celsius转华氏度的值。
Action: get_weather
Action Input: 北京晴天30度Thought: 我需要先获取北京的天气信息,然后计算30度 Celsius转华氏度的值。
Action: get_weather
Action Input: 北京晴天30度 

Agent 重复调用 get_weather,并且 Action Input 错误地传入了 "北京晴天30度"(这是工具的输出,不是输入),同时完全没调用 cal 工具。

原因:

模型(Qwen3:8b)对 ReAct 格式理解有限

  • Qwen3 虽然支持中文,但在 结构化推理(ReAct)+ 工具调用 上不如 GPT-4 或 Claude。
  • 它容易"自由发挥",把 Observation 的内容错误地当作下一次的 Action Input

尝试换用更强的模型,如 qwen3:32bllama3.1:8b-instruct-q8_0

复制代码
react_prompt = PromptTemplate.from_template(
    """你是一个智能助手,必须严格遵守以下规则:

1. 只能使用以下工具:
{tools}

2. 工具名称:{tool_names}

3. 回答必须使用以下格式(每行以关键词开头,且关键词后紧跟冒号和空格):

Question: 用户的问题
Thought: 你应思考要做什么
Action: 要使用的工具,必须是 [{tool_names}] 中的一个
Action Input: 工具的输入
Observation: 工具返回的结果
...(可重复多次)
Thought: 我现在知道最终答案了
Final Answer: 对原始问题的最终答案

4. 对话历史:
{chat_history}

现在开始!

Question: {input}
Thought: {agent_scratchpad}"""
)

预期正确流程:

复制代码
Question: 北京天气如何?如果温度是30度,转成华氏度是多少?
Thought: 我需要先获取北京的天气。
Action: get_weather
Action Input: 北京
Observation: 晴天30度
Thought: 我需要将30摄氏度转换为华氏度。
Action: cal
Action Input: 30 * 9 / 5 + 32
Observation: 计算结果:86.0
Thought: 我现在知道最终答案了。
Final Answer: 北京天气晴天30度,30摄氏度等于86华氏度。

采用新版方式,加入记忆:

复制代码
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

# ================== 工具定义 ==================
@tool
def get_weather(city: str):
    """获取指定城市的天气信息。输入必须是城市名称(如 '北京'),不要包含其他文字。"""
    weather = {
        "北京": "晴天30度",
        "成都": "晴天32度",
    }
    return weather.get(city.strip(), f"{city}天气未知")


@tool
def cal(expression: str):
    """计算数学表达式,例如 '30 * 9 / 5 + 32'。仅支持基本算术运算。"""
    try:
        # 使用 eval 存在风险,生产环境请替换为 simpleeval
        result = eval(expression)
        return f"计算结果:{result}"
    except Exception as e:
        return f"计算错误:{e}"


# ================== LLM 与 Agent ==================
model = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434")

tools = [get_weather, cal]

# 注意:{chat_history} 必须出现在 prompt 中,且 input_key 要匹配
react_prompt = PromptTemplate.from_template("""
你是一个智能助手。必须严格按照以下格式进行推理和回答。你可以使用以下工具:

{tools}

工具名称: {tool_names}

使用以下格式回答:

Question: 用户的问题
Thought: 你应该思考要做什么
Action: 要使用的工具,必须是 [{tool_names}] 中的一个
Action Input: 工具的输入(必须是纯值,如城市名或表达式)
Observation: 工具返回的结果
...(可以重复多次)
Thought: 我现在知道最终答案了
Final Answer: 对原始问题的最终答案

对话历史:
{chat_history}

开始!

Question: {input}
Thought: {agent_scratchpad}
""")

agent = create_react_agent(model, tools, react_prompt)

# 创建 AgentExecutor(注意:这里不传 memory!)
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=3
)

# ================== 添加会话记忆 ==================
store = {}

def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

# 包装成带历史的 Runnable
agent_with_chat_history = RunnableWithMessageHistory(
    runnable=agent_executor,
    get_session_history=get_session_history,
    input_messages_key="input",          # 用户输入字段名
    history_messages_key="chat_history", # 历史消息字段名(必须和 prompt 中一致)
)

# ================== 测试调用 ==================
if __name__ == "__main__":
    session_id = "user_123"

    result0 = agent_with_chat_history.invoke(
        {"input": "北京天气如何?如果温度是30度,转成华氏度是多少?"},
        config={"configurable": {"session_id": session_id}}
    )
    print(result0["output"])

    # # 第一轮
    # result1 = agent_with_chat_history.invoke(
    #     {"input": "北京天气如何?"},
    #     config={"configurable": {"session_id": session_id}}
    # )
    # print("第一轮:", result1["output"])
    #
    # # 第二轮(依赖上文)
    # result2 = agent_with_chat_history.invoke(
    #     {"input": "那30摄氏度是多少华氏度?"},
    #     config={"configurable": {"session_id": session_id}}
    # )
    # print("第二轮:", result2["output"])

示例二:create_tool_calling_agent

复制代码
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.tools import tool
from langchain_ollama import ChatOllama

# 初始化大语言模型 - 负责决策
model = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434")

@tool
def add(a: int, b: int):
    """两个数相加"""
    return a + b


# 构建 prompt(必须包含 placeholders)
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个有用的助手"),
    ("human", "{input}"),
    MessagesPlaceholder("agent_scratchpad")  # 必须有这个才能记录工具调用过程,这是 Agent 记录"工具调用 → 结果"历史的地方
])
# prompt: 提示模板,必须包含 MessagesPlaceholder("agent_scratchpad"),用于记录工具调用的历史

# 创建 agent
# create_tool_calling_agent 需要知道有哪些工具可用,以便在 prompt 中描述它们(让模型知道能调什么)。

agent = create_tool_calling_agent(model, [add], prompt)  # [add]: 可用的工具列表

# AgentExecutor 需要知道如何执行这些工具(实际调用函数)。
agent_executor = AgentExecutor(agent=agent, tools=[add], verbose=True)

# 调用
result = agent_executor.invoke({"input": "计算 5623633 + 522565689"})
print(result["output"])

示例三:create_tool_calling_agent

在正式使用前,先测试模型的 Function Calling 能力:

复制代码
# 测试模型的 function calling 能力
from langchain_ollama import ChatOllama
from langchain_core.tools import tool

@tool
def test_tool(answer: str):
    """测试工具。参数 answer 是一个字符串。"""
    return f"你输入了: {answer}"

model = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434", temperature=0)

# 绑定工具
model_with_tools = model.bind_tools([test_tool])

response = model_with_tools.invoke("请调用测试工具,参数是'hello'")
print(response)

如果输出中没有 tool_calls 字段,说明该模型不支持 Function Calling。

qwen3:8b 确实支持 Function Calling。

在执行前打印工具的 schema,帮助诊断:

复制代码
from langchain_core.utils.function_calling import convert_to_openai_tool
from langchain_core.tools import tool


@tool
def test_tool(answer: str):
    """测试工具。参数 answer 是一个字符串。"""
    return f"你输入了: {answer}"

tools = [test_tool]

# 打印工具的 OpenAI 格式 schema
for tool in tools:
    print(f"\n工具: {tool.name}")
    print(f"描述: {tool.description}")
    print(f"Schema: {convert_to_openai_tool(tool)}")
    print("-" * 50)

完整代码:

复制代码
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

# ================== 工具定义 ==================
@tool
def get_weather(city: str):
    """获取指定城市的天气。输入必须是城市名称(如 "北京")。"""
    weather = {"北京": "晴天30度", "成都": "晴天32度"}
    return weather.get(city.strip(), f"{city}天气未知")


@tool
def cal(expression: str):
    """计算数学表达式,例如 '30 * 9 / 5 + 32'。仅支持基本算术运算。"""
    try:
        # 注意:eval 有安全风险,生产环境请用 simpleeval
        result = eval(expression)
        return str(result)
    except Exception as e:
        return f"计算错误: {e}"


# ================== LLM 与 Agent ==================
# 使用支持 function calling 的模型
model = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434", temperature=0.2)

tools = [get_weather, cal]

# 构建 prompt(必须包含 agent_scratchpad)
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个智能助手,可以调用工具回答问题。请利用对话历史理解上下文。"),
    MessagesPlaceholder("chat_history"),  
    ("human", "{input}"),
    MessagesPlaceholder("agent_scratchpad")  # 必需:记录工具调用过程
])

# 创建 Tool-Calling Agent
agent = create_tool_calling_agent(model, tools, prompt)

# 创建执行器(不传 memory!)
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=3
)

# ================== 添加会话记忆 ==================
store = {}

def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

# 包装成带历史的 Runnable
agent_with_memory = RunnableWithMessageHistory(
    runnable=agent_executor,
    get_session_history=get_session_history,
    input_messages_key="input",
    history_messages_key="chat_history",  # 注意:Tool-Calling Agent 不直接使用 chat_history,但 RunnableWithMessageHistory 会自动注入 Human/AI 消息
)

# ================== 测试多轮对话 ==================
if __name__ == "__main__":
    session_id = "user_abc"

    result0 = agent_with_memory.invoke(
        {"input": "北京天气如何?如果温度是30度,转成华氏度是多少?"},
        config={"configurable": {"session_id": session_id}}
    )
    print(result0["output"])

    # # 第一轮:问天气
    # result1 = agent_with_memory.invoke(
    #     {"input": "北京天气怎么样?"},
    #     config={"configurable": {"session_id": session_id}}
    # )
    # print("第一轮:", result1["output"])
    #
    # # 第二轮:基于上文问温度转换(依赖"30度"来自上文)
    # result2 = agent_with_memory.invoke(
    #     {"input": "那30摄氏度等于多少华氏度?"},
    #     config={"configurable": {"session_id": session_id}}
    # )
    # print("第二轮:", result2["output"])

┌─────────────────────────────────────────────────────────┐
│  Prompt 模板结构:                                       │
├─────────────────────────────────────────────────────────┤
│  [System Message]                                       │
│      "你是一个智能助手..."                               │
│                                                         │
│  [chat_history] ← RunnableWithMessageHistory 自动注入    │
│      AI: 第一轮回答                                      │
│      Human: 第二轮问题                                   │
│      AI: 第二轮回答                                      │
│                                                         │
│  [input] ← 当前用户输入                                  │
│      "把那个温度转成华氏度"                              │
│                                                         │
│  [agent_scratchpad] ← Agent 执行过程中自动填充           │
│      Tool: cal(expression="30 * 9 / 5 + 32")            │
│      Tool Output: "86.0"                                │
└─────────────────────────────────────────────────────────┘

输出结果:

这个错误很明显:模型错误地调用了 cal 工具,并且传了错误的参数 {'city': '北京'}

问题根源是 qwen3:8b 模型对 Function Calling 的支持不够好,它没有正确解析工具描述和参数。

问题核心 :模型调用了错误的工具 cal,却传了 get_weather 的参数 city

这说明在 Agent 的复杂 prompt 场景 下,模型混淆了工具用途。解决方案是让工具的描述更加清晰、有区分度

建议:

  1. 优先换模型 - qwen3:8b 对 Function Calling 支持不好,建议换成qwen2.5:7b-instruct

  2. 改进工具描述 - 让描述更详细、更清晰

  3. 加强 prompt 引导 - 明确告诉模型如何使用工具

  4. 使用 ReAct Agent(不依赖 Function Calling)

    如果 Function Calling 不稳定,可以用 ReAct 模式,通过自然语言让模型调用工具。

解决方案一:强化工具描述
复制代码
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory


# ================== 工具定义(改进版)==================
@tool
def get_weather(city: str):
    """查询指定城市的天气情况。

    【适用场景】用户询问某地的天气、温度、阴晴等天气相关信息时使用。

    【参数说明】
    - city (必需): 城市名称字符串,例如:"北京"、"上海"、"广州"、"深圳"

    【使用示例】
    - 用户问:"北京今天天气怎么样?" → 调用 get_weather(city="北京")
    - 用户问:"上海冷吗?" → 调用 get_weather(city="上海")

    【注意】此工具只能查询天气,不能进行数学计算!
    """
    weather = {"北京": "晴天30度", "成都": "晴天32度", "上海": "多云25度", "广州": "小雨28度"}
    return weather.get(city.strip(), f"{city}的天气信息暂未收录")


@tool
def cal(expression: str):
    """计算数学表达式的值。

    【适用场景】用户需要进行数学计算、单位换算、数值运算时使用。

    【参数说明】
    - expression (必需): 数学表达式字符串
      - 支持的运算符:+ - * / ( )
      - 使用示例:"30 * 9 / 5 + 32"、"2 + 3 * 4"、"100 / 2.5"

    【使用示例】
    - 用户问:"摄氏30度转华氏度" → 调用 cal(expression="30 * 9 / 5 + 32")
    - 用户问:"2乘以3加4等于几" → 调用 cal(expression="2 * 3 + 4")

    【注意】此工具只能进行计算,不能查询天气信息!
    """
    try:
        result = eval(expression)
        return str(result)
    except Exception as e:
        return f"计算错误: {e}"


# ================== LLM 与 Agent ==================
model = ChatOllama(
    model="qwen3:8b",
    base_url="http://localhost:11434",
    temperature=0.2
)

tools = [get_weather, cal]

# ================== 改进后的 Prompt ==================
prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一个智能助手,可以调用工具回答问题。

    【可用工具列表】
    
    工具1:get_weather(天气查询)
    - 功能:查询城市天气
    - 参数:city(城市名称,如"北京")
    - 判断标准:用户提到"天气"、"温度"、"阴晴"等关键词
    
    工具2:cal(数学计算)
    - 功能:计算数学表达式
    - 参数:expression(表达式,如"30 * 9 / 5 + 32")
    - 判断标准:用户提到"计算"、"换算"、"等于多少"、"几度"等数学运算关键词
    
    【重要提醒】
    1. 查询天气 → 用 get_weather,参数是 city(城市名)
    2. 数学计算 → 用 cal,参数是 expression(表达式)
    3. 千万不要混淆这两个工具!
    4. 如果用户问"温度转华氏度",先查天气得到摄氏度,再用计算工具转换
    
    请利用对话历史理解上下文,准确选择工具和参数。"""),

    MessagesPlaceholder("chat_history"),
    ("human", "{input}"),
    MessagesPlaceholder("agent_scratchpad")
])

# ================== 创建 Agent ==================
agent = create_tool_calling_agent(model, tools, prompt)

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=5
)

# ================== 添加会话记忆 ==================
store = {}


def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]


agent_with_memory = RunnableWithMessageHistory(
    runnable=agent_executor,
    get_session_history=get_session_history,
    input_messages_key="input",
    history_messages_key="chat_history",
)

# ================== 测试 ==================
if __name__ == "__main__":
    session_id = "user_abc"

    print("=" * 60)
    print("测试1:查询天气")
    print("=" * 60)
    result0 = agent_with_memory.invoke(
        {"input": "北京天气如何?"},
        config={"configurable": {"session_id": session_id}}
    )
    print("\n回答:", result0["output"])

    print("\n" + "=" * 60)
    print("测试2:温度换算(依赖上一轮记忆)")
    print("=" * 60)
    result1 = agent_with_memory.invoke(
        {"input": "把那个温度转成华氏度"},
        config={"configurable": {"session_id": session_id}}
    )
    print("\n回答:", result1["output"])

    print("\n" + "=" * 60)
    print("测试3:直接计算")
    print("=" * 60)
    result2 = agent_with_memory.invoke(
        {"input": "计算 2 * 3 + 4 等于多少"},
        config={"configurable": {"session_id": session_id}}
    )
    print("\n回答:", result2["output"])

┌─────────────────────────────────────────────────────────┐
│  工具描述结构(改进后)                                  │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  【适用场景】← 告诉模型什么时候用                        │
│      用户询问某地的天气、温度、阴晴等...                 │
│                                                         │
│  【参数说明】← 告诉模型参数是什么                        │
│      - city (必需): 城市名称字符串                       │
│                                                         │
│  【使用示例】← 给出具体例子                              │
│      用户问:"北京今天天气怎么样?"                      │
│      → 调用 get_weather(city="北京")                     │
│                                                         │
│  【注意】← 明确区分边界                                  │
│      此工具只能查询天气,不能进行数学计算!               │
│                                                         │
└─────────────────────────────────────────────────────────┘

如果运行后仍然出错,可以尝试:

  1. 降低 temperature:设为 0,让模型更确定

    model = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434" , temperature=0)

  2. 打印详细的调用信息

    在 tools 列表后面添加

    for tool in tools:
    print(f"\n工具: {tool.name}")
    print(f"描述: {tool.description}\n")

  3. 添加返回格式约束(如果模型支持):

    from langchain_core.output_parsers import StrOutputParser

    agent = create_tool_calling_agent(model, tools, prompt)

解决方案二:使用 ReAct Agent(不依赖 Function Calling)
复制代码
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.prompts import PromptTemplate
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

# ================== 工具定义 ==================
@tool
def get_weather(city: str):
    """获取指定城市的天气。输入必须是城市名称(如 "北京")。"""
    weather = {"北京": "晴天30度", "成都": "晴天32度"}
    return weather.get(city.strip(), f"{city}天气未知")


@tool
def cal(expression: str):
    """计算数学表达式,例如 '30 * 9 / 5 + 32'。仅支持基本算术运算。"""
    try:
        result = eval(expression)
        return str(result)
    except Exception as e:
        return f"计算错误: {e}"


tools = [get_weather, cal]

# ReAct Prompt(用自然语言控制工具调用)
template = """你是一个智能助手,可以使用以下工具回答问题。

工具:
{tools}

工具名称:{tool_names}

请按照以下格式思考:

Question: 用户的问题
Thought: 你应该做什么来回答这个问题
Action: 要使用的工具名称,必须是 [{tool_names}] 之一
Action Input: 工具的参数
Observation: 工具返回的结果
... (可以重复 Thought/Action/Action Input/Observation)
Thought: 我现在知道最终答案了
Final Answer: 对原始问题的最终答案

开始!

Question: {input}
Thought: {agent_scratchpad}"""

prompt = PromptTemplate(
    template=template,
    input_variables=["input", "agent_scratchpad", "tools", "tool_names"]
)

model = ChatOllama(
    model="qwen3:8b",
    base_url="http://localhost:11434",
    temperature=0
)

# 使用 ReAct Agent
agent = create_react_agent(model, tools, prompt)

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=5
)

# 测试
if __name__ == "__main__":
    result = agent_executor.invoke({"input": "北京天气如何?"})
    print("\n回答:", result["output"])

二者对比:

复制代码
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

# ================== 工具定义 ==================
@tool
def get_weather(city: str):
    """获取指定城市的天气。输入必须是城市名称(如 "北京")。"""
    weather = {"北京": "晴天30度", "成都": "晴天32度"}
    return weather.get(city.strip(), f"{city}天气未知")


@tool
def cal(expression: str):
    """计算数学表达式,例如 '30 * 9 / 5 + 32'。仅支持基本算术运算。"""
    try:
        # 注意:eval 有安全风险,生产环境请用 simpleeval
        result = eval(expression)
        return str(result)
    except Exception as e:
        return f"计算错误: {e}"


# ================== LLM ==================
model = ChatOllama(
    model="qwen3:8b",
    base_url="http://localhost:11434",
    temperature=0.2
)

tools = [get_weather, cal]

# ================== ReAct Prompt(关键!)==================
react_prompt = PromptTemplate.from_template(
    """你是一个智能助手,必须严格按照以下格式进行推理和回答。

可用工具:
{tools}

工具名称:{tool_names}

回答必须使用以下格式(每行以关键词开头):
Question: 用户的问题
Thought: 你应该思考要做什么
Action: 要使用的工具,必须是 [{tool_names}] 中的一个
Action Input: 工具的输入(必须是纯值,不要包含任何额外文字)
Observation: 工具返回的结果
...(可以重复多次)
Thought: 我现在知道最终答案了
Final Answer: 对原始问题的最终答案

当前对话历史:
{chat_history}

开始!

Question: {input}
Thought: {agent_scratchpad}"""
)

# ================== 创建 Agent ==================
agent = create_react_agent(model, tools, react_prompt)

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=5,
    early_stopping_method="generate"
)

# ================== 添加记忆 ==================
store = {}

def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

agent_with_memory = RunnableWithMessageHistory(
    runnable=agent_executor,
    get_session_history=get_session_history,
    input_messages_key="input",
    history_messages_key="chat_history",  # 必须与 prompt 中的 {chat_history} 一致
)

# ================== 测试 ==================
if __name__ == "__main__":
    session_id = "user_abc"

    result = agent_with_memory.invoke(
        {"input": "北京天气如何?如果温度是30度,转成华氏度是多少?"},
        config={"configurable": {"session_id": session_id}}
    )
    print("\n最终答案:", result["output"])

from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

# ================== 工具 ==================
@tool
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b

tools = [multiply]

# ================== LLM ==================
llm = ChatOllama(
    model="qwen3:8b",
    base_url="http://localhost:11434",
    temperature=0.1
)

# ================== ReAct Prompt(中文友好)==================
template = """
你是一个数学助手,必须严格按照以下格式回答:

可用工具:
{tools}

工具名称:{tool_names}

格式要求:
Question: 用户的问题
Thought: 思考是否需要使用工具
Action: 工具名称(必须是 [{tool_names}] 之一)
Action Input: 工具输入(仅数字或表达式,不要解释)
Observation: 工具返回结果
...(可重复)
Thought: 我现在知道答案了
Final Answer: 最终答案

对话历史:
{chat_history}

开始!

Question: {input}
Thought: {agent_scratchpad}
"""

prompt = PromptTemplate.from_template(template)

# ================== 创建 Agent ==================
agent = create_react_agent(llm, tools, prompt)

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=5
)

# ================== 添加记忆 ==================
store = {}

def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

agent_with_memory = RunnableWithMessageHistory(
    runnable=agent_executor,
    get_session_history=get_session_history,
    input_messages_key="input",
    history_messages_key="chat_history"
)

# ================== 测试 ==================
if __name__ == "__main__":
    session_id = "user1"
    
    result = agent_with_memory.invoke(
        {"input": "355222 * 5521222 等于多少?"},
        config={"configurable": {"session_id": session_id}}
    )
    
    print("\n最终答案:", result["output"])
    
    # 查看记忆内容
    history = get_session_history(session_id)
    print("\n对话历史:")
    for msg in history.messages:
        print(f"  {type(msg).__name__}: {msg.content}")

示例四:initialize_agent, AgentType

复制代码
from langchain import memory
from langchain.globals import set_debug, set_verbose
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate, MessagesPlaceholder
from langchain.memory import ConversationBufferMemory
from langchain.agents import initialize_agent, AgentType

# # 启用调试模式
# # set_debug(True)
# # set_verbose(True)

llm = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434")

memory = ConversationBufferMemory(return_messages=True, memory_key="chat_history")


@tool
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b


agent = initialize_agent(
    tools=[multiply],
    llm=llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    handle_parsing_errors=True,  # 自动处理ai输出错误的格式
    agent_kwargs={
        # 自定义系统提示
        "system_message": "你是一个专业的旅游规划师,擅长为用户推荐旅游景点和制定行程计划。",

        # 插入历史对话
        "extra_prompt_messages": [
            MessagesPlaceholder(variable_name="chat_history")
        ],
    },
    memory=memory,
    max_iterations=5  # 限制react的步数
)

res = agent.invoke({"input": "355222*5521222等于多少"})
print(memory.load_memory_variables({}))
相关推荐
JaydenAI5 小时前
[拆解LangChain执行引擎] ManagedValue——一种特殊的只读虚拟通道
python·langchain
OPEN-Source6 小时前
大模型实战:搭建一张“看得懂”的大模型应用可观测看板
人工智能·python·langchain·rag·deepseek
一切尽在,你来8 小时前
1.4 LangChain 1.2.7 核心架构概览
人工智能·langchain·ai编程
一切尽在,你来8 小时前
1.3 环境搭建
人工智能·ai·langchain·ai编程
蛇皮划水怪15 小时前
深入浅出LangChain4J
java·langchain·llm
、BeYourself16 小时前
LangChain4j 流式响应
langchain
、BeYourself16 小时前
LangChain4j之Chat and Language
langchain
qfljg18 小时前
langchain usage
langchain
kjkdd1 天前
6.1 核心组件(Agent)
python·ai·语言模型·langchain·ai编程
渣渣苏1 天前
Langchain实战快速入门
人工智能·python·langchain