-
Notifications
You must be signed in to change notification settings - Fork 16.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cli[patch]: tool integration templates (#24837)
Co-authored-by: Erick Friis <[email protected]>
- Loading branch information
Showing
4 changed files
with
410 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
278 changes: 278 additions & 0 deletions
278
libs/cli/langchain_cli/integration_template/docs/tools.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "raw", | ||
"id": "10238e62-3465-4973-9279-606cbb7ccf16", | ||
"metadata": {}, | ||
"source": [ | ||
"---\n", | ||
"sidebar_label: __ModuleName__\n", | ||
"---" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "a6f91f20", | ||
"metadata": {}, | ||
"source": [ | ||
"# __ModuleName__\n", | ||
"\n", | ||
"- TODO: Make sure API reference link is correct.\n", | ||
"\n", | ||
"This notebook provides a quick overview for getting started with __ModuleName__ [tool](/docs/integrations/tools/). For detailed documentation of all __ModuleName__ features and configurations head to the [API reference](https://api.python.langchain.com/en/latest/tools/langchain_community.tools.__module_name__.tool.__ModuleName__.html).\n", | ||
"\n", | ||
"- TODO: Add any other relevant links, like information about underlying API, etc.\n", | ||
"\n", | ||
"## Overview\n", | ||
"\n", | ||
"### Integration details\n", | ||
"\n", | ||
"- TODO: Make sure links and features are correct\n", | ||
"\n", | ||
"| Class | Package | Serializable | [JS support](https://js.langchain.com/v0.2/docs/integrations/tools/__module_name__) | Package latest |\n", | ||
"| :--- | :--- | :---: | :---: | :---: |\n", | ||
"| [__ModuleName__](https://api.python.langchain.com/en/latest/tools/langchain_community.tools.__module_name__.tool.__ModuleName__.html) | [langchain-community](https://api.python.langchain.com/en/latest/community_api_reference.html) | beta/❌ | ✅/❌ | ![PyPI - Version](https://img.shields.io/pypi/v/langchain-community?style=flat-square&label=%20) |\n", | ||
"\n", | ||
"### Tool features\n", | ||
"\n", | ||
"- TODO: Add feature table if it makes sense\n", | ||
"\n", | ||
"\n", | ||
"## Setup\n", | ||
"\n", | ||
"- TODO: Add any additional deps\n", | ||
"\n", | ||
"The integration lives in the `langchain-community` package." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "f85b4089", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%pip install --quiet -U langchain-community" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "b15e9266", | ||
"metadata": {}, | ||
"source": [ | ||
"### Credentials\n", | ||
"\n", | ||
"- TODO: Add any credentials that are needed" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"id": "e0b178a2-8816-40ca-b57c-ccdd86dde9c9", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import getpass\n", | ||
"import os\n", | ||
"\n", | ||
"# if not os.environ.get(\"__MODULE_NAME___API_KEY\"):\n", | ||
"# os.environ[\"__MODULE_NAME___API_KEY\"] = getpass.getpass(\"__MODULE_NAME__ API key:\\n\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "bc5ab717-fd27-4c59-b912-bdd099541478", | ||
"metadata": {}, | ||
"source": [ | ||
"It's also helpful (but not needed) to set up [LangSmith](https://smith.langchain.com/) for best-in-class observability:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"id": "a6c2f136-6367-4f1f-825d-ae741e1bf281", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n", | ||
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "1c97218f-f366-479d-8bf7-fe9f2f6df73f", | ||
"metadata": {}, | ||
"source": [ | ||
"## Instantiation\n", | ||
"\n", | ||
"- TODO: Fill in instantiation params\n", | ||
"\n", | ||
"Here we show how to instatiate an instance of the __ModuleName__ tool, with " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"id": "8b3ddfe9-ca79-494c-a7ab-1f56d9407a64", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from langchain_community.tools import __ModuleName__\n", | ||
"\n", | ||
"\n", | ||
"tool = __ModuleName__(\n", | ||
" ...\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "74147a1a", | ||
"metadata": {}, | ||
"source": [ | ||
"## Invocation\n", | ||
"\n", | ||
"### [Invoke directly with args](/docs/concepts/#invoke-with-just-the-arguments)\n", | ||
"\n", | ||
"- TODO: Describe what the tool args are, fill them in, run cell" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "65310a8b-eb0c-4d9e-a618-4f4abe2414fc", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"tool.invoke({...})" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "d6e73897", | ||
"metadata": {}, | ||
"source": [ | ||
"### [Invoke with ToolCall](/docs/concepts/#invoke-with-toolcall)\n", | ||
"\n", | ||
"We can also invoke the tool with a model-generated ToolCall, in which case a ToolMessage will be returned:\n", | ||
"\n", | ||
"- TODO: Fill in tool args and run cell" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "f90e33a7", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# This is usually generated by a model, but we'll create a tool call directly for demo purposes.\n", | ||
"model_generated_tool_call = {\n", | ||
" \"args\": {...}, # TODO: FILL IN\n", | ||
" \"id\": \"1\",\n", | ||
" \"name\": tool.name,\n", | ||
" \"type\": \"tool_call\",\n", | ||
"}\n", | ||
"tool.invoke(model_generated_tool_call)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "659f9fbd-6fcf-445f-aa8c-72d8e60154bd", | ||
"metadata": {}, | ||
"source": [ | ||
"## Chaining\n", | ||
"\n", | ||
"- TODO: Add user question and run cells\n", | ||
"\n", | ||
"We can use our tool in a chain by first binding it to a [tool-calling model](/docs/how_to/tool_calling/) and then calling it:\n", | ||
"\n", | ||
"import ChatModelTabs from \"@theme/ChatModelTabs\";\n", | ||
"\n", | ||
"<ChatModelTabs customVarName=\"llm\" />\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 16, | ||
"id": "af3123ad-7a02-40e5-b58e-7d56e23e5830", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# | output: false\n", | ||
"# | echo: false\n", | ||
"\n", | ||
"# !pip install -qU langchain langchain-openai\n", | ||
"from langchain.chat_models import init_chat_model\n", | ||
"\n", | ||
"llm = init_chat_model(model=\"gpt-4o\", model_provider=\"openai\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "fdbf35b5-3aaf-4947-9ec6-48c21533fb95", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from langchain_core.prompts import ChatPromptTemplate\n", | ||
"from langchain_core.runnables import RunnableConfig, chain\n", | ||
"\n", | ||
"prompt = ChatPromptTemplate(\n", | ||
" [\n", | ||
" (\"system\", \"You are a helpful assistant.\"),\n", | ||
" (\"human\", \"{user_input}\"),\n", | ||
" (\"placeholder\", \"{messages}\"),\n", | ||
" ]\n", | ||
")\n", | ||
"\n", | ||
"# specifying tool_choice will force the model to call this tool.\n", | ||
"llm_with_tools = llm.bind_tools([tool], tool_choice=tool.name)\n", | ||
"\n", | ||
"llm_chain = prompt | llm_with_tools\n", | ||
"\n", | ||
"\n", | ||
"@chain\n", | ||
"def tool_chain(user_input: str, config: RunnableConfig):\n", | ||
" input_ = {\"user_input\": user_input}\n", | ||
" ai_msg = llm_chain.invoke(input_, config=config)\n", | ||
" tool_msgs = tool.batch(ai_msg.tool_calls, config=config)\n", | ||
" return llm_chain.invoke({**input_, \"messages\": [ai_msg, *tool_msgs]}, config=config)\n", | ||
"\n", | ||
"\n", | ||
"tool_chain.invoke(\"...\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "4ac8146c", | ||
"metadata": {}, | ||
"source": [ | ||
"## API reference\n", | ||
"\n", | ||
"For detailed documentation of all __ModuleName__ features and configurations head to the API reference: https://api.python.langchain.com/en/latest/tools/langchain_community.tools.__module_name__.tool.__ModuleName__.html" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "poetry-venv-311", | ||
"language": "python", | ||
"name": "poetry-venv-311" | ||
}, | ||
"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.11.9" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
93 changes: 93 additions & 0 deletions
93
libs/cli/langchain_cli/integration_template/integration_template/tools.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
"""__ModuleName__ tools.""" | ||
|
||
from typing import Optional, Type | ||
|
||
from langchain_core.callbacks import ( | ||
AsyncCallbackManagerForToolRun, | ||
CallbackManagerForToolRun, | ||
) | ||
from langchain_core.pydantic_v1 import BaseModel, Field | ||
from langchain_core.tools import BaseTool | ||
|
||
|
||
class __ModuleName__Input(BaseModel): | ||
"""Input schema for __ModuleName__ tool. | ||
This docstring is **not** part of what is sent to the model when performing tool | ||
calling. The Field default values and descriptions **are** part of what is sent to | ||
the model when performing tool calling. | ||
""" | ||
|
||
# TODO: Add input args and descriptions. | ||
# a: int = Field(..., description="first number") | ||
# b: int = Field(0, description="second number") | ||
... | ||
|
||
|
||
class __ModuleName__Tool(BaseTool): | ||
"""__ModuleName__ tool. | ||
Setup: | ||
# TODO: Replace with relevant packages, env vars. | ||
Install ``__package_name__`` and set environment variable ``__MODULE_NAME___API_KEY``. | ||
.. code-block:: bash | ||
pip install -U __package_name__ | ||
export __MODULE_NAME___API_KEY="your-api-key" | ||
Instantiation: | ||
.. code-block:: python | ||
tool = __ModuleName__Tool( | ||
# TODO: init params | ||
) | ||
Invocation with args: | ||
.. code-block:: python | ||
# TODO: invoke args | ||
tool.invoke({...}) | ||
.. code-block:: python | ||
# TODO: output of invocation | ||
Invocation with ToolCall: | ||
.. code-block:: python | ||
# TODO: invoke args | ||
tool.invoke({"args": {...}, "id": "1", "name": tool.name, "type": "tool_call}) | ||
.. code-block:: python | ||
# TODO: output of invocation | ||
""" | ||
|
||
# TODO: Set tool name and description | ||
name: str = "TODO: Tool name" | ||
"""The name that is passed to the model when performing tool calling.""" | ||
description: str = "TODO: Tool description." | ||
"""The description that is passed to the model when performing tool calling.""" | ||
args_schema: Type[BaseModel] = __ModuleName__Input | ||
"""The schema that is passed to the model when performing tool calling.""" | ||
|
||
# TODO: Add any other init params for the tool. | ||
# param1: Optional[str] | ||
# """param1 determines foobar""" | ||
|
||
# TODO: Replaced *args with real tool arguments. | ||
def _run( | ||
self, *args, run_manager: Optional[CallbackManagerForToolRun] = None | ||
) -> str: | ||
raise NotImplementedError | ||
|
||
# TODO: Implement if tool has native async functionality, otherwise delete. | ||
|
||
# async def _arun( | ||
# self, | ||
# *args, | ||
# run_manager: Optional[AsyncCallbackManagerForToolRun] = None, | ||
# ) -> str: | ||
# ... |
Oops, something went wrong.