forked from langchain-ai/langchain
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add serialization guide (langchain-ai#23223)
- Loading branch information
Showing
2 changed files
with
307 additions
and
0 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
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,305 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "ab3dc782-321e-4503-96ee-ac88a15e4b5e", | ||
"metadata": {}, | ||
"source": [ | ||
"# How to save and load LangChain objects\n", | ||
"\n", | ||
"LangChain classes implement standard methods for serialization. Serializing LangChain objects using these methods confer some advantages:\n", | ||
"\n", | ||
"- Secrets, such as API keys, are separated from other parameters and can be loaded back to the object on de-serialization;\n", | ||
"- De-serialization is kept compatible across package versions, so objects that were serialized with one version of LangChain can be properly de-serialized with another.\n", | ||
"\n", | ||
"To save and load LangChain objects using this system, use the `dumpd`, `dumps`, `load`, and `loads` functions in the [load module](https://api.python.langchain.com/en/latest/core_api_reference.html#module-langchain_core.load) of `langchain-core`. These functions support JSON and JSON-serializable objects.\n", | ||
"\n", | ||
"All LangChain objects that inherit from [Serializable](https://api.python.langchain.com/en/latest/load/langchain_core.load.serializable.Serializable.html) are JSON-serializable. Examples include [messages](https://api.python.langchain.com/en/latest/core_api_reference.html#module-langchain_core.messages), [document objects](https://api.python.langchain.com/en/latest/documents/langchain_core.documents.base.Document.html) (e.g., as returned from [retrievers](/docs/concepts/#retrievers)), and most [Runnables](/docs/concepts/#langchain-expression-language-lcel), such as chat models, retrievers, and [chains](/docs/how_to/sequence) implemented with the LangChain Expression Language.\n", | ||
"\n", | ||
"Below we walk through an example with a simple [LLM chain](/docs/tutorials/llm_chain).\n", | ||
"\n", | ||
":::{.callout-caution}\n", | ||
"\n", | ||
"De-serialization using `load` and `loads` can instantiate any serializable LangChain object. Only use this feature with trusted inputs!\n", | ||
"\n", | ||
"De-serialization is a beta feature and is subject to change.\n", | ||
":::" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 12, | ||
"id": "f85d9e51-2a36-4f69-83b1-c716cd43f790", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from langchain_core.load import dumpd, dumps, load, loads\n", | ||
"from langchain_core.prompts import ChatPromptTemplate\n", | ||
"from langchain_openai import ChatOpenAI\n", | ||
"\n", | ||
"prompt = ChatPromptTemplate.from_messages(\n", | ||
" [\n", | ||
" (\"system\", \"Translate the following into {language}:\"),\n", | ||
" (\"user\", \"{text}\"),\n", | ||
" ],\n", | ||
")\n", | ||
"\n", | ||
"llm = ChatOpenAI(model=\"gpt-3.5-turbo-0125\", api_key=\"llm-api-key\")\n", | ||
"\n", | ||
"chain = prompt | llm" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "356ea99f-5cb5-4433-9a6c-2443d2be9ed3", | ||
"metadata": {}, | ||
"source": [ | ||
"## Saving objects\n", | ||
"\n", | ||
"### To json" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"id": "26516764-d46b-4357-a6c6-bd8315bfa530", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"{\n", | ||
" \"lc\": 1,\n", | ||
" \"type\": \"constructor\",\n", | ||
" \"id\": [\n", | ||
" \"langchain\",\n", | ||
" \"schema\",\n", | ||
" \"runnable\",\n", | ||
" \"RunnableSequence\"\n", | ||
" ],\n", | ||
" \"kwargs\": {\n", | ||
" \"first\": {\n", | ||
" \"lc\": 1,\n", | ||
" \"type\": \"constructor\",\n", | ||
" \"id\": [\n", | ||
" \"langchain\",\n", | ||
" \"prompts\",\n", | ||
" \"chat\",\n", | ||
" \"ChatPromptTemplate\"\n", | ||
" ],\n", | ||
" \"kwargs\": {\n", | ||
" \"input_variables\": [\n", | ||
" \"language\",\n", | ||
" \"text\"\n", | ||
" ],\n", | ||
" \"messages\": [\n", | ||
" {\n", | ||
" \"lc\": 1,\n", | ||
" \"type\": \"constructor\",\n", | ||
" \n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"string_representation = dumps(chain, pretty=True)\n", | ||
"print(string_representation[:500])" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "bd425716-545d-466b-a4e5-dc9952cfd72a", | ||
"metadata": {}, | ||
"source": [ | ||
"### To a json-serializable Python dict" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"id": "6561a968-1741-4419-8c29-e705b9d0ef39", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"<class 'dict'>\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"dict_representation = dumpd(chain)\n", | ||
"\n", | ||
"print(type(dict_representation))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "711e986e-dd24-4839-9e38-c57903378a5f", | ||
"metadata": {}, | ||
"source": [ | ||
"### To disk" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"id": "f818378b-f4d6-43a7-895b-76cf7359b157", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import json\n", | ||
"\n", | ||
"with open(\"/tmp/chain.json\", \"w\") as fp:\n", | ||
" json.dump(string_representation, fp)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "1e621a32-ff5f-4627-ad59-88cacba73c6b", | ||
"metadata": {}, | ||
"source": [ | ||
"Note that the API key is withheld from the serialized representations. Parameters that are considered secret are specified by the `.lc_secrets` attribute of the LangChain object:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"id": "8225e150-000a-4fbc-9f3d-09568f4b560b", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"{'openai_api_key': 'OPENAI_API_KEY'}" | ||
] | ||
}, | ||
"execution_count": 5, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"chain.last.lc_secrets" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "6d090177-eb1c-4bfb-8c13-29286afe17d9", | ||
"metadata": {}, | ||
"source": [ | ||
"## Loading objects\n", | ||
"\n", | ||
"Specifying `secrets_map` in `load` and `loads` will load the corresponding secrets onto the de-serialized LangChain object.\n", | ||
"\n", | ||
"### From string" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 7, | ||
"id": "54a66267-5f3a-40a2-bfcc-8b44bb24c154", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"chain = loads(string_representation, secrets_map={\"OPENAI_API_KEY\": \"llm-api-key\"})" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "5ed9aff1-92cc-44ba-b2ec-4d12f924fa03", | ||
"metadata": {}, | ||
"source": [ | ||
"### From dict" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 9, | ||
"id": "76979932-13de-4427-9f88-040fb05a6778", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"chain = load(dict_representation, secrets_map={\"OPENAI_API_KEY\": \"llm-api-key\"})" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "7dd81a2a-5163-414d-ab42-f1c35e30471b", | ||
"metadata": {}, | ||
"source": [ | ||
"### From disk" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 10, | ||
"id": "033f62a7-3377-472a-be58-718baa6ab445", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"with open(\"/tmp/chain.json\", \"r\") as fp:\n", | ||
" chain = loads(json.load(fp), secrets_map={\"OPENAI_API_KEY\": \"llm-api-key\"})" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "dc520fdb-035a-468f-a8a8-c3ffe8ed98eb", | ||
"metadata": {}, | ||
"source": [ | ||
"Note that we recover the API key specified at the start of the guide:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 11, | ||
"id": "566b2475-d9b4-432b-8c3b-27c2f183624e", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"'llm-api-key'" | ||
] | ||
}, | ||
"execution_count": 11, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"chain.last.openai_api_key.get_secret_value()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "7b4cba53-e1d5-4979-927e-b5794a02afc3", | ||
"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.10.4" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |