6大核心模块(Modules)
工具输入验证(Tool Input Validation)

工具输入模式

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

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)

创建一个OpenAI对象,用于调用OpenAI的API。

!pip install tldextract > /dev/null

安装tldextract库,用于从url中提取域名。

[notice] A new release of pip is available: 23.0.1 -> 23.1
[notice] To update, run: pip install --upgrade pip

显示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

以上代码定义了一个工具输入模式,包含了url字段。使用root_validator装饰器定义了一个验证器,用于验证url是否属于指定的域名之一。

如果不属于,则抛出异常。ValueError(f"域名 {domain} 不在批准列表中: {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)
 
# 这将成功,因为在验证期间不会触发任何参数
answer = agent.run("langchain.com 的主标题是什么?")
print(answer)
 
langchain.com 的主标题是 "LANG CHAIN 🦜️🔗 官方主页"
 
agent.run("google.com 的主标题是什么?")
 
 
ValidationError Traceback (most recent call last)
Cell In[7], line 1
----> 1 agent.run("google.com 的主标题是什么?")
 
File ~/code/lc/lckg/langchain/chains/base.py:213, in Chain.run(self, \*args```python
 
在文件~/code/lc/lckg/langchain/chains/base.py中的116行,Chain的__call__方法抛出异常。在113行,该方法调用_call方法,并在try语句中捕获异常。在110行到111行之间,Chain的callback_manager管理器的on_chain_start方法被调用,传递了Chain的名称和输入参数。如果kwargs存在且args不存在,则在215行返回self(kwargs)[self.output_keys[0]]。如果args存在且长度不等于1,则在212行引发ValueError异常。否则,在213行返回self(args[0])[self.output_keys[0]]。如果try语句块内抛出异常,则在115行调用Chain的callback_manager管理器的on_chain_error方法,并重新抛出异常。在118行,Chain的callback_manager管理器的on_chain_end方法被调用,传递了输出参数和verbose参数。最后,在119行返回prep_outputs方法的结果,该方法接收输入参数、输出参数和return_only_outputs参数。在文件~/code/lc/lckg/langchain/agents/agent.py的第792行,当出现链错误时,调用back_manager.on_chain_error(e, verbose=self.verbose)函数。
 
在文件~/code/lc/lckg/langchain/agents/agent.py的第790行,进入Agent循环,直到返回某些东西。
 
在AgentExecutor._call(self, inputs)函数中,第792行调用了_take_next_step()函数,该函数传入name_to_tool_map、color_mapping、inputs和intermediate_steps参数。
 
在AgentExecutor._take_next_step(self, name_to_tool_map, color_mapping, inputs, intermediate_steps)函数中,第695行调用了tool.run()函数,传入agent_action.tool_input、verbose=self.verbose、color和tool_run_kwargs等参数,以获取观察值。如果agent_action是None,则返回None。在文件~/code/lc/lckg/langchain/tools/base.py的第110行,BaseTool类的run方法中,获取了self.agent.tool_run_logging_kwargs()的参数并赋值给tool_run_kwargs。
 
在文件~/code/lc/lckg/langchain/tools/base.py的第71行,BaseTool类的_parse_input方法中,解析了tool_input,并将其返回。
 
在文件~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py的第526行,BaseModel类的parse_obj方法被调用。在/pydantic/main.py的第341行,pydantic.main.BaseModel.__init__()函数的参数校验出错了,错误信息是:ToolInputSchema的__root__字段的值不在['langchain', 'wikipedia']中,不符合要求。
 
```  python