mirror of
https://github.com/langchain-ai/langchain.git
synced 2026-10-06 01:45:27 +03:00
Co-authored-by: vowelparrot <130414180+vowelparrot@users.noreply.github.com>
15 KiB
15 KiB
In [1]:
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.llms import OpenAI
from langchain.tools.python.tool import PythonREPLTool
from pydantic import BaseModel
from pydantic import Field, root_validator
from typing import Dict, AnyIn [2]:
llm = OpenAI(temperature=0)In [3]:
class ToolInputModel(BaseModel):
query: str = Field(...)
@root_validator
def validate_query(cls, values: Dict[str, Any]) -> Dict:
# Note: this is NOT a safe REPL! This is used for instructive purposes only
if "import os" in values["query"]:
raise ValueError("'import os' not permitted in this python REPL.")
return values
tool = PythonREPLTool(args_schema=ToolInputModel)In [4]:
agent = initialize_agent([tool], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)In [5]:
# This will succeed, since there aren't any arguments that will be triggered during validation
agent.run("Run a python function that adds 2 and 2")Out [5]:
[1m> Entering new AgentExecutor chain...[0m
[32;1m[1;3m I need to define a function that adds two numbers
Action: Python REPL
Action Input: def add_two_numbers(a, b):
return a + b[0m[36;1m[1;3m[0m[32;1m[1;3m I need to call the function
Action: Python REPL
Action Input: print(add_two_numbers(2, 2))[0m[36;1m[1;3m4
[0m[32;1m[1;3m I now know the final answer
Final Answer: 4[0m
[1m> Finished chain.[0m
'4'
In [6]:
# This will fail, because the attempt to import os will trigger a validation error
agent.run("Run a python function that imports os and lists the dir")[1m> Entering new AgentExecutor chain...[0m [32;1m[1;3m I need to import os and then list the dir Action: Python REPL Action Input: import os; print(os.listdir())[0m
[0;31m---------------------------------------------------------------------------[0m
[0;31mValidationError[0m Traceback (most recent call last)
Cell [0;32mIn[6], line 1[0m
[0;32m----> 1[0m [43magent[49m[38;5;241;43m.[39;49m[43mrun[49m[43m([49m[38;5;124;43m"[39;49m[38;5;124;43mRun a python function that imports os and lists the dir[39;49m[38;5;124;43m"[39;49m[43m)[49m
File [0;32m~/code/lc/lckg/langchain/chains/base.py:213[0m, in [0;36mChain.run[0;34m(self, *args, **kwargs)[0m
[1;32m 211[0m [38;5;28;01mif[39;00m [38;5;28mlen[39m(args) [38;5;241m!=[39m [38;5;241m1[39m:
[1;32m 212[0m [38;5;28;01mraise[39;00m [38;5;167;01mValueError[39;00m([38;5;124m"[39m[38;5;124m`run` supports only one positional argument.[39m[38;5;124m"[39m)
[0;32m--> 213[0m [38;5;28;01mreturn[39;00m [38;5;28;43mself[39;49m[43m([49m[43margs[49m[43m[[49m[38;5;241;43m0[39;49m[43m][49m[43m)[49m[[38;5;28mself[39m[38;5;241m.[39moutput_keys[[38;5;241m0[39m]]
[1;32m 215[0m [38;5;28;01mif[39;00m kwargs [38;5;129;01mand[39;00m [38;5;129;01mnot[39;00m args:
[1;32m 216[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m(kwargs)[[38;5;28mself[39m[38;5;241m.[39moutput_keys[[38;5;241m0[39m]]
File [0;32m~/code/lc/lckg/langchain/chains/base.py:116[0m, in [0;36mChain.__call__[0;34m(self, inputs, return_only_outputs)[0m
[1;32m 114[0m [38;5;28;01mexcept[39;00m ([38;5;167;01mKeyboardInterrupt[39;00m, [38;5;167;01mException[39;00m) [38;5;28;01mas[39;00m e:
[1;32m 115[0m [38;5;28mself[39m[38;5;241m.[39mcallback_manager[38;5;241m.[39mon_chain_error(e, verbose[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39mverbose)
[0;32m--> 116[0m [38;5;28;01mraise[39;00m e
[1;32m 117[0m [38;5;28mself[39m[38;5;241m.[39mcallback_manager[38;5;241m.[39mon_chain_end(outputs, verbose[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39mverbose)
[1;32m 118[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m[38;5;241m.[39mprep_outputs(inputs, outputs, return_only_outputs)
File [0;32m~/code/lc/lckg/langchain/chains/base.py:113[0m, in [0;36mChain.__call__[0;34m(self, inputs, return_only_outputs)[0m
[1;32m 107[0m [38;5;28mself[39m[38;5;241m.[39mcallback_manager[38;5;241m.[39mon_chain_start(
[1;32m 108[0m {[38;5;124m"[39m[38;5;124mname[39m[38;5;124m"[39m: [38;5;28mself[39m[38;5;241m.[39m[38;5;18m__class__[39m[38;5;241m.[39m[38;5;18m__name__[39m},
[1;32m 109[0m inputs,
[1;32m 110[0m verbose[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39mverbose,
[1;32m 111[0m )
[1;32m 112[0m [38;5;28;01mtry[39;00m:
[0;32m--> 113[0m outputs [38;5;241m=[39m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_call[49m[43m([49m[43minputs[49m[43m)[49m
[1;32m 114[0m [38;5;28;01mexcept[39;00m ([38;5;167;01mKeyboardInterrupt[39;00m, [38;5;167;01mException[39;00m) [38;5;28;01mas[39;00m e:
[1;32m 115[0m [38;5;28mself[39m[38;5;241m.[39mcallback_manager[38;5;241m.[39mon_chain_error(e, verbose[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39mverbose)
File [0;32m~/code/lc/lckg/langchain/agents/agent.py:792[0m, in [0;36mAgentExecutor._call[0;34m(self, inputs)[0m
[1;32m 790[0m [38;5;66;03m# We now enter the agent loop (until it returns something).[39;00m
[1;32m 791[0m [38;5;28;01mwhile[39;00m [38;5;28mself[39m[38;5;241m.[39m_should_continue(iterations, time_elapsed):
[0;32m--> 792[0m next_step_output [38;5;241m=[39m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_take_next_step[49m[43m([49m
[1;32m 793[0m [43m [49m[43mname_to_tool_map[49m[43m,[49m[43m [49m[43mcolor_mapping[49m[43m,[49m[43m [49m[43minputs[49m[43m,[49m[43m [49m[43mintermediate_steps[49m
[1;32m 794[0m [43m [49m[43m)[49m
[1;32m 795[0m [38;5;28;01mif[39;00m [38;5;28misinstance[39m(next_step_output, AgentFinish):
[1;32m 796[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m[38;5;241m.[39m_return(next_step_output, intermediate_steps)
File [0;32m~/code/lc/lckg/langchain/agents/agent.py:695[0m, in [0;36mAgentExecutor._take_next_step[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps)[0m
[1;32m 693[0m tool_run_kwargs[[38;5;124m"[39m[38;5;124mllm_prefix[39m[38;5;124m"[39m] [38;5;241m=[39m [38;5;124m"[39m[38;5;124m"[39m
[1;32m 694[0m [38;5;66;03m# We then call the tool on the tool input to get an observation[39;00m
[0;32m--> 695[0m observation [38;5;241m=[39m [43mtool[49m[38;5;241;43m.[39;49m[43mrun[49m[43m([49m
[1;32m 696[0m [43m [49m[43magent_action[49m[38;5;241;43m.[39;49m[43mtool_input[49m[43m,[49m
[1;32m 697[0m [43m [49m[43mverbose[49m[38;5;241;43m=[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mverbose[49m[43m,[49m
[1;32m 698[0m [43m [49m[43mcolor[49m[38;5;241;43m=[39;49m[43mcolor[49m[43m,[49m
[1;32m 699[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mtool_run_kwargs[49m[43m,[49m
[1;32m 700[0m [43m [49m[43m)[49m
[1;32m 701[0m [38;5;28;01melse[39;00m:
[1;32m 702[0m tool_run_kwargs [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39magent[38;5;241m.[39mtool_run_logging_kwargs()
File [0;32m~/code/lc/lckg/langchain/tools/base.py:146[0m, in [0;36mBaseTool.run[0;34m(self, tool_input, verbose, start_color, color, **kwargs)[0m
[1;32m 137[0m [38;5;28;01mdef[39;00m [38;5;21mrun[39m(
[1;32m 138[0m [38;5;28mself[39m,
[1;32m 139[0m tool_input: Union[[38;5;28mstr[39m, Dict],
[0;32m (...)[0m
[1;32m 143[0m [38;5;241m*[39m[38;5;241m*[39mkwargs: Any,
[1;32m 144[0m ) [38;5;241m-[39m[38;5;241m>[39m [38;5;28mstr[39m:
[1;32m 145[0m [38;5;250m [39m[38;5;124;03m"""Run the tool."""[39;00m
[0;32m--> 146[0m run_input [38;5;241m=[39m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_parse_input[49m[43m([49m[43mtool_input[49m[43m)[49m
[1;32m 147[0m [38;5;28;01mif[39;00m [38;5;129;01mnot[39;00m [38;5;28mself[39m[38;5;241m.[39mverbose [38;5;129;01mand[39;00m verbose [38;5;129;01mis[39;00m [38;5;129;01mnot[39;00m [38;5;28;01mNone[39;00m:
[1;32m 148[0m verbose_ [38;5;241m=[39m verbose
File [0;32m~/code/lc/lckg/langchain/tools/base.py:112[0m, in [0;36mBaseTool._parse_input[0;34m(self, tool_input)[0m
[1;32m 110[0m tool_input [38;5;241m=[39m {field_name: tool_input}
[1;32m 111[0m [38;5;28;01mif[39;00m pydantic_input_type [38;5;129;01mis[39;00m [38;5;129;01mnot[39;00m [38;5;28;01mNone[39;00m:
[0;32m--> 112[0m [38;5;28;01mreturn[39;00m [43mpydantic_input_type[49m[38;5;241;43m.[39;49m[43mparse_obj[49m[43m([49m[43mtool_input[49m[43m)[49m
[1;32m 113[0m [38;5;28;01melse[39;00m:
[1;32m 114[0m [38;5;28;01mraise[39;00m [38;5;167;01mValueError[39;00m(
[1;32m 115[0m [38;5;124mf[39m[38;5;124m"[39m[38;5;124margs_schema required for tool [39m[38;5;132;01m{[39;00m[38;5;28mself[39m[38;5;241m.[39mname[38;5;132;01m}[39;00m[38;5;124m in order to[39m[38;5;124m"[39m
[1;32m 116[0m [38;5;124mf[39m[38;5;124m"[39m[38;5;124m accept input of type [39m[38;5;132;01m{[39;00m[38;5;28mtype[39m(tool_input)[38;5;132;01m}[39;00m[38;5;124m"[39m
[1;32m 117[0m )
File [0;32m~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:526[0m, in [0;36mpydantic.main.BaseModel.parse_obj[0;34m()[0m
File [0;32m~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:341[0m, in [0;36mpydantic.main.BaseModel.__init__[0;34m()[0m
[0;31mValidationError[0m: 1 validation error for ToolInputModel
__root__
'import os' not (type=value_error)In [ ]: