文章目录
1. LangChain tools
2. Python Agent
3. 自定义工具
3.1 查询日期
3.2 查询天气
learn from https://learn.deeplearning.ai/langchain
1. LangChain tools
from config import api_type, api_key, api_base, api_version, model_name
from langchain.chat_models import AzureChatOpenAI
from langchain.agents.agent_toolkits import create_python_agent
from langchain.agents import load_tools, initialize_agent
from langchain.agents import AgentType
from langchain.tools.python.tool import PythonREPLTool
from langchain.python import PythonREPL
from langchain.chat_models import ChatOpenAI
llm = AzureChatOpenAI(
openai_api_base=api_base,
openai_api_version=api_version,
deployment_name=model_name,
openai_api_key=api_key,
openai_api_type=api_type,
temperature=0.5,
)
tools = load_tools(["llm-math", "wikipedia", "terminal"], llm=llm)
agent = initialize_agent(
tools,
llm,
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
handle_parsing_errors=True,
verbose=True)
agent("300的四分之一是多少?")
给定了一些内置的工具,让模型自行选择使用哪个
问了个简单的除法,输出:
数学工具
> Entering new AgentExecutor chain...
Question: 300的四分之一是多少?
Thought: We can easily solve this problem using a calculator.
Action:
``
{
"action": "Calculator",
"action_input": "300/4"
}
``
Observation: Answer: 75.0
Thought:The calculator tool was able to solve the problem easily and gave us the answer.
Final Answer: 300的四分之一是75。
> Finished chain.
terminal工具
question = "列出当前目录下的所有文件,应该使用什么命令?"
result = agent(question)
print(result)
问了命令行的问题,输出
> Entering new AgentExecutor chain...
Question: 列出当前目录下的所有文件,应该使用什么命令?
Thought: 我需要使用一个能够列出当前目录下所有文件的命令。
Action:
``
{
"action": "terminal",
"action_input": "ls"
}
``
/opt/envs/rasa/lib/python3.8/site-packages/langchain/tools/shell/tool.py:33: UserWarning: The shell tool has no safeguards by default. Use at your own risk.
warnings.warn(
Observation: chains.py
config.py
demo.py
goods.csv
langchain1.py
langchain2.py
langchain3.py
langchain4.py
langchain5.py
people.csv
__pycache__
Thought:我已经成功列出了当前目录下的所有文件。
Final Answer: 可以使用"ls"命令来列出当前目录下的所有文件。
> Finished chain.
{'input': '列出当前目录下的所有文件,应该使用什么命令?', 'output': '可以使用"ls"命令来列出当前目录下的所有文件。'}
2. Python Agent
agent = create_python_agent(
llm,
tool=PythonREPLTool(),
verbose=True
)
import langchain
langchain.debug=True
customer_list = [["Harrison", "Chase"],
["Lang", "Chain"],
["Dolly", "Too"],
["Elle", "Elem"],
["Geoff","Fusion"],
["Trance","Former"],
["Jen","Ayai"]
]
res = agent.run(f"""对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:{customer_list}""")
print(res)
输出:
/opt/bdp/data01/anaconda3/envs/rasa/bin/python /opt/bdp/data01/chenmingming/gpt/langchain5.py
[chain/start] [1:chain:AgentExecutor] Entering Chain run with input:
{
"input": "对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:[['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]"
}
[chain/start] [1:chain:AgentExecutor > 2:chain:LLMChain] Entering Chain run with input:
{
"input": "对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:[['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]",
"agent_scratchpad": "",
"stop": [
"\nObservation:",
"\n\tObservation:"
]
}
[llm/start] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:AzureChatOpenAI] Entering LLM run with input:
{
"prompts": [
"Human: You are an agent designed to write and execute python code to answer questions.\nYou have access to a python REPL, which you can use to execute python code.\nIf you get an error, debug your code and try again.\nOnly use the output of your code to answer the question. \nYou might know the answer without running any code, but you should still run the code to get the answer.\nIf it does not seem like you can write code to answer the question, just return \"I don't know\" as the answer.\n\n\nPython_REPL: A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Python_REPL]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:[['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nThought:"
]
}
[llm/end] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:AzureChatOpenAI] [5.13s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "I need to sort the list of names by last name first, then by first name. I can use the sorted() function with a key parameter to specify the sorting order.\nAction: Python_REPL\nAction Input: sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))",
"generation_info": {
"finish_reason": "stop"
},
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "I need to sort the list of names by last name first, then by first name. I can use the sorted() function with a key parameter to specify the sorting order.\nAction: Python_REPL\nAction Input: sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))",
"additional_kwargs": {}
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 110,
"prompt_tokens": 344,
"total_tokens": 454
},
"model_name": "gpt-3.5-turbo"
},
"run": null
}
[chain/end] [1:chain:AgentExecutor > 2:chain:LLMChain] [5.13s] Exiting Chain run with output:
{
"text": "I need to sort the list of names by last name first, then by first name. I can use the sorted() function with a key parameter to specify the sorting order.\nAction: Python_REPL\nAction Input: sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))"
}
[tool/start] [1:chain:AgentExecutor > 4:tool:Python_REPL] Entering Tool run with input:
"sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))"
[tool/end] [1:chain:AgentExecutor > 4:tool:Python_REPL] [1.4369999999999998ms] Exiting Tool run with output:
""
[chain/start] [1:chain:AgentExecutor > 5:chain:LLMChain] Entering Chain run with input:
{
"input": "对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:[['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]",
"agent_scratchpad": "I need to sort the list of names by last name first, then by first name. I can use the sorted() function with a key parameter to specify the sorting order.\nAction: Python_REPL\nAction Input: sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))\nObservation: \nThought:",
"stop": [
"\nObservation:",
"\n\tObservation:"
]
}
[llm/start] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:AzureChatOpenAI] Entering LLM run with input:
{
"prompts": [
"Human: You are an agent designed to write and execute python code to answer questions.\nYou have access to a python REPL, which you can use to execute python code.\nIf you get an error, debug your code and try again.\nOnly use the output of your code to answer the question. \nYou might know the answer without running any code, but you should still run the code to get the answer.\nIf it does not seem like you can write code to answer the question, just return \"I don't know\" as the answer.\n\n\nPython_REPL: A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Python_REPL]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:[['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nThought:I need to sort the list of names by last name first, then by first name. I can use the sorted() function with a key parameter to specify the sorting order.\nAction: Python_REPL\nAction Input: sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))\nObservation: \nThought:"
]
}
[llm/end] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:AzureChatOpenAI] [2.84s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "The sorted() function sorted the list of names by last name first, then by first name. I need to print the final sorted list.\nAction: Python_REPL\nAction Input: print(sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1])))",
"generation_info": {
"finish_reason": "stop"
},
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "The sorted() function sorted the list of names by last name first, then by first name. I need to print the final sorted list.\nAction: Python_REPL\nAction Input: print(sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1])))",
"additional_kwargs": {}
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 104,
"prompt_tokens": 459,
"total_tokens": 563
},
"model_name": "gpt-3.5-turbo"
},
"run": null
}
[chain/end] [1:chain:AgentExecutor > 5:chain:LLMChain] [2.85s] Exiting Chain run with output:
{
"text": "The sorted() function sorted the list of names by last name first, then by first name. I need to print the final sorted list.\nAction: Python_REPL\nAction Input: print(sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1])))"
}
[tool/start] [1:chain:AgentExecutor > 7:tool:Python_REPL] Entering Tool run with input:
"print(sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1])))"
[tool/end] [1:chain:AgentExecutor > 7:tool:Python_REPL] [0.641ms] Exiting Tool run with output:
"[['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]"
[chain/start] [1:chain:AgentExecutor > 8:chain:LLMChain] Entering Chain run with input:
{
"input": "对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:[['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]",
"agent_scratchpad": "I need to sort the list of names by last name first, then by first name. I can use the sorted() function with a key parameter to specify the sorting order.\nAction: Python_REPL\nAction Input: sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))\nObservation: \nThought:The sorted() function sorted the list of names by last name first, then by first name. I need to print the final sorted list.\nAction: Python_REPL\nAction Input: print(sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1])))\nObservation: [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]\n\nThought:",
"stop": [
"\nObservation:",
"\n\tObservation:"
]
}
[llm/start] [1:chain:AgentExecutor > 8:chain:LLMChain > 9:llm:AzureChatOpenAI] Entering LLM run with input:
{
"prompts": [
"Human: You are an agent designed to write and execute python code to answer questions.\nYou have access to a python REPL, which you can use to execute python code.\nIf you get an error, debug your code and try again.\nOnly use the output of your code to answer the question. \nYou might know the answer without running any code, but you should still run the code to get the answer.\nIf it does not seem like you can write code to answer the question, just return \"I don't know\" as the answer.\n\n\nPython_REPL: A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Python_REPL]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 对这些顾客的姓名进行排序:先是姓,再是名字,并打印最终排序结果:[['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nThought:I need to sort the list of names by last name first, then by first name. I can use the sorted() function with a key parameter to specify the sorting order.\nAction: Python_REPL\nAction Input: sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1]))\nObservation: \nThought:The sorted() function sorted the list of names by last name first, then by first name. I need to print the final sorted list.\nAction: Python_REPL\nAction Input: print(sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[0], x[1])))\nObservation: [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]\n\nThought:"
]
}
[llm/end] [1:chain:AgentExecutor > 8:chain:LLMChain > 9:llm:AzureChatOpenAI] [3.69s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "The final sorted list is [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]\nFinal Answer: [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]",
"generation_info": {
"finish_reason": "stop"
},
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "The final sorted list is [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]\nFinal Answer: [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]",
"additional_kwargs": {}
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 110,
"prompt_tokens": 619,
"total_tokens": 729
},
"model_name": "gpt-3.5-turbo"
},
"run": null
}
[chain/end] [1:chain:AgentExecutor > 8:chain:LLMChain] [3.69s] Exiting Chain run with output:
{
"text": "The final sorted list is [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]\nFinal Answer: [['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]"
}
[chain/end] [1:chain:AgentExecutor] [11.67s] Exiting Chain run with output:
{
"output": "[['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]"
}
[['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Harrison', 'Chase'], ['Jen', 'Ayai'], ['Lang', 'Chain'], ['Trance', 'Former']]
3. 自定义工具
3.1 查询日期
from langchain.agents import tool
from datetime import date
@tool
def time(text: str) -> str:
"""返回今天的日期,将其用于与今天的日期相关的任何问题。
输入应始终为空字符串, 此函数将始终返回今天的date,任何日期的数学运算都应在此函数之外发生"""
return str(date.today())
agent1 = initialize_agent(
tools + [time],
llm,
agent=AgentTyp