mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-02 21:23:32 +00:00
Harrison/openapi planner (#2692)
Co-authored-by: Adam McCabe <adam.r.mccabe@gmail.com>
This commit is contained in:
parent
e0a13e9355
commit
1271c00ff0
@ -24,6 +24,7 @@ from langchain.agents.mrkl.base import ZeroShotAgent
|
|||||||
from langchain.agents.tools import Tool
|
from langchain.agents.tools import Tool
|
||||||
from langchain.chains.llm import LLMChain
|
from langchain.chains.llm import LLMChain
|
||||||
from langchain.llms.openai import OpenAI
|
from langchain.llms.openai import OpenAI
|
||||||
|
from langchain.memory import ReadOnlySharedMemory
|
||||||
from langchain.prompts import PromptTemplate
|
from langchain.prompts import PromptTemplate
|
||||||
from langchain.requests import RequestsWrapper
|
from langchain.requests import RequestsWrapper
|
||||||
from langchain.schema import BaseLanguageModel
|
from langchain.schema import BaseLanguageModel
|
||||||
@ -53,7 +54,8 @@ class RequestsGetToolWithParsing(BaseRequestsTool, BaseTool):
|
|||||||
data = json.loads(text)
|
data = json.loads(text)
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
raise e
|
raise e
|
||||||
response = self.requests_wrapper.get(data["url"])
|
data_params = data.get("params")
|
||||||
|
response = self.requests_wrapper.get(data["url"], params=data_params)
|
||||||
response = response[: self.response_length]
|
response = response[: self.response_length]
|
||||||
return self.llm_chain.predict(
|
return self.llm_chain.predict(
|
||||||
response=response, instructions=data["output_instructions"]
|
response=response, instructions=data["output_instructions"]
|
||||||
@ -183,6 +185,7 @@ def create_openapi_agent(
|
|||||||
api_spec: ReducedOpenAPISpec,
|
api_spec: ReducedOpenAPISpec,
|
||||||
requests_wrapper: RequestsWrapper,
|
requests_wrapper: RequestsWrapper,
|
||||||
llm: BaseLanguageModel,
|
llm: BaseLanguageModel,
|
||||||
|
shared_memory: Optional[ReadOnlySharedMemory] = None,
|
||||||
) -> AgentExecutor:
|
) -> AgentExecutor:
|
||||||
"""Instantiate API planner and controller for a given spec.
|
"""Instantiate API planner and controller for a given spec.
|
||||||
|
|
||||||
@ -207,7 +210,7 @@ def create_openapi_agent(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
agent = ZeroShotAgent(
|
agent = ZeroShotAgent(
|
||||||
llm_chain=LLMChain(llm=llm, prompt=prompt),
|
llm_chain=LLMChain(llm=llm, prompt=prompt, memory=shared_memory),
|
||||||
allowed_tools=[tool.name for tool in tools],
|
allowed_tools=[tool.name for tool in tools],
|
||||||
)
|
)
|
||||||
return AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)
|
return AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)
|
||||||
|
@ -40,7 +40,7 @@ Here are endpoints you can use. Do not reference any of the endpoints above.
|
|||||||
User query: {query}
|
User query: {query}
|
||||||
Plan:"""
|
Plan:"""
|
||||||
API_PLANNER_TOOL_NAME = "api_planner"
|
API_PLANNER_TOOL_NAME = "api_planner"
|
||||||
API_PLANNER_TOOL_DESCRIPTION = f"Can be used to generate the right API calls to assist with a user query, like {API_PLANNER_TOOL_NAME}(query). Should always be called before trying to calling the API controller."
|
API_PLANNER_TOOL_DESCRIPTION = f"Can be used to generate the right API calls to assist with a user query, like {API_PLANNER_TOOL_NAME}(query). Should always be called before trying to call the API controller."
|
||||||
|
|
||||||
# Execution.
|
# Execution.
|
||||||
API_CONTROLLER_PROMPT = """You are an agent that gets a sequence of API calls and given their documentation, should execute them and return the final response.
|
API_CONTROLLER_PROMPT = """You are an agent that gets a sequence of API calls and given their documentation, should execute them and return the final response.
|
||||||
@ -81,7 +81,7 @@ API_CONTROLLER_TOOL_DESCRIPTION = f"Can be used to execute a plan of API calls,
|
|||||||
# The goal is to have an agent at the top-level (e.g. so it can recover from errors and re-plan) while
|
# The goal is to have an agent at the top-level (e.g. so it can recover from errors and re-plan) while
|
||||||
# keeping planning (and specifically the planning prompt) simple.
|
# keeping planning (and specifically the planning prompt) simple.
|
||||||
API_ORCHESTRATOR_PROMPT = """You are an agent that assists with user queries against API, things like querying information or creating resources.
|
API_ORCHESTRATOR_PROMPT = """You are an agent that assists with user queries against API, things like querying information or creating resources.
|
||||||
Some user queries can be resolved in a single API call though some require several API call.
|
Some user queries can be resolved in a single API call, particularly if you can find appropriate params from the OpenAPI spec; though some require several API call.
|
||||||
You should always plan your API calls first, and then execute the plan second.
|
You should always plan your API calls first, and then execute the plan second.
|
||||||
You should never return information without executing the api_controller tool.
|
You should never return information without executing the api_controller tool.
|
||||||
|
|
||||||
@ -106,12 +106,12 @@ User query: can you add some trendy stuff to my shopping cart.
|
|||||||
Thought: I should plan API calls first.
|
Thought: I should plan API calls first.
|
||||||
Action: api_planner
|
Action: api_planner
|
||||||
Action Input: I need to find the right API calls to add trendy items to the users shopping cart
|
Action Input: I need to find the right API calls to add trendy items to the users shopping cart
|
||||||
Observation: 1) GET /items/trending to get trending item ids
|
Observation: 1) GET /items with params 'trending' is 'True' to get trending item ids
|
||||||
2) GET /user to get user
|
2) GET /user to get user
|
||||||
3) POST /cart to post the trending items to the user's cart
|
3) POST /cart to post the trending items to the user's cart
|
||||||
Thought: I'm ready to execute the API calls.
|
Thought: I'm ready to execute the API calls.
|
||||||
Action: api_controller
|
Action: api_controller
|
||||||
Action Input: 1) GET /items/trending to get trending item ids
|
Action Input: 1) GET /items params 'trending' is 'True' to get trending item ids
|
||||||
2) GET /user to get user
|
2) GET /user to get user
|
||||||
3) POST /cart to post the trending items to the user's cart
|
3) POST /cart to post the trending items to the user's cart
|
||||||
...
|
...
|
||||||
@ -123,8 +123,12 @@ Thought: I should generate a plan to help with this query and then copy that pla
|
|||||||
{agent_scratchpad}"""
|
{agent_scratchpad}"""
|
||||||
|
|
||||||
REQUESTS_GET_TOOL_DESCRIPTION = """Use this to GET content from a website.
|
REQUESTS_GET_TOOL_DESCRIPTION = """Use this to GET content from a website.
|
||||||
Input to the tool should be a json string with 2 keys: "url" and "output_instructions".
|
Input to the tool should be a json string with 3 keys: "url", "params" and "output_instructions".
|
||||||
The value of "url" should be a string. The value of "output_instructions" should be instructions on what information to extract from the response, for example the id(s) for a resource(s) that the GET request fetches.
|
The value of "url" should be a string.
|
||||||
|
The value of "params" should be a dict of the needed and available parameters from the OpenAPI spec related to the endpoint.
|
||||||
|
If parameters are not needed, or not available, leave it empty.
|
||||||
|
The value of "output_instructions" should be instructions on what information to extract from the response,
|
||||||
|
for example the id(s) for a resource(s) that the GET request fetches.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PARSING_GET_PROMPT = PromptTemplate(
|
PARSING_GET_PROMPT = PromptTemplate(
|
||||||
|
Loading…
Reference in New Issue
Block a user