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({}))
相关推荐
樊小肆2 小时前
ollmam+langchain.js实现本地大模型简单记忆对话-内存版
前端·langchain·aigc
飞梦工作室3 小时前
Qwen-Agent 与 LangChain、AutoGPT 详细对比:技术架构、能力差异与选型指南
架构·langchain·ocr
北冥有一鲲19 小时前
LangChain.js:RAG 深度解析与全栈实践
开发语言·javascript·langchain
kimi-22221 小时前
LangChain 中少样本提示(Few-shot Prompting)
langchain
北冥有一鲲1 天前
LangChain.js:Tool、Memory 与 Agent 的深度解析与实战
开发语言·javascript·langchain
七夜zippoe1 天前
使用OpenLLM管理轻量级大模型服务
架构·langchain·大模型·kv·轻量
玖日大大2 天前
LangGraph 深度解析:构建强大智能体的新一代框架
人工智能·语言模型·架构·langchain
Tinero2 天前
LangChain 的核心概念与实现案例
langchain
Mr.朱鹏2 天前
大模型入门学习路径(Java开发者版)下
java·python·学习·微服务·langchain·大模型·llm