Agents安装与使用--例子

 什么是Agents ?

Agents 是一个具有智能功能的智能体,它使用 LLM 和工具来执行任务

Agents 核心思想是使用LLM来选择要采取的一系列动作。在链式结构中,一系列动作是硬编码的(在代码中)。 在 Agents 中,使用语言模型作为推理引擎来确定要采取的动作及其顺序。

Agents 包括几个关键组件:

- **Agent**: 用于生成指令和执行动作的代理。

- **Tool**: 用于执行动作的函数。

- **Memory**: 用于存储历史对话和生成的指令。

- **LLM**: 用于生成指令和执行动作的 LLM。

第一个例子

搭建工具

- serpai是一个聚合搜索引擎,需要安装谷歌搜索包以及申请账号 https://serpapi.com/manage-api-key

- llm-math是一个封装好的数学计算链

pip install google-search-results

# 导入os模块,用于设置环境变量

import os

# 设置环境变量SERPAPI_API_KEY,用于配置SERPAPI的API密钥

# 这是访问SERPAPI服务所必需的,通过环境变量管理密钥可以提高安全性 
os.environ["SERPAPI_API_KEY"] = 'apl_key'

# 导入Tongyi类,用于后续的语言模型操作
from langchain_community.llms.tongyi import Tongyi

# 初始化Tongyi语言模型实例
# 这里没有对Tongyi类的具体功能进行注释,因为注释应该专注于代码的意图,而不是实现细节。
# Tongyi类的具体功能和用途应在更高级别的文档或说明中描述。
llm = Tongyi()
# 导入加载工具和初始化代理的函数,以及代理类型的枚举
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType

# 加载特定的工具,为后续的代理初始化准备必要的资源
# 这里加载了"serpapi"和"llm-math"两个工具,其中"llm"可能是为语言模型提供的一个接口或配置
tools = load_tools(["serpapi","llm-math"], llm=llm)

# 初始化代理,配置其为零样本响应描述类型,并设置为verbose模式
# 这里的AgentType.ZERO_SHOT_REACT_DESCRIPTION指定了代理的行为类型,即零样本响应描述
# verbose=True使得代理在执行过程中输出更多的调试信息
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,#这里有不同的类型
    verbose=True,#是否打印日志
)
# 调用低层模型(LLM)进行文本生成
llm.invoke("请问2024年的美国总统是谁?他的年龄的除以2是多少?")



# 运行代理程序,针对特定问题进行解答
agent.run("请问现任的美国总统是谁?他的年龄的除以2是多少?")

输出示例:'现任美国总统是乔·拜登(Joe Biden),他的年龄除以2是40.5。'

Agents 的类型

- ZERO_SHOT_REACT_DESCRIPTION                   零样本反应描述

- CHAT_ZERO_SHOT_REACT_DESCRIPTION              聊天零样本反应描述

- CONVERSATIONAL_REACT_DESCRIPTION              会话反应描述

- CHAT_CONVERSATIONAL_REACT_DESCRIPTION         聊天会话反应描述

- STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION   聊天结构化零样本反应描述

- STRUCTURED_ZERO_SHOT_REACT_DESCRIPTION        结构化零样本反应描述

ZERO_SHOT_REACT_DESCRIPTION    即在没有示例的情况下可以自主的进行对话的类型。
# 定义tools
tools = load_tools(["serpapi","llm-math"],llm=llm)

# 定义agent--(tools、agent、llm、memory)
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
)

print(agent)
print("------------------------")
print(agent.agent.llm_chain.prompt.template)

#agent.invoke("现在美国总统是谁?他的年龄除以2是多少?")
CHAT_ZERO_SHOT_REACT_DESCRIPTION   零样本增强式生成,即在没有示例的情况下可以自主的进行对话的类型。
tools = load_tools(["serpapi","llm-math"],llm=llm)
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
)
print(agent)
print("------------------------")
print(agent.agent.llm_chain.prompt.messages[0].prompt.template)
print("------------------------")
agent.invoke("现在美国总统是谁?他的年龄除以2是多少?")

输出结果:{'input': '现在美国总统是谁?他的年龄除以2是多少?', 'output': '现任美国总统是乔·拜登,他的年龄除以2是40.5岁。'}

CONVERSATIONAL_REACT_DESCRIPTION   一个对话型的agent,这个agent要求与memory一起使用
from langchain.memory import ConversationBufferMemory
#记忆组件
memory = ConversationBufferMemory(
    memory_key="chat_history",
)

# 定义tool
tools = load_tools(["serpapi","llm-math"],llm=llm)

# 定义agent
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory,#记忆组件
    verbose=True,
)
print(agent)
print(agent.agent.llm_chain.prompt.template)

agent.run("我是张三,今年18岁,性别女,现在在深圳工作,工作年限1年,月薪5000元")

