使用langchain构建一个agent

代码如下:

故意给LLM提供一个没有用的工具,看看LLM如何处理

from langchain.agents import create_react_agent
from langchain.agents import AgentExecutor
from langchain_core.prompts import PromptTemplate


# 打印LLM接收到的prompt
from langchain.callbacks.base import BaseCallbackHandler
from typing import List
class PromptPrinter(BaseCallbackHandler):
    def on_llm_new_token(self, token: str, **kwargs) -> None:
        pass  # 不需要这个
    
    def on_llm_start(self, serialized: dict, prompts: List[str], **kwargs) -> None:
        print("\nLLM 接收到的 prompt:")
        for prompt in prompts:
            print(prompt)
        print("---------------end prompt-----------------")
# 初始化 LLM
from langchain_community.llms import Tongyi
import os
DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY")
llm = Tongyi(model_name="qwen-turbo-latest", dashscope_api_key=DASHSCOPE_API_KEY,callbacks=[PromptPrinter()])

# 自定义工具1:文本分析工具
class TextAnalysisTool:
    """文本分析工具,用于分析文本内容"""
    
    def __init__(self):
        self.name = "文本分析"
        self.description = "分析文本内容,提取字数、字符数和情感倾向"
    
    def run(self, text: str) -> str:
        """分析文本内容
        
        参数:
            text: 要分析的文本
        返回:
            分析结果
        """
        # 简单的文本分析示例
        word_count = len(text.split())
        char_count = len(text)
        
        # 简单的情感分析(示例)
        positive_words = ["好", "优秀", "喜欢", "快乐", "成功", "美好"]
        negative_words = ["差", "糟糕", "讨厌", "悲伤", "失败", "痛苦"]
        
        positive_count = sum(1 for word in positive_words if word in text)
        negative_count = sum(1 for word in negative_words if word in text)
        
        sentiment = "积极" if positive_count > negative_count else "消极" if negative_count > positive_count else "中性"
        
        return f"文本分析结果:\n- 字数: {word_count}\n- 字符数: {char_count}\n- 情感倾向: {sentiment}"

text_analysis = TextAnalysisTool()

# 创建工具列表
from langchain.agents import Tool 
tools = [Tool(
            name=text_analysis.name,
            func=text_analysis.run,
            description="分析文本内容,提取字数、字符数和情感倾向"
        )]
    


react_template = """回答以下问题:{input}
    你有这些工具可用,不要使用其他工具:
    {tools}

    工具名称列表: {tool_names}

    使用以下格式:
    Thought: 你应该思考如何解决这个问题
    Action: 工具名称
    Action Input: 工具的输入参数
    Observation: 工具的输出结果
    Final Answer: 最终答案

    {agent_scratchpad}"""

# 创建PromptTemplate实例时传递正确的变量
react_prompt = PromptTemplate(
        input_variables=['input', 'tools', 'tool_names', 'agent_scratchpad'],
        template=react_template
    )


# 创建ReAct agent
react_agent = create_react_agent(llm, tools, react_prompt)

agent_executor = AgentExecutor(agent=react_agent, tools=tools,
     verbose=True, handle_parsing_errors=True, max_iterations=3,
      tool_input_fixers=[])

result1 = agent_executor.invoke({
        "input": "我想了解一些北欧神话中的女孩名字,能帮我搜索相关信息,存储到rag向量库,然后给出回答吗?"
    })
print("结果:", result1["output"])

打印信息

$ python 003.py 

> Entering new AgentExecutor chain...

LLM 接收到的 prompt:
回答以下问题:我想了解一些北欧神话中的女孩名字,能帮我搜索相关信息,存储到rag向量库,然后给出回答吗?
    你有这些工具可用,不要使用其他工具:
    文本分析(text: str) -> str - 分析文本内容,提取字数、字符数和情感倾向

    工具名称列表: 文本分析

    使用以下格式:
    Thought: 你应该思考如何解决这个问题
    Action: 工具名称
    Action Input: 工具的输入参数
    Observation: 工具的输出结果
    Final Answer: 最终答案

---------------end prompt-----------------
Thought: 我需要搜索北欧神话中的女孩名字,但由于我只能使用“文本分析”工具,我无法直接搜索信息。不过,我可以提供一些已知的北欧神话中的女孩名字,并使用“文本分析”工具来处理这些名字的信息。

