langchain react开发

react 开发跟普通agent区别
1 prompt不一样,
react的提示词

template = '''Answer the following questions as best you can. You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}'''

2 tools绑定逻辑不一样,

#需要根据`ReAct`模版的规范去绑定并且指定每一步的操作,如果遇到`\nObservation`便进 入下一轮的处理逻辑,直至完成最后一个子任务在输出最终的处理结果。
llm_with_stop = llm.bind(stop=["\nObservation"])

3 提示词处理有差异

示例代码

原生实现

import json
import os

import requests
from langchain_core.prompts import PromptTemplate
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

template = '''Answer the following questions as best you can. You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}'''

prompt = PromptTemplate.from_template(template)


open_weather_key = "5c939a7cc59eb8696f4cd77bf75c5a9a"

@tool
def get_weather(loc):
    """
    查询即时天气函数
    :param loc: 必要参数,字符串类型,用于表示查询天气的具体城市名称,\
    注意,中国的城市需要用对应城市的英文名称代替,例如如果需要查询上海市天气,则loc参数需要输入'ShangHai';
    :return:OpenWeather API查询即时天气的结果,具体URL请求地址为:https://api.openweathermap.org/data/2.5/weather\
    返回结果对象类型为解析之后的JSON格式对象,并用字符串形式进行表示,其中包含了全部重要的天气信息
    """
    # Step 1.构建请求
    url = "https://api.openweathermap.org/data/2.5/weather"
    print("get_weather loc=:",loc)

    # Step 2.设置查询参数
    params = {
        "q": loc,
        "appid": open_weather_key,  # 输入API key
        "units": "metric",  # 使用摄氏度而不是华氏度
        "lang": "zh_cn"  # 输出语言为简体中文
    }

    # Step 3.发送GET请求
    response = requests.get(url, params=params)

    # Step 4.解析响应
    data = response.json()
    resp =json.dumps(data)
    print("天气查询返回:",resp)
    return resp

# resp = get_weather("Beijing")


def create_llm() -> ChatOpenAI:
    """创建并返回配置好的大模型实例"""
    return ChatOpenAI(
        api_key=os.getenv("DASHSCOPE_API_KEY") or "your_api_key_here",
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        model="qwen2.5-math-72b-instruct",

    )


llm = create_llm()
weather_function_list = [get_weather]
# llm_with_tools = llm.bind_tools(weather_function_list)

from langchain.tools.render import render_text_description

prompt = prompt.partial(
    tools=render_text_description(list(weather_function_list)),
    tool_names=", ".join([t.name for t in weather_function_list]),
)

print(prompt)

from langchain_openai import ChatOpenAI

llm_with_stop = llm.bind(stop=["\nObservation"])#需要根据`ReAct`模版的规范去绑定并且指定每一步的操作,如果遇到`\nObservation`便进 入下一轮的处理逻辑,直至完成最后一个子任务在输出最终的处理结果。

from langchain.agents.output_parsers import ReActSingleInputOutputParser
from langchain.agents.format_scratchpad import format_log_to_str

output_parser = ReActSingleInputOutputParser()

agent = (
    {
        "input": lambda x: x["input"],
        "agent_scratchpad": lambda x: format_log_to_str(
            x["intermediate_steps"]
        ),
    }
    | prompt
    | llm_with_stop
    | output_parser
)

from langchain.agents import AgentExecutor

agent_executor = AgentExecutor(agent=agent, tools=weather_function_list, verbose=True)


def main():
    # 1. 获取用户输入
    user_input = ""
    while (True):
        user_input = input("请输入文本:")
        if (user_input == "exit"):
            print("程序结束")
            break
        # 2. 处理数据
        print(user_input)
        try:
            resp = agent_executor.invoke({"input": user_input})
            print(resp)
            ## TODO history 要追加到下次的聊天里面
        except json.JSONDecodeError:
            print("❌ 工具参数解析失败")
        except (AttributeError, ValueError) as e:
            print(f"❌ 工具调用错误: {str(e)}")
        except Exception as e:
            print(f"❌ 未知工具错误: {str(e)}")