agent.run("我的名字是什么?")

agent.run("有什么好吃的泰国菜可以推荐给我吗?")

agent.run("这些我都没吃过!我名字的最后一个字母是什么?1998年的世界杯谁夺冠了?")

agent.run("中国陕西西安现在的气温多少?截止目前我们聊了什么?")

输出结果:

'你好,张三。你是一名18岁的女性,在深圳工作,已经有一年的工作经验,目前的月薪是5000元。如果你有任何问题或需要进一步的建议,请随时告诉我。'

输出结果:'你的名字是张三。'

输出结果:'当然,这里有一些推荐的泰国菜供你尝试:\n\n1. 青木瓜沙拉 (Som Tam) - 这是一道清爽的沙拉,通常由未成熟的木瓜、辣椒、蒜、青柠檬、鱼露和花生混合制成。\n2. 泰式炒河粉 (Pad Thai) - 这是泰国最著名的菜肴之一,由米粉、蔬菜、鸡蛋、虾或鸡肉以及甜、酸、咸的酱汁炒制而成。\n3. 冬阴功汤 (Tom Yum Goong) - 这是一道酸辣海鲜汤,含有柠檬草、香茅、辣椒、大蒜和 shrimp,口感鲜美。\n4. 泰式椰奶鸡汤 (Khao Soi) - 这是一种咖喱面条汤,通常配有炸过的面条、鸡肉或牛肉,以及浓郁的椰奶为基础的汤底。\n5. 红咖喱 (Gaeng Daeng) - 一道辣味浓郁的菜肴,通常与肉类(如鸡肉、牛肉或猪肉)和蔬菜一起烹饪。\n6. 烤肉串 (Moo Ping) - 猪肉串,腌制后在炭火上烤制,味道甜美且多汁。\n7. 椰香糯米饭 (Kao Niew Ma Muang) - 与芒果一起食用的糯米,是泰国甜点的经典选择。\n\n这些都是非常受欢迎的泰国菜,你可以根据自己的口味选择尝试。希望你会喜欢!'

输出结果:'你名字的最后一个字母是“三”。1998年的世界杯,法国国家足球队夺得了冠军。'

输出结果:'目前中国陕西西安的气温是98华氏度,天气情况是大部分晴朗。我们聊天的内容包括你叫张三,18岁,女性,目前在深圳工作,有1年工作经验,月薪5000元,你喜欢的泰国菜,以及1998年世界杯的冠军是法国队。'

CHAT_CONVERSATIONAL_REACT_DESCRIPTION   使用了chatmodel
from langchain.memory import ConversationBufferMemory
#记忆组件
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True,
)

tools = load_tools(["serpapi","llm-math"],llm=llm)


agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory,#记忆组件
    verbose=True,
)
print(agent)
print("1 ------------------------")
print(len(agent.agent.llm_chain.prompt.messages))
print("2 ------------------------")
print(agent.agent.llm_chain.prompt.messages[0].prompt.template)
print("3 ------------------------")
print(agent.agent.llm_chain.prompt.messages[1])
print("4 ------------------------")
print(agent.agent.llm_chain.prompt.messages[2].prompt.template)
print("5 ------------------------")
print(agent.agent.llm_chain.prompt.messages[3])


agent.run("有什么好吃的泰国菜可以推荐给我吗?用中文回答")

输出结果:'泰国菜有很多美味的选项可以推荐。例如,泰式绿咖喱(Green Curry)是一道经典的菜肴,由嫩鸡块、椰奶和绿色咖喱酱制成,口味辛辣中带有香草和柠檬叶的香气。另一道不容错过的菜品是 pad Thai(泰式炒河粉),它混合了炒米粉、豆芽、胡萝卜、鸡肉或虾,并通常搭配花生碎和酸橙汁调味。还有泰式冬阴功汤(Tom Yum Soup),这是一道酸辣口味的汤,含有柠檬草、辣椒、虾和香茅,味道非常开胃。尝试这些菜品,你一定会喜欢上泰国美食的!'

STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION    对输出做了结构化处理
from langchain.memory import ConversationBufferMemory
#记忆组件
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True,
)

## 定义tool
tools = load_tools(["serpapi","llm-math"],llm=llm)

# 定义agent
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, #agent类型 
    memory=memory,#记忆组件
    handle_parsing_errors=True,
    verbose=True,
)
print(agent)
print(agent.agent.llm_chain.prompt.messages[0].prompt.template)
print(agent.agent.llm_chain.prompt.messages[1].prompt.template)

agent.run("有什么好吃的泰国菜可以推荐给我吗?用中文回答")

