LangChain手册(Python版)24模块:Agent代理

代理使用 LLM 来确定采取哪些行动以及采取何种顺序。动作可以是使用工具并观察其输出,也可以是返回给用户。

如果使用得当,代理可以非常强大。本笔记本的目的是向您展示如何通过最简单、最高级别的 API 轻松使用代理。

为了加载代理,您应该了解以下概念:

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI

首先,让我们加载我们要用来控制代理的语言模型。

llm = OpenAI(temperature=0)

接下来,让我们加载一些工具来使用。请注意,该llm-math工具使用 LLM,因此我们需要将其传入。

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

最后,让我们使用工具、语言模型和我们要使用的代理类型来初始化代理。

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

现在让我们测试一下!

agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")
> Entering new AgentExecutor chain...
 I need to find out who Leo DiCaprio's girlfriend is and then calculate her age raised to the 0.43 power.
Action: Search
Action Input: "Leo DiCaprio girlfriend"
Observation: Camila Morrone
Thought: I need to find out Camila Morrone's age
Action: Search
Action Input: "Camila Morrone age"
Observation: 25 years
Thought: I need to calculate 25 raised to the 0.43 power
Action: Calculator
Action Input: 25^0.43
Observation: Answer: 3.991298452658078

Thought: I now know the final answer
Final Answer: Camila Morrone is Leo DiCaprio's girlfriend and her current age raised to the 0.43 power is 3.991298452658078.

> Finished chain.
"Camila Morrone is Leo DiCaprio's girlfriend and her current age raised to the 0.43 power is 3.991298452658078."

工具

工具是代理可以用来与外界交互的方式。

接下来,我们有一些自定义和通用使用工具的示例

在本文档中,我们介绍了通用工具功能(例如,如何创建您自己的工具)以及工具示例以及如何使用它们。

开始

工具是代理可以用来与世界交互的功能。这些工具可以是通用实用程序(例如搜索)、其他链,甚至是其他代理。

目前,可以使用以下代码片段加载工具:

from langchain.agents import load_tools
tool_names = [...]
tools = load_tools(tool_names)

一些工具(例如链、代理)可能需要一个基础 LLM 来初始化它们。在这种情况下,您也可以传入 LLM:

from langchain.agents import load_tools
tool_names = [...]
llm = ...
tools = load_tools(tool_names, llm=llm)

以下是所有支持的工具和相关信息的列表:

工具清单

python_repl

serpapi

wolfram-alpha

requests

terminal

pal-math

pal-colored-objects

llm-math

open-meteo-api

news-api

tmdb-api

google-search

searx-search

google-serper

wikipedia

podcast-api

openweathermap-api

定义自定义工具

在构建您自己的代理时,您需要为其提供一个它可以使用的工具列表。除了调用的实际函数外,该工具还包含几个组件:

定义工具有两种主要方法,我们将在下面的示例中介绍这两种方法。

# Import things that are needed generically
from langchain import LLMMathChain, SerpAPIWrapper
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.tools import BaseTool, StructuredTool, Tool, tool

初始化 LLM 以供代理使用。

llm = ChatOpenAI(temperature=0)

全新工具 - 字符串输入和输出

最简单的工具接受单个查询字符串并返回字符串输出。如果您的工具函数需要多个参数,您可能想跳到StructuredTool下面的部分。

有两种方法可以做到这一点:通过使用 Tool 数据类,或者通过子类化 BaseTool 类。

工具数据类

“工具”数据类包装接受单个字符串输入并返回字符串输出的函数。