if __name__ == "__main__":
    main()

基于langchain抽象API的实现


import json
import os

import requests
from langchain_core.prompts import PromptTemplate
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

template = '''Answer the following questions as best you can. You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}'''

prompt = PromptTemplate.from_template(template)


open_weather_key = "5c939a7cc59eb8696f4cd77bf75c5a9a"

@tool
def get_weather(loc):
    """
    查询即时天气函数
    :param loc: 必要参数,字符串类型,用于表示查询天气的具体城市名称,\
    注意,中国的城市需要用对应城市的英文名称代替,例如如果需要查询上海市天气,则loc参数需要输入'ShangHai';
    :return:OpenWeather API查询即时天气的结果,具体URL请求地址为:https://api.openweathermap.org/data/2.5/weather\
    返回结果对象类型为解析之后的JSON格式对象,并用字符串形式进行表示,其中包含了全部重要的天气信息
    """
    # Step 1.构建请求
    url = "https://api.openweathermap.org/data/2.5/weather"
    print("get_weather loc=:",loc)

    # Step 2.设置查询参数
    params = {
        "q": loc,
        "appid": open_weather_key,  # 输入API key
        "units": "metric",  # 使用摄氏度而不是华氏度
        "lang": "zh_cn"  # 输出语言为简体中文
    }

    # Step 3.发送GET请求
    response = requests.get(url, params=params)

    # Step 4.解析响应
    data = response.json()
    resp =json.dumps(data)
    print("天气查询返回:",resp)
    return resp

# resp = get_weather("Beijing")


def create_llm() -> ChatOpenAI:
    """创建并返回配置好的大模型实例"""
    return ChatOpenAI(
        api_key=os.getenv("DASHSCOPE_API_KEY") or "your_api_key_here",
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        model="qwen2.5-math-72b-instruct",

    )


llm = create_llm()
weather_function_list = [get_weather]
# llm_with_tools = llm.bind_tools(weather_function_list)

from langchain.tools.render import render_text_description

prompt = prompt.partial(
    tools=render_text_description(list(weather_function_list)),
    tool_names=", ".join([t.name for t in weather_function_list]),
)

print("prompt=",prompt)

from langchain_openai import ChatOpenAI

llm_with_stop = llm.bind(stop=["\nObservation"])#需要根据`ReAct`模版的规范去绑定并且指定每一步的操作,如果遇到`\nObservation`便进 入下一轮的处理逻辑,直至完成最后一个子任务在输出最终的处理结果。

from langchain.agents.output_parsers import ReActSingleInputOutputParser
from langchain.agents.format_scratchpad import format_log_to_str

output_parser = ReActSingleInputOutputParser()

agent = (
    {
        "input": lambda x: x["input"],
        "agent_scratchpad": lambda x: format_log_to_str(
            x["intermediate_steps"]
        ),
    }
    | prompt
    | llm_with_stop
    | output_parser
)

from langchain.agents import AgentExecutor

agent_executor = AgentExecutor(agent=agent, tools=weather_function_list, verbose=True)


def main():
    # 1. 获取用户输入
    user_input = ""
    while (True):
        user_input = input("请输入文本:")
        if (user_input == "exit"):
            print("程序结束")
            break
        # 2. 处理数据
        print(user_input)
        try:
            resp = agent_executor.invoke({"input": user_input})
            print(resp)
            ## TODO history 要追加到下次的聊天里面
        except json.JSONDecodeError:
            print("❌ 工具参数解析失败")
        except (AttributeError, ValueError) as e:
            print(f"❌ 工具调用错误: {str(e)}")
        except Exception as e:
            print(f"❌ 未知工具错误: {str(e)}")

if __name__ == "__main__":
    main()


posted @ 2025-04-04 20:35  向着朝阳  阅读(138)  评论(0)    收藏  举报