输出结果:'泰国菜有很多美味的选择,以下是一些推荐:\n1. 冬阴功汤 (Tom Yum Soup) - 酸辣口味,带有柠檬草和香茅的味道。\n2. 红咖喱鸡 (Gaeng Daeng Gai) - 辣味浓郁的红咖喱与鸡肉和蔬菜搭配。\n3. 泰式炒河粉 (Pad Thai) - 炒米粉配上豆芽、花生、鸡蛋和蔬菜,可选鸡肉、虾或豆腐。\n4. 香芒糯米饭 (Mango Sticky Rice) - 甜点,由糯米、芒果和椰奶组成。\n5. 椰奶鸡汤 (Tom Kha Gai) - 鸡肉和椰奶为基础的汤,口感醇厚且微辣。\n\n尝试这些菜品,你会享受到泰国美食的美妙滋味!'

Tools

langchain预制了大量的tools,基本这些工具能满足大部分需求。 https://python.langchain.com.cn/docs/modules/agents/tools/

- 加载预制tool的方法

- 几种tool的使用方式

#添加预制工具的方法很简单
from langchain.agents import load_tools
tool_names = [...]
tools = load_tools(tool_names) #使用load方法
#有些tool需要单独设置llm
from langchain.agents import load_tools
tool_names = [...]
llm = ...
tools = load_tools(tool_names, llm=llm) #在load的时候指定llm
SerpAPI    最常见的聚合搜索引擎

https://serper.dev/dashboard,支持google\bing

from langchain.utilities import SerpAPIWrapper

search = SerpAPIWrapper()

search.run("美国现在的总统是谁?")


# 支持自定义参数,比如将引擎切换到bing,设置搜索语言等
params = {
    "engine": "bing",
    "gl": "us",
    "hl": "en",
}
search = SerpAPIWrapper(params=params)
search.run("美国现在的总统是谁?")
Dall-E    openai出品的文到图AI大模型

Eleven Labs Text2Speech

ElevenLabs 是非常优秀的TTS合成API

```

pip install elevenlabs

pip install --upgrade pydantic

```

import os

os.environ["ELEVEN_API_KEY"] = "23261e4a3b79697822252a505a169863"
from langchain.tools import ElevenLabsText2SpeechTool

text_to_speak = "Hello! 你好! Hola! नमस्ते! Bonjour! こんにちは! مرحبا! 안녕하세요! Ciao! Cześć! Привіт! வணக்கம்!"

tts = ElevenLabsText2SpeechTool(
    voice="Bella",
    text_to_speak=text_to_speak,
    verbose=True
)
tts.name

speech_file = tts.run(text_to_speak)

speech_file = tts.run(text_to_speak)

tts.stream_speech(text_to_speak)
GraphQL    一种api查询语言,

GraphQL 一种api查询语言,类似sql,我们用它来查询奈飞的数据库,查找一下和星球大战相关的电影,API地址https://swapi-graphql.netlify.app/.netlify/functions/index

```

pip install httpx gql > /dev/null

pip install gql

pip install requests_toolbelt

```

### from langchain.chat_models import ChatOpenAI
from langchain.agents import load_tools, initialize_agent, AgentType
from langchain.utilities import GraphQLAPIWrapper

llm = ChatOpenAI(
    temperature=0,
    model="gpt-4",
    )

tools = load_tools(
    ["graphql"],
    graphql_endpoint="https://swapi-graphql.netlify.app/.netlify/functions/index",
)

agent = initialize_agent(
    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)

Tookit   

tookit是langchain已经封装好的一系列工具,一个工具包是一组工具来组合完成特定的任务

python

一个python代码机器人

 pip install langchain_experimental

from langchain_experimental.agents.agent_toolkits import create_python_agent
from langchain_experimental.tools import PythonREPLTool
from langchain_experimental.utilities import PythonREPL
from langchain.llms.openai import OpenAI
from langchain.agents.agent_types import AgentType
from langchain.chat_models import ChatOpenAI

agent_executor = create_python_agent(
    llm=ChatOpenAI(temperature=0, model="gpt-4-1106-preview"),
    tool=PythonREPLTool(),
    verbose=True,
    agent_type=AgentType.OPENAI_FUNCTIONS,
    agent_executor_kwargs={"handle_parsing_errors": True},
)

agent_executor.run("What is the 10th fibonacci number?")
SQL Database

使用SQLDatabaseChain构建的agent,用来根据数据库回答一般行动饿问题

from langchain.agents import create_sql_agent
from langchain.agents.agent_toolkits import SQLDatabaseToolkit
from langchain.sql_database import SQLDatabase
from langchain.llms.openai import OpenAI
from langchain.agents import AgentExecutor
from langchain.agents.agent_types import AgentType
from langchain.chat_models import ChatOpenAI

db = SQLDatabase.from_uri("sqlite:///Chinook.db")
toolkit = SQLDatabaseToolkit(db=db, llm=OpenAI(temperature=0))

agent_executor = create_sql_agent(
    llm=ChatOpenAI(temperature=0, model="gpt-4-1106-preview"),
    toolkit=toolkit,
    verbose=True,
    agent_type=AgentType.OPENAI_FUNCTIONS
)

agent_executor.run("Describe the playlisttrack table")
自定义Agent

- 定义一个class

- 工具:默认搜索

- 提示词:定义agent要做什么任务

- outparse:约束LLM的行为和输出

- 不同的LLM不同的质量

from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser
from langchain.prompts import StringPromptTemplate
from langchain import SerpAPIWrapper, LLMChain
from typing import List, Union
from langchain.schema import AgentAction, AgentFinish, OutputParserException
from langchain_community.llms.tongyi import Tongyi
import re
import os

class MyAgentTool:
    def __init__(self) -> None:
        os.environ["SERPAPI_API_KEY"] = "f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594"
        self.serpapi = SerpAPIWrapper()
        
    def tools(self):
        return [
            Tool(
                name="search",
                description="适用于当你需要回答关于当前事件的问题时",
                func=self.serpapi.run,
            )
        ]
s = MyAgentTool()
s.serpapi.run("python")
    

构建一个agents类

from typing import Any


class MyAgent:
    def __init__(self) -> None:
        #agent的提示词,用来描述agent的功能
        self.template =  """尽你最大可能回答下面问题,你将始终用中文回答. 你在必要时可以使用下面这些工具:
                    {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}
                    {agent_scratchpad}"""
        #定义一个openai的llm
        self.llm = Tongyi()
        #工具列表
        self.tools = self.MyAgentTool().tools()
        #agent的prompt
        self.prompt = self.MyTemplate(
            template=self.template,
            tools=self.tools,
            #输入变量和中间变量
            input_variables=["input", "intermediate_steps"],
        )

        #定义一个LLMChain
        self.llm_chain = LLMChain(
            llm=self.llm,
            prompt = self.prompt
        )
        #工具名称列表
        self.toolnames = [tool.name for tool in self.tools]
        #定义一个agent
        self.agent = LLMSingleActionAgent(
            llm_chain=self.llm_chain,
            allowed_tools=self.toolnames,
            output_parser=self.MyOutputParser(),
            
            stop=["\nObservation:"],
        )
    
    #运行agent
    def run(self, input: str) -> str:
        #创建一个agent执行器
        agent_executor = AgentExecutor.from_agent_and_tools(
            agent=self.agent, 
            tools=self.tools, 
            handle_parsing_errors=True,
            verbose=True
        )
        agent_executor.run(input=input)

    #自定义工具类
    class MyAgentTool:
        def __init__(self) -> None:
            os.environ["SERPAPI_API_KEY"] = "f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594"
            self.serpapi = SerpAPIWrapper()
            
        def tools(self):
            return [
                Tool(
                    name="search",
                    description="适用于当你需要回答关于当前事件的问题时",
                    func=self.serpapi.run,
                )
            ]
    

    #自定义模版渲染类
    class MyTemplate(StringPromptTemplate):
        #渲染模版
        template: str
        #需要用到的工具
        tools:List[Tool]

        #格式化函数
        def format(self, **kwargs: Any) -> str:
            #获取中间步骤
            intermediate_steps = kwargs.pop("intermediate_steps")
            thoughts = ""
            for action, observation in intermediate_steps:
                thoughts += action.log
                thoughts += f"\nObservation: {observation}\nThought: "
            #将agent_scratchpad设置为该值
            kwargs["agent_scratchpad"] = thoughts
            # 从提供的工具列表中创建一个名为tools的变量
            kwargs["tools"] = "\n".join([f"{tool.name}: {tool.description}" for tool in self.tools])
            #创建一个提供的工具名称列表
            kwargs["tool_names"] = ", ".join([tool.name for tool in self.tools])
            return self.template.format(**kwargs)


    #自定义输出解析类
    class MyOutputParser(AgentOutputParser):
        #解析函数
        def parse(self, output: str) -> Union[AgentAction, AgentFinish]:
            #检查agent是否应该完成
            if "Final Answer:" in output:
                return AgentFinish(
                # 返回值通常始终是一个具有单个 `output` 键的字典。
                # It is not recommended to try anything else at the moment :)
                return_values={"output": output.split("Final Answer:")[-1].strip()},
                log=output,
                )
            #用正则解析出动作和动作输入
            regex = r"Action\s*\d*\s*:(.*?)\nAction\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)"
            match = re.search(regex, output, re.DOTALL)
            #如果没有匹配到则抛出异常
            if not match:
                raise OutputParserException(f"Could not parse LLM output: `{output}`")
            action = match.group(1).strip()
            action_input = match.group(2)
            # 返回操作和操作输入
            return AgentAction(tool=action, tool_input=action_input.strip(" ").strip('"'), log=output)
myagent = MyAgent()
myagent.run("比特币现在多少钱了?预计未来会涨吗?")

 

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值