# Load the tool configs that are needed.
search = SerpAPIWrapper()
llm_math_chain = LLMMathChain(llm=llm, verbose=True)
tools = [
    Tool.from_function(
        func=search.run,
        name = "Search",
        description="useful for when you need to answer questions about current events"
        # coroutine= ... <- you can specify an async method if desired as well
    ),
]
/Users/wfh/code/lc/lckg/langchain/chains/llm_math/base.py:50: UserWarning: Directly instantiating an LLMMathChain with an llm is deprecated. Please instantiate with llm_chain argument or using the from_llm class method.
  warnings.warn(

您还可以定义自定义“args_schema”以提供有关输入的更多信息。

from pydantic import BaseModel, Field

class CalculatorInput(BaseModel):
    question: str = Field()
        

tools.append(
    Tool.from_function(
        func=llm_math_chain.run,
        name="Calculator",
        description="useful for when you need to answer questions about math",
        args_schema=CalculatorInput
        # coroutine= ... <- you can specify an async method if desired as well
    )
)
# Construct the agent. We will use the default agent type here.
# See documentation for a full list of options.
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")
> Entering new AgentExecutor chain...
I need to find out Leo DiCaprio's girlfriend's name and her age
Action: Search
Action Input: "Leo DiCaprio girlfriend"
Observation: After rumours of a romance with Gigi Hadid, the Oscar winner has seemingly moved on. First being linked to the television personality in September 2022, it appears as if his "age bracket" has moved up. This follows his rumoured relationship with mere 19-year-old Eden Polani.
Thought:I still need to find out his current girlfriend's name and age
Action: Search
Action Input: "Leo DiCaprio current girlfriend"
Observation: Just Jared on Instagram: “Leonardo DiCaprio & girlfriend Camila Morrone couple up for a lunch date!
Thought:Now that I know his girlfriend's name is Camila Morrone, I need to find her current age
Action: Search
Action Input: "Camila Morrone age"
Observation: 25 years
Thought:Now that I have her age, I need to calculate her age raised to the 0.43 power
Action: Calculator
Action Input: 25^(0.43)

> Entering new LLMMathChain chain...
25^(0.43)```text
25**(0.43)
```
...numexpr.evaluate("25**(0.43)")...

Answer: 3.991298452658078
> Finished chain.

Observation: Answer: 3.991298452658078
Thought:I now know the final answer
Final Answer: Camila Morrone's current age raised to the 0.43 power is approximately 3.99.

> Finished chain.
"Camila Morrone's current age raised to the 0.43 power is approximately 3.99."

子类化 BaseTool 类

你也可以直接子类化BaseTool。如果您想要更多地控制实例变量,或者如果您想要将回调传播到嵌套链或其他工具,这将很有用。

from typing import Optional, Type

from langchain.callbacks.manager import AsyncCallbackManagerForToolRun, CallbackManagerForToolRun

class CustomSearchTool(BaseTool):
    name = "custom_search"
    description = "useful for when you need to answer questions about current events"

    def _run(self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None) -> str:
        """Use the tool."""
        return search.run(query)
    
    async def _arun(self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None) -> str:
        """Use the tool asynchronously."""
        raise NotImplementedError("custom_search does not support async")
    
class CustomCalculatorTool(BaseTool):
    name = "Calculator"
    description = "useful for when you need to answer questions about math"
    args_schema: Type[BaseModel] = CalculatorInput

    def _run(self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None) -> str:
        """Use the tool."""
        return llm_math_chain.run(query)
    
    async def _arun(self, query: str,  run_manager: Optional[AsyncCallbackManagerForToolRun] = None) -> str:
        """Use the tool asynchronously."""
        raise NotImplementedError("Calculator does not support async")
tools = [CustomSearchTool(), CustomCalculatorTool()]
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")
> Entering new AgentExecutor chain...
I need to use custom_search to find out who Leo DiCaprio's girlfriend is, and then use the Calculator to raise her age to the 0.43 power.
Action: custom_search
Action Input: "Leo DiCaprio girlfriend"
Observation: After rumours of a romance with Gigi Hadid, the Oscar winner has seemingly moved on. First being linked to the television personality in September 2022, it appears as if his "age bracket" has moved up. This follows his rumoured relationship with mere 19-year-old Eden Polani.
Thought:I need to find out the current age of Eden Polani.
Action: custom_search
Action Input: "Eden Polani age"
Observation: 19 years old
Thought:Now I can use the Calculator to raise her age to the 0.43 power.
Action: Calculator
Action Input: 19 ^ 0.43

> Entering new LLMMathChain chain...
19 ^ 0.43```text
19 ** 0.43
```
...numexpr.evaluate("19 ** 0.43")...

Answer: 3.547023357958959
> Finished chain.

Observation: Answer: 3.547023357958959
Thought:I now know the final answer.
Final Answer: 3.547023357958959

> Finished chain.
'3.547023357958959'

使用tool装饰器

为了更容易定义自定义工具,@tool提供了一个装饰器。这个装饰器可以用来Tool从一个简单的函数中快速创建一个。默认情况下,装饰器使用函数名称作为工具名称,但这可以通过传递字符串作为第一个参数来覆盖。此外,装饰器将使用函数的文档字符串作为工具的描述。

from langchain.tools import tool

@tool
def search_api(query: str) -> str:
    """Searches the API for the query."""
    return f"Results for query {query}"

search_api

您还可以提供参数,例如工具名称以及是否直接返回。

@tool("search", return_direct=True)
def search_api(query: str) -> str:
    """Searches the API for the query."""
    return "Results"
search_api
Tool(name='search', description='search(query: str) -> str - Searches the API for the query.', args_schema=, return_direct=True, verbose=False, callback_manager=, func=, coroutine=None)

您还可以提供args_schema有关参数的更多信息

class SearchInput(BaseModel):
    query: str = Field(description="should be a search query")
        
@tool("search", return_direct=True, args_schema=SearchInput)
def search_api(query: str) -> str:
    """Searches the API for the query."""
    return "Results"
search_api
Tool(name='search', description='search(query: str) -> str - Searches the API for the query.', args_schema=, return_direct=True, verbose=False, callback_manager=, func=, coroutine=None)

自定义结构化工具

如果您的函数需要更多结构化参数,您可以StructuredTool直接使用该类,或者仍然继承该类BaseTool。

结构化工具数据类

要从给定函数动态生成结构化工具,最快的入门方法是使用StructuredTool.from_function().

import requests
from langchain.tools import StructuredTool

def post_message(url: str, body: dict, parameters: Optional[dict] = None) -> str:
    """Sends a POST request to the given url with the given body and parameters."""
    result = requests.post(url, json=body, params=parameters)
    return f"Status: {result.status_code} - {result.text}"

tool = StructuredTool.from_function(post_message)

子类化 BaseTool

BaseTool 自动从 _run 方法的签名中推断模式。

from typing import Optional, Type

from langchain.callbacks.manager import AsyncCallbackManagerForToolRun, CallbackManagerForToolRun
            
class CustomSearchTool(BaseTool):
    name = "custom_search"
    description = "useful for when you need to answer questions about current events"

    def _run(self, query: str, engine: str = "google", gl: str = "us", hl: str = "en", run_manager: Optional[CallbackManagerForToolRun] = None) -> str:
        """Use the tool."""
        search_wrapper = SerpAPIWrapper(params={"engine": engine, "gl": gl, "hl": hl})
        return search_wrapper.run(query)
    
    async def _arun(self, query: str,  engine: str = "google", gl: str = "us", hl: str = "en", run_manager: Optional[AsyncCallbackManagerForToolRun] = None) -> str:
        """Use the tool asynchronously."""
        raise NotImplementedError("custom_search does not support async")



# You can provide a custom args schema to add descriptions or custom validation

class SearchSchema(BaseModel):
    query: str = Field(description="should be a search query")
    engine: str = Field(description="should be a search engine")
    gl: str = Field(description="should be a country code")
    hl: str = Field(description="should be a language code")

class CustomSearchTool(BaseTool):
    name = "custom_search"
    description = "useful for when you need to answer questions about current events"
    args_schema: Type[SearchSchema] = SearchSchema

    def _run(self, query: str, engine: str = "google", gl: str = "us", hl: str = "en", run_manager: Optional[CallbackManagerForToolRun] = None) -> str:
        """Use the tool."""
        search_wrapper = SerpAPIWrapper(params={"engine": engine, "gl": gl, "hl": hl})
        return search_wrapper.run(query)
    
    async def _arun(self, query: str,  engine: str = "google", gl: str = "us", hl: str = "en", run_manager: Optional[AsyncCallbackManagerForToolRun] = None) -> str:
        """Use the tool asynchronously."""
        raise NotImplementedError("custom_search does not support async")
    
    

使用装饰器

tool如果签名有多个参数,装饰器会自动创建一个结构化工具。

import requests
from langchain.tools import tool

@tool
def post_message(url: str, body: dict, parameters: Optional[dict] = None) -> str:
    """Sends a POST request to the given url with the given body and parameters."""
    result = requests.post(url, json=body, params=parameters)
    return f"Status: {result.status_code} - {result.text}"

修改现有工具

现在,我们将展示如何加载现有工具并直接修改它们。在下面的示例中,我们做了一些非常简单的事情,并将搜索工具更改为名称。Google Search

from langchain.agents import load_tools
tools = load_tools(["serpapi", "llm-math"], llm=llm)
tools[0].name = "Google Search"
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")
> Entering new AgentExecutor chain...
I need to find out Leo DiCaprio's girlfriend's name and her age.
Action: Google Search
Action Input: "Leo DiCaprio girlfriend"
Observation: After rumours of a romance with Gigi Hadid, the Oscar winner has seemingly moved on. First being linked to the television personality in September 2022, it appears as if his "age bracket" has moved up. This follows his rumoured relationship with mere 19-year-old Eden Polani.
Thought:I still need to find out his current girlfriend's name and her age.
Action: Google Search
Action Input: "Leo DiCaprio current girlfriend age"
Observation: Leonardo DiCaprio has been linked with 19-year-old model Eden Polani, continuing the rumour that he doesn't date any women over the age of ...
Thought:I need to find out the age of Eden Polani.
Action: Calculator
Action Input: 19^(0.43)
Observation: Answer: 3.547023357958959
Thought:I now know the final answer.
Final Answer: The age of Leo DiCaprio's girlfriend raised to the 0.43 power is approximately 3.55.

> Finished chain.
"The age of Leo DiCaprio's girlfriend raised to the 0.43 power is approximately 3.55."

定义工具之间的优先级

当您制作自定义工具时,您可能希望 Agent 比普通工具更多地使用自定义工具。

例如,您制作了一个自定义工具,它可以从您的数据库中获取有关音乐的信息。当用户想要有关歌曲的信息时,您希望 Agent 使用 比正常情况下更多的. 但是代理可能会优先考虑普通的搜索工具。the custom toolSearch tool

这可以通过在描述中添加诸如此类的语句来实现。Use this more than the normal search if the question is about Music, like 'who is the singer of yesterday?' or 'what is the most popular song in 2022?'

下面是一个例子。

# Import things that are needed generically
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper
search = SerpAPIWrapper()
tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events"
    ),
    Tool(
        name="Music Search",
        func=lambda x: "'All I Want For Christmas Is You' by Mariah Carey.", #Mock Function
        description="A Music search engine. Use this more than the normal search if the question is about Music, like 'who is the singer of yesterday?' or 'what is the most popular song in 2022?'",
    )
]

agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("what is the most famous song of christmas")
> Entering new AgentExecutor chain...
 I should use a music search engine to find the answer
Action: Music Search
Action Input: most famous song of christmas'All I Want For Christmas Is You' by Mariah Carey. I now know the final answer
Final Answer: 'All I Want For Christmas Is You' by Mariah Carey.

> Finished chain.
"'All I Want For Christmas Is You' by Mariah Carey."

使用工具直接返回

通常,如果调用工具,可能希望将工具输出直接返回给用户。通过将工具的 return_direct 标志设置为 True,您可以使用 LangChain 轻松做到这一点。

llm_math_chain = LLMMathChain(llm=llm)
tools = [
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math",
        return_direct=True
    )
]
llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("whats 2**.12")
> Entering new AgentExecutor chain...
 I need to calculate this
Action: Calculator
Action Input: 2**.12Answer: 1.086734862526058

> Finished chain.
'Answer: 1.086734862526058'

多输入工具

此笔记本展示了如何使用需要多个输入的工具与代理。推荐的方法是在课堂上StructuredTool。

import os
os.environ["LANGCHAIN_TRACING"] = "true"
from langchain import OpenAI
from langchain.agents import initialize_agent, AgentType

llm = OpenAI(temperature=0)
from langchain.tools import StructuredTool

