From b83e8265102514d1722b2fb1aad29763c5cad62a Mon Sep 17 00:00:00 2001 From: Harrison Chase Date: Fri, 24 Mar 2023 12:30:08 -0700 Subject: [PATCH] plugin tool (#1974) --- .../agents/examples/chatgpt_plugins.ipynb | 119 ++++++++++++++++++ langchain/tools/__init__.py | 3 +- langchain/tools/plugin.py | 34 +++++ pyproject.toml | 2 +- 4 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 docs/modules/agents/examples/chatgpt_plugins.ipynb create mode 100644 langchain/tools/plugin.py diff --git a/docs/modules/agents/examples/chatgpt_plugins.ipynb b/docs/modules/agents/examples/chatgpt_plugins.ipynb new file mode 100644 index 00000000..2bb14b0e --- /dev/null +++ b/docs/modules/agents/examples/chatgpt_plugins.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3f34700b", + "metadata": {}, + "source": [ + "# ChatGPT Plugins\n", + "\n", + "This example shows how to use ChatGPT Plugins within LangChain abstractions.\n", + "\n", + "Note 1: This currently only works for plugins with no auth.\n", + "\n", + "Note 2: There are almost certainly other ways to do this, this is just a first pass. If you have better ideas, please open a PR!" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d41405b5", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.chat_models import ChatOpenAI\n", + "from langchain.agents import load_tools, initialize_agent\n", + "from langchain.tools import AIPluginTool" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d9e61df5", + "metadata": {}, + "outputs": [], + "source": [ + "tool = AIPluginTool.from_plugin_url(\"https://www.klarna.com/.well-known/ai-plugin.json\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "edc0ea0e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mI need to check the Klarna Shopping API to see if it has information on available t shirts.\n", + "Action: KlarnaProducts\n", + "Action Input: None\u001b[0m\n", + "Observation: \u001b[33;1m\u001b[1;3mUsage Guide: Use the Klarna plugin to get relevant product suggestions for any shopping or researching purpose. The query to be sent should not include stopwords like articles, prepositions and determinants. The api works best when searching for words that are related to products, like their name, brand, model or category. Links will always be returned and should be shown to the user.\n", + "\n", + "OpenAPI Spec: {'openapi': '3.0.1', 'info': {'version': 'v0', 'title': 'Open AI Klarna product Api'}, 'servers': [{'url': 'https://www.klarna.com/us/shopping'}], 'tags': [{'name': 'open-ai-product-endpoint', 'description': 'Open AI Product Endpoint. Query for products.'}], 'paths': {'/public/openai/v0/products': {'get': {'tags': ['open-ai-product-endpoint'], 'summary': 'API for fetching Klarna product information', 'operationId': 'productsUsingGET', 'parameters': [{'name': 'q', 'in': 'query', 'description': 'query, must be between 2 and 100 characters', 'required': True, 'schema': {'type': 'string'}}, {'name': 'size', 'in': 'query', 'description': 'number of products returned', 'required': False, 'schema': {'type': 'integer'}}, {'name': 'budget', 'in': 'query', 'description': 'maximum price of the matching product in local currency, filters results', 'required': False, 'schema': {'type': 'integer'}}], 'responses': {'200': {'description': 'Products found', 'content': {'application/json': {'schema': {'$ref': '#/components/schemas/ProductResponse'}}}}, '503': {'description': 'one or more services are unavailable'}}, 'deprecated': False}}}, 'components': {'schemas': {'Product': {'type': 'object', 'properties': {'attributes': {'type': 'array', 'items': {'type': 'string'}}, 'name': {'type': 'string'}, 'price': {'type': 'string'}, 'url': {'type': 'string'}}, 'title': 'Product'}, 'ProductResponse': {'type': 'object', 'properties': {'products': {'type': 'array', 'items': {'$ref': '#/components/schemas/Product'}}}, 'title': 'ProductResponse'}}}}\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mI need to use the Klarna Shopping API to search for t shirts.\n", + "Action: requests_get\n", + "Action Input: https://www.klarna.com/us/shopping/public/openai/v0/products?q=t%20shirts\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3m{\"products\":[{\"name\":\"Lacoste Men's Pack of Plain T-Shirts\",\"url\":\"https://www.klarna.com/us/shopping/pl/cl10001/3202043025/Clothing/Lacoste-Men-s-Pack-of-Plain-T-Shirts/?source=openai\",\"price\":\"$28.99\",\"attributes\":[\"Material:Cotton\",\"Target Group:Man\",\"Color:White,Black\"]},{\"name\":\"Hanes Men's Ultimate 6pk. Crewneck T-Shirts\",\"url\":\"https://www.klarna.com/us/shopping/pl/cl10001/3201808270/Clothing/Hanes-Men-s-Ultimate-6pk.-Crewneck-T-Shirts/?source=openai\",\"price\":\"$13.40\",\"attributes\":[\"Material:Cotton\",\"Target Group:Man\",\"Color:White\"]},{\"name\":\"Nike Boy's Jordan Stretch T-shirts\",\"url\":\"https://www.klarna.com/us/shopping/pl/cl359/3201863202/Children-s-Clothing/Nike-Boy-s-Jordan-Stretch-T-shirts/?source=openai\",\"price\":\"$14.99\",\"attributes\":[\"Color:White,Green\",\"Model:Boy\",\"Pattern:Solid Color\",\"Size (Small-Large):S,XL,L,M\"]},{\"name\":\"Polo Classic Fit Cotton V-Neck T-Shirts 3-Pack\",\"url\":\"https://www.klarna.com/us/shopping/pl/cl10001/3203028500/Clothing/Polo-Classic-Fit-Cotton-V-Neck-T-Shirts-3-Pack/?source=openai\",\"price\":\"$29.95\",\"attributes\":[\"Material:Cotton\",\"Target Group:Man\",\"Color:White,Blue,Black\"]},{\"name\":\"adidas Comfort T-shirts Men's 3-pack\",\"url\":\"https://www.klarna.com/us/shopping/pl/cl10001/3202640533/Clothing/adidas-Comfort-T-shirts-Men-s-3-pack/?source=openai\",\"price\":\"$14.99\",\"attributes\":[\"Material:Cotton\",\"Target Group:Man\",\"Color:White,Black\",\"Pattern:Solid Color\"]}]}\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mThe available t shirts on Klarna are Lacoste Men's Pack of Plain T-Shirts, Hanes Men's Ultimate 6pk. Crewneck T-Shirts, Nike Boy's Jordan Stretch T-shirts, Polo Classic Fit Cotton V-Neck T-Shirts 3-Pack, and adidas Comfort T-shirts Men's 3-pack.\n", + "Final Answer: The available t shirts on Klarna are Lacoste Men's Pack of Plain T-Shirts, Hanes Men's Ultimate 6pk. Crewneck T-Shirts, Nike Boy's Jordan Stretch T-shirts, Polo Classic Fit Cotton V-Neck T-Shirts 3-Pack, and adidas Comfort T-shirts Men's 3-pack.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "\"The available t shirts on Klarna are Lacoste Men's Pack of Plain T-Shirts, Hanes Men's Ultimate 6pk. Crewneck T-Shirts, Nike Boy's Jordan Stretch T-shirts, Polo Classic Fit Cotton V-Neck T-Shirts 3-Pack, and adidas Comfort T-shirts Men's 3-pack.\"" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "llm = ChatOpenAI(temperature=0)\n", + "tools = load_tools([\"requests\"] )\n", + "tools += [tool]\n", + "\n", + "agent_chain = initialize_agent(tools, llm, agent=\"zero-shot-react-description\", verbose=True)\n", + "\n", + "agent_chain.run(\"what t shirts are available in klarna?\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e49318a4", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/langchain/tools/__init__.py b/langchain/tools/__init__.py index fcacd361..46e8dc9a 100644 --- a/langchain/tools/__init__.py +++ b/langchain/tools/__init__.py @@ -2,5 +2,6 @@ from langchain.tools.base import BaseTool from langchain.tools.ifttt import IFTTTWebhook +from langchain.tools.plugin import AIPluginTool -__all__ = ["BaseTool", "IFTTTWebhook"] +__all__ = ["BaseTool", "IFTTTWebhook", "AIPluginTool"] diff --git a/langchain/tools/plugin.py b/langchain/tools/plugin.py new file mode 100644 index 00000000..efac2faf --- /dev/null +++ b/langchain/tools/plugin.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import requests + +from langchain.tools.base import BaseTool + + +class AIPluginTool(BaseTool): + api_spec: str + + @classmethod + def from_plugin_url(cls, url: str) -> AIPluginTool: + response = requests.get(url).json() + description = ( + f"Call this tool to get the OpenAPI spec (and usage guide) " + f"for interacting with the {response['name_for_human']} API. " + f"You should only call this ONCE! What is the " + f"{response['name_for_human']} API useful for? " + ) + response["description_for_human"] + api_spec = ( + f"Usage Guide: {response['description_for_model']}\n\n" + f"OpenAPI Spec: {requests.get(response['api']['url']).json()}" + ) + return cls( + name=response["name_for_model"], description=description, api_spec=api_spec + ) + + def _run(self, tool_input: str) -> str: + """Use the tool.""" + return self.api_spec + + async def _arun(self, tool_input: str) -> str: + """Use the tool asynchronously.""" + return self.api_spec diff --git a/pyproject.toml b/pyproject.toml index 7ec21cc8..07adfff0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langchain" -version = "0.0.122" +version = "0.0.123" description = "Building applications with LLMs through composability" authors = [] license = "MIT"