Action: 文本分析
Action Input: "以下是一些北欧神话中的女孩名字:芙蕾亚(Freya)、西芙(Sif)、伊敦(Idun)、格琳德(Grid)、瓦尔特里(Valkyrie)、赫伦雅(Hel)。"
文本分析结果:
- 字数: 1
- 字符数: 80
- 情感倾向: 中性
LLM 接收到的 prompt:
回答以下问题:我想了解一些北欧神话中的女孩名字,能帮我搜索相关信息,存储到rag向量库,然后给出回答吗?
    你有这些工具可用,不要使用其他工具:
    文本分析(text: str) -> str - 分析文本内容,提取字数、字符数和情感倾向

    工具名称列表: 文本分析

    使用以下格式:
    Thought: 你应该思考如何解决这个问题
    Action: 工具名称
    Action Input: 工具的输入参数
    Observation: 工具的输出结果
    Final Answer: 最终答案

    Thought: 我需要搜索北欧神话中的女孩名字,但由于我只能使用“文本分析”工具,我无法直接搜索信息。不过,我可以提供一些已知的北欧神话中的女孩名字,并使用“文本分 析”工具来处理这些名字的信息。

Action: 文本分析
Action Input: "以下是一些北欧神话中的女孩名字:芙蕾亚(Freya)、西芙(Sif)、伊敦(Idun)、格琳德(Grid)、瓦尔特里(Valkyrie)、赫伦雅(Hel)。"

Observation: 文本分析结果:
- 字数: 1
- 字符数: 80
- 情感倾向: 中性
Thought:
---------------end prompt-----------------
虽然文本分析工具没有提供关于名字的具体信息,但它确认了提供的名字列表是中性的,且符合北欧神话的主题。

Final Answer: 以下是一些北欧神话中的女孩名字:芙蕾亚(Freya)、西芙(Sif)、伊敦(Idun)、格琳德(Grid)、瓦尔特里(Valkyrie,这是瓦尔基里的通用名称,并非特定 人物的名字)、赫伦雅(Hel)。这些名字在北欧神话中具有重要意义,代表了不同的女神和角色。

> Finished chain.
结果: 以下是一些北欧神话中的女孩名字:芙蕾亚(Freya)、西芙(Sif)、伊敦(Idun)、格琳德(Grid)、瓦尔特里(Valkyrie,这是瓦尔基里的通用名称,并非特定人物的名 字)、赫伦雅(Hel)。这些名字在北欧神话中具有重要意义,代表了不同的女神和角色。

### 使用LangChain创建自定义工具Agent #### 准备工作梳理 为了构建能够执行特定任务(如SQL查询)的自定义Agent,需先安装并导入必要的Python库。这通常涉及`langchain`及其依赖项以及其他可能用于数据处理或API调用的相关模块[^1]。 ```bash pip install langchain sqlalchemy pandas ``` 接着,在编写具体逻辑前,应明确定义目标——即希望此Agent完成的任务是什么?对于本案例而言,则是要实现一个能与SQL数据库对话的功能性组件。 #### 定义自定义Tool类 基于上述需求分析,下面展示了一个简单的名为`SqlExecutor`的自定义Tool类的设计: ```python from typing import Dict, Any import pandas as pd from sqlalchemy import create_engine class SqlExecutor: """A tool that executes SQL queries against a database.""" def __init__(self, connection_string: str): self.engine = create_engine(connection_string) def run(self, query: str) -> pd.DataFrame: with self.engine.connect() as conn: result = conn.execute(query) columns = result.keys() rows = result.fetchall() return pd.DataFrame(rows, columns=columns) ``` 这里通过继承实现了基本接口方法`run()`,它接受一条SQL语句作为参数,并返回由Pandas DataFrame表示的结果集。此外还初始化了连接到指定数据库所需的引擎对象。 #### 实例化Tools并将其实例加入列表 一旦完成了对各个独立功能单元(即不同类型的Tool)的设计之后,就可以按照如下方式将其实例化并收集起来形成集合形式供后续操作使用[^2]: ```python sql_executor = SqlExecutor('sqlite:///example.db') tools = [sql_executor] ``` 此处假设已经存在一个SQLite数据库文件位于当前目录下命名为`example.db`;当然也可以替换为其他支持的数据源路径表达式以适应不同的应用场景。 #### 配置Action Schema 为了让代理更好地理解如何利用这些工具所提供的能力去解决问题,可以通过设置action schema的方式让其知道每个动作应该接收什么样的输入格式以及预期产生的输出结构。例如针对前面提到过的`SqlExecutor.run()`函数来说,就应当告知系统该方法期望获取的是字符串类型的SQL命令文本[^3]。 ```json { "type": "object", "properties": { "query": {"type": "string"} }, "required": ["query"] } ``` 最后一步就是将以上准备好的所有要素组合在一起构成完整的Agent解决方案啦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值