def multiplier(a: float, b: float) -> float:
    """Multiply the provided floats."""
    return a * b

tool = StructuredTool.from_function(multiplier)
# Structured tools are compatible with the STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION agent type. 
agent_executor = initialize_agent([tool], llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent_executor.run("What is 3 times 4")
> Entering new AgentExecutor chain...

Thought: I need to multiply 3 and 4
Action:
```
{
  "action": "multiplier",
  "action_input": {"a": 3, "b": 4}
}
```

Observation: 12
Thought: I know what to respond
Action:
```
{
  "action": "Final Answer",
  "action_input": "3 times 4 is 12"
}
```

> Finished chain.
'3 times 4 is 12'

具有字符串格式的多输入工具

结构化工具的替代方法是使用常规Tool类并接受单个字符串。然后该工具必须处理解析逻辑以从文本中提取相关值,这将工具表示与代理提示紧密耦合。如果底层语言模型不能可靠地生成结构化模式,这仍然有用。

我们以乘法函数为例。为了使用它,我们将告诉代理将“动作输入”生成为逗号分隔的长度为 2 的列表。然后我们将编写一个精简的包装器,它接受一个字符串,将它分成两个围绕逗号,并将解析的两边作为整数传递给乘法函数。

from langchain.llms import OpenAI
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType

这是乘法函数,以及将字符串解析为输入的包装器。

def multiplier(a, b):
    return a * b

def parsing_multiplier(string):
    a, b = string.split(",")
    return multiplier(int(a), int(b))
llm = OpenAI(temperature=0)
tools = [
    Tool(
        name = "Multiplier",
        func=parsing_multiplier,
        description="useful for when you need to multiply two numbers together. The input to this tool should be a comma separated list of numbers of length two, representing the two numbers you want to multiply together. For example, `1,2` would be the input if you wanted to multiply 1 by 2."
    )
]
mrkl = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
mrkl.run("What is 3 times 4")
> Entering new AgentExecutor chain...
 I need to multiply two numbers
Action: Multiplier
Action Input: 3,4
Observation: 12
Thought: I now know the final answer
Final Answer: 3 times 4 is 12

> Finished chain.
'3 times 4 is 12'

工具输入模式

默认情况下,工具通过检查函数签名来推断参数模式。对于更严格的要求,可以指定自定义输入模式以及自定义验证逻辑。

from typing import Any, Dict

from langchain.agents import AgentType, initialize_agent
from langchain.llms import OpenAI
from langchain.tools.requests.tool import RequestsGetTool, TextRequestsWrapper
from pydantic import BaseModel, Field, root_validator
llm = OpenAI(temperature=0)
!pip install tldextract > /dev/null
[notice] A new release of pip is available: 23.0.1 -> 23.1
[notice] To update, run: pip install --upgrade pip
import tldextract

_APPROVED_DOMAINS = {
    "langchain",
    "wikipedia",
}

class ToolInputSchema(BaseModel):

    url: str = Field(...)
    
    @root_validator
    def validate_query(cls, values: Dict[str, Any]) -> Dict:
        url = values["url"]
        domain = tldextract.extract(url).domain
        if domain not in _APPROVED_DOMAINS:
            raise ValueError(f"Domain {domain} is not on the approved list:"
                             f" {sorted(_APPROVED_DOMAINS)}")
        return values
    
tool = RequestsGetTool(args_schema=ToolInputSchema, requests_wrapper=TextRequestsWrapper())
agent = initialize_agent([tool], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=False)
# This will succeed, since there aren't any arguments that will be triggered during validation
answer = agent.run("What's the main title on langchain.com?")
print(answer)
The main title of langchain.com is "LANG CHAIN   Official Home Page"
agent.run("What's the main title on google.com?")
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Cell In[7], line 1
----> 1 agent.run("What's the main title on google.com?")

File ~/code/lc/lckg/langchain/chains/base.py:213, in Chain.run(self, *args, **kwargs)
    211     if len(args) != 1:
    212         raise ValueError("`run` supports only one positional argument.")
--> 213     return self(args[0])[self.output_keys[0]]
    215 if kwargs and not args:
    216     return self(kwargs)[self.output_keys[0]]

File ~/code/lc/lckg/langchain/chains/base.py:116, in Chain.__call__(self, inputs, return_only_outputs)
    114 except (KeyboardInterrupt, Exception) as e:
    115     self.callback_manager.on_chain_error(e, verbose=self.verbose)
--> 116     raise e
    117 self.callback_manager.on_chain_end(outputs, verbose=self.verbose)
    118 return self.prep_outputs(inputs, outputs, return_only_outputs)

File ~/code/lc/lckg/langchain/chains/base.py:113, in Chain.__call__(self, inputs, return_only_outputs)
    107 self.callback_manager.on_chain_start(
    108     {"name": self.__class__.__name__},
    109     inputs,
    110     verbose=self.verbose,
    111 )
    112 try:
--> 113     outputs = self._call(inputs)
    114 except (KeyboardInterrupt, Exception) as e:
    115     self.callback_manager.on_chain_error(e, verbose=self.verbose)

File ~/code/lc/lckg/langchain/agents/agent.py:792, in AgentExecutor._call(self, inputs)
    790 # We now enter the agent loop (until it returns something).
    791 while self._should_continue(iterations, time_elapsed):
--> 792     next_step_output = self._take_next_step(
    793         name_to_tool_map, color_mapping, inputs, intermediate_steps
    794     )
    795     if isinstance(next_step_output, AgentFinish):
    796         return self._return(next_step_output, intermediate_steps)

File ~/code/lc/lckg/langchain/agents/agent.py:695, in AgentExecutor._take_next_step(self, name_to_tool_map, color_mapping, inputs, intermediate_steps)
    693         tool_run_kwargs["llm_prefix"] = ""
    694     # We then call the tool on the tool input to get an observation
--> 695     observation = tool.run(
    696         agent_action.tool_input,
    697         verbose=self.verbose,
    698         color=color,
    699         **tool_run_kwargs,
    700     )
    701 else:
    702     tool_run_kwargs = self.agent.tool_run_logging_kwargs()

File ~/code/lc/lckg/langchain/tools/base.py:110, in BaseTool.run(self, tool_input, verbose, start_color, color, **kwargs)
    101 def run(
    102     self,
    103     tool_input: Union[str, Dict],
   (...)
    107     **kwargs: Any,
    108 ) -> str:
    109     """Run the tool."""
--> 110     run_input = self._parse_input(tool_input)
    111     if not self.verbose and verbose is not None:
    112         verbose_ = verbose

File ~/code/lc/lckg/langchain/tools/base.py:71, in BaseTool._parse_input(self, tool_input)
     69 if issubclass(input_args, BaseModel):
     70     key_ = next(iter(input_args.__fields__.keys()))
---> 71     input_args.parse_obj({key_: tool_input})
     72 # Passing as a positional argument is more straightforward for
     73 # backwards compatability
     74 return tool_input

File ~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:526, in pydantic.main.BaseModel.parse_obj()

File ~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:341, in pydantic.main.BaseModel.__init__()

ValidationError: 1 validation error for ToolInputSchema
__root__
  Domain google is not on the approved list: ['langchain', 'wikipedia'] (type=value_error)

应用

本笔记本展示了如何使用Apify 集成LangChain。

Apify是一个用于网络抓取和数据提取的云平台,它提供了一个生态系统,其中包含超过一千个现成的应用程序,称为Actors,用于各种网络抓取、爬行和数据提取用例。例如,您可以使用它来提取 Google 搜索结果、Instagram 和 Facebook 个人资料、来自 Amazon 或 Shopify 的产品、Google 地图评论等。

在这个例子中,我们将使用Website Content Crawler Actor,它可以深度爬取文档、知识库、帮助中心或博客等网站,并从网页中提取文本内容。然后我们将文档输入向量索引并从中回答问题。

#!pip install apify-client

首先,导入ApifyWrapper您的源代码:

from langchain.document_loaders.base import Document
from langchain.indexes import VectorstoreIndexCreator
from langchain.utilities import ApifyWrapper

使用您的Apify API 令牌对其进行初始化,并且出于本示例的目的,还使用您的 OpenAI API 密钥:

import os
os.environ["OPENAI_API_KEY"] = "Your OpenAI API key"
os.environ["APIFY_API_TOKEN"] = "Your Apify API token"

apify = ApifyWrapper()

然后运行 Actor,等待它完成,并将其结果从 Apify 数据集中提取到 LangChain 文档加载器中。

请注意,如果您在 Apify 数据集中已有一些结果,则可以直接使用 加载它们ApifyDatasetLoader,如本笔记本所示。在该笔记本中,您还会找到 的解释dataset_mapping_function,它用于将字段从 Apify 数据集记录映射到 LangChainDocument字段。

loader = apify.call_actor(
    actor_id="apify/website-content-crawler",
    run_input={"startUrls": [{"url": "https://python.langchain.com/en/latest/"}]},
    dataset_mapping_function=lambda item: Document(
        page_content=item["text"] or "", metadata={"source": item["url"]}
    ),
)

从爬取的文档中初始化向量索引:

index = VectorstoreIndexCreator().from_loaders([loader])

最后,查询向量索引:

query = "What is LangChain?"
result = index.query_with_sources(query)
print(result["answer"])
print(result["sources"])
 LangChain is a standard interface through which you can interact with a variety of large language models (LLMs). It provides modules that can be used to build language model applications, and it also provides chains and agents with memory capabilities.

https://python.langchain.com/en/latest/modules/models/llms.html, https://python.langchain.com/en/latest/getting_started/getting_started.html

必应搜索

本笔记本介绍了如何使用必应搜索组件。

首先,您需要设置适当的 API 密钥和环境变量。要进行设置,请按照此处的说明进行操作。

然后我们需要设置一些环境变量。

import os
os.environ["BING_SUBSCRIPTION_KEY"] = ""
os.environ["BING_SEARCH_URL"] = ""
from langchain.utilities import BingSearchAPIWrapper
search = BingSearchAPIWrapper()
search.run("python")
'Thanks to the flexibility of Python and the powerful ecosystem of packages, the Azure CLI supports features such as autocompletion (in shells that support it), persistent credentials, JMESPath result parsing, lazy initialization, network-less unit tests, and more. Building an open-source and cross-platform Azure CLI with Python by Dan Taylor. Python releases by version number: Release version Release date Click for more. Python 3.11.1 Dec. 6, 2022 Download Release Notes. Python 3.10.9 Dec. 6, 2022 Download Release Notes. Python 3.9.16 Dec. 6, 2022 Download Release Notes. Python 3.8.16 Dec. 6, 2022 Download Release Notes. Python 3.7.16 Dec. 6, 2022 Download Release Notes. In this lesson, we will look at the += operator in Python and see how it works with several simple examples.. The operator ‘+=’ is a shorthand for the addition assignment operator.It adds two values and assigns the sum to a variable (left operand). W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more. This tutorial introduces the reader informally to the basic concepts and features of the Python language and system. It helps to have a Python interpreter handy for hands-on experience, but all examples are self-contained, so the tutorial can be read off-line as well. For a description of standard objects and modules, see The Python Standard ... Python is a general-purpose, versatile, and powerful programming language. It's a great first language because Python code is concise and easy to read. Whatever you want to do, python can do it. From web development to machine learning to data science, Python is the language for you. To install Python using the Microsoft Store: Go to your Start menu (lower left Windows icon), type "Microsoft Store", select the link to open the store. Once the store is open, select Search from the upper-right menu and enter "Python". Select which version of Python you would like to use from the results under Apps. Under the “Python Releases for Mac OS X” heading, click the link for the Latest Python 3 Release - Python 3.x.x. As of this writing, the latest version was Python 3.8.4. Scroll to the bottom and click macOS 64-bit installer to start the download. When the installer is finished downloading, move on to the next step. Step 2: Run the Installer'

结果数

可以使用k参数设置结果数

search = BingSearchAPIWrapper(k=1)
search.run("python")
'Thanks to the flexibility of Python and the powerful ecosystem of packages, the Azure CLI supports features such as autocompletion (in shells that support it), persistent credentials, JMESPath result parsing, lazy initialization, network-less unit tests, and more. Building an open-source and cross-platform Azure CLI with Python by Dan Taylor.'

元数据结果

通过 BingSearch 运行查询并返回片段、标题和链接元数据。

search = BingSearchAPIWrapper()
search.results("apples", 5)
[{'snippet': 'Lady Alice. Pink Lady apples aren’t the only lady in the apple family. Lady Alice apples were discovered growing, thanks to bees pollinating, in Washington. They are smaller and slightly more stout in appearance than other varieties. Their skin color appears to have red and yellow stripes running from stem to butt.',
  'title': '25 Types of Apples - Jessica Gavin',
  'link': 'https://www.jessicagavin.com/types-of-apples/'},
 {'snippet': 'Apples can do a lot for you, thanks to plant chemicals called flavonoids. And they have pectin, a fiber that breaks down in your gut. If you take off the apple’s skin before eating it, you won ...',
  'title': 'Apples: Nutrition & Health Benefits - WebMD',
  'link': 'https://www.webmd.com/food-recipes/benefits-apples'},
 {'snippet': 'Apples boast many vitamins and minerals, though not in high amounts. However, apples are usually a good source of vitamin C. Vitamin C. Also called ascorbic acid, this vitamin is a common ...',
  'title': 'Apples 101: Nutrition Facts and Health Benefits',
  'link': 'https://www.healthline.com/nutrition/foods/apples'},
 {'snippet': 'Weight management. The fibers in apples can slow digestion, helping one to feel greater satisfaction after eating. After following three large prospective cohorts of 133,468 men and women for 24 years, researchers found that higher intakes of fiber-rich fruits with a low glycemic load, particularly apples and pears, were associated with the least amount of weight gain over time.',
  'title': 'Apples | The Nutrition Source | Harvard T.H. Chan School of Public Health',
  'link': 'https://www.hsph.harvard.edu/nutritionsource/food-features/apples/'}]

谷歌搜索

本笔记本介绍了如何使用谷歌搜索组件。

首先,您需要设置适当的 API 密钥和环境变量。要进行设置,请在 Google Cloud 凭证控制台 (https://console.cloud.google.com/apis/credentials) 中创建 GOOGLE_API_KEY,并使用可编程搜索引擎 (https://programmablesearchengine.google.com/) 创建 GOOGLE_CSE_ID控制面板/创建)。接下来,最好按照此处的说明进行操作。

然后我们需要设置一些环境变量。

import os
os.environ["GOOGLE_CSE_ID"] = ""
os.environ["GOOGLE_API_KEY"] = ""
from langchain.tools import Tool
from langchain.utilities import GoogleSearchAPIWrapper

search = GoogleSearchAPIWrapper()

tool = Tool(
    name = "Google Search",
    description="Search Google for recent results.",
    func=search.run
)
tool.run("Obama's first name?")
"STATE OF HAWAII. 1 Child's First Name. (Type or print). 2. Sex. BARACK. 3. This Birth. CERTIFICATE OF LIVE BIRTH. FILE. NUMBER 151 le. lb. Middle Name. Barack Hussein Obama II is an American former politician who served as the 44th president of the United States from 2009 to 2017. A member of the Democratic ... When Barack Obama was elected president in 2008, he became the first African American to hold ... The Middle East remained a key foreign policy challenge. Jan 19, 2017 ... Jordan Barack Treasure, New York City, born in 2008 ... Jordan Barack Treasure made national news when he was the focus of a New York newspaper ... Portrait of George Washington, the 1st President of the United States ... Portrait of Barack Obama, the 44th President of the United States ... His full name is Barack Hussein Obama II. Since the “II” is simply because he was named for his father, his last name is Obama. Mar 22, 2008 ... Barry Obama decided that he didn't like his nickname. A few of his friends at Occidental College had already begun to call him Barack (his ... Aug 18, 2017 ... It took him several seconds and multiple clues to remember former President Barack Obama's first name. Miller knew that every answer had to ... Feb 9, 2015 ... Michael Jordan misspelled Barack Obama's first name on 50th-birthday gift ... Knowing Obama is a Chicagoan and huge basketball fan, ... 4 days ago ... Barack Obama, in full Barack Hussein Obama II, (born August 4, 1961, Honolulu, Hawaii, U.S.), 44th president of the United States (2009–17) and ..."

结果数

可以使用k参数设置结果数

search = GoogleSearchAPIWrapper(k=1)

tool = Tool(
    name = "I'm Feeling Lucky",
    description="Search Google and return the first result.",
    func=search.run
)
tool.run("python")
'The official home of the Python Programming Language.'

“Python 编程语言的官方主页。”

元数据结果

通过 GoogleSearch 运行查询并返回片段、标题和链接元数据。

search = GoogleSearchAPIWrapper()

def top5_results(query):
    return search.results(query, 5)

tool = Tool(
    name = "Google Search Snippets",
    description="Search Google for recent results.",
    func=top5_results
)
展开阅读全文

页面更新:2024-03-01

标签:自然语言   密钥   初始化   字符串   函数   模块   名称   参数   手册   工具   法学硕士   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top