From 803b2b37e20b4b693bcd3f3b390f5bee36a6320d Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Thu, 18 Apr 2024 20:41:49 -0700 Subject: [PATCH] Merge, update structured output guide --- .../resolve_versioned_links_in_markdown.py | 6 +- .../HTML_header_metadata_splitter.ipynb} | 0 .../HTML_section_aware_splitter.ipynb | 0 .../MultiQueryRetriever.ipynb | 0 .../character_text_splitter.ipynb | 0 .../code_splitter.ipynb | 0 .../contextual_compression.ipynb | 0 .../custom_retriever.ipynb | 0 .../document_loader_csv.mdx} | 0 .../document_loader_directory.mdx} | 0 .../document_loader_html.mdx} | 0 .../document_loader_json.mdx} | 0 .../document_loader_markdown.mdx} | 0 .../document_loader_office_file.mdx} | 0 .../document_loader_pdf.mdx} | 0 .../ensemble_retriever.ipynb} | 0 .../long_context_reorder.ipynb | 0 .../markdown_header_metadata_splitter.ipynb} | 0 .../retrievers => how_to}/multi_vector.ipynb | 0 .../parent_document_retriever.ipynb | 0 .../recursive_json_splitter.ipynb | 0 .../recursive_text_splitter.ipynb | 0 .../retrievers => how_to}/self_query.ipynb | 0 .../semantic-chunker.ipynb | 0 .../split_by_token.ipynb | 0 .../how_to/structured_output.ipynb | 877 +++++++++--------- .../text_embedding.ipynb} | 0 .../time_weighted_vectorstore.ipynb | 0 .../vectorstore_retriever.ipynb} | 0 .../index.mdx => how_to/vectorstores.mdx} | 0 .../version-0.2.x/how_to_guides.md | 62 +- .../data_connection/text_embedding/index.mdx | 129 --- 32 files changed, 466 insertions(+), 608 deletions(-) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers/HTML_header_metadata.ipynb => how_to/HTML_header_metadata_splitter.ipynb} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers => how_to}/HTML_section_aware_splitter.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/MultiQueryRetriever.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers => how_to}/character_text_splitter.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers => how_to}/code_splitter.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/contextual_compression.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/custom_retriever.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_loaders/csv.mdx => how_to/document_loader_csv.mdx} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_loaders/file_directory.mdx => how_to/document_loader_directory.mdx} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_loaders/html.mdx => how_to/document_loader_html.mdx} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_loaders/json.mdx => how_to/document_loader_json.mdx} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_loaders/markdown.mdx => how_to/document_loader_markdown.mdx} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_loaders/office_file.mdx => how_to/document_loader_office_file.mdx} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_loaders/pdf.mdx => how_to/document_loader_pdf.mdx} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers/ensemble.ipynb => how_to/ensemble_retriever.ipynb} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/long_context_reorder.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers/markdown_header_metadata.ipynb => how_to/markdown_header_metadata_splitter.ipynb} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/multi_vector.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/parent_document_retriever.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers => how_to}/recursive_json_splitter.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers => how_to}/recursive_text_splitter.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/self_query.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers => how_to}/semantic-chunker.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/document_transformers => how_to}/split_by_token.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/text_embedding/caching_embeddings.ipynb => how_to/text_embedding.ipynb} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers => how_to}/time_weighted_vectorstore.ipynb (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/retrievers/vectorstore.ipynb => how_to/vectorstore_retriever.ipynb} (100%) rename docs/versioned_docs/version-0.2.x/{modules/data_connection/vectorstores/index.mdx => how_to/vectorstores.mdx} (100%) delete mode 100644 docs/versioned_docs/version-0.2.x/modules/data_connection/text_embedding/index.mdx diff --git a/docs/scripts/resolve_versioned_links_in_markdown.py b/docs/scripts/resolve_versioned_links_in_markdown.py index 81cb50250e1..ccb919f1e03 100644 --- a/docs/scripts/resolve_versioned_links_in_markdown.py +++ b/docs/scripts/resolve_versioned_links_in_markdown.py @@ -7,8 +7,8 @@ DOCS_DIR = Path(os.path.abspath(__file__)).parents[1] def update_links(doc_path, docs_link): - for path in (DOCS_DIR / doc_path).glob('**/*'): - if path.is_file() and path.suffix in ['.md', '.mdx', '.ipynb']: + for path in (DOCS_DIR / doc_path).glob("**/*"): + if path.is_file() and path.suffix in [".md", ".mdx", ".ipynb"]: with open(path, "r") as f: content = f.read() @@ -20,4 +20,4 @@ def update_links(doc_path, docs_link): if __name__ == "__main__": - update_links(sys.argv[1], sys.argv[2]) \ No newline at end of file + update_links(sys.argv[1], sys.argv[2]) diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/HTML_header_metadata.ipynb b/docs/versioned_docs/version-0.2.x/how_to/HTML_header_metadata_splitter.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/HTML_header_metadata.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/HTML_header_metadata_splitter.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/HTML_section_aware_splitter.ipynb b/docs/versioned_docs/version-0.2.x/how_to/HTML_section_aware_splitter.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/HTML_section_aware_splitter.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/HTML_section_aware_splitter.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/MultiQueryRetriever.ipynb b/docs/versioned_docs/version-0.2.x/how_to/MultiQueryRetriever.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/MultiQueryRetriever.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/MultiQueryRetriever.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/character_text_splitter.ipynb b/docs/versioned_docs/version-0.2.x/how_to/character_text_splitter.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/character_text_splitter.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/character_text_splitter.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/code_splitter.ipynb b/docs/versioned_docs/version-0.2.x/how_to/code_splitter.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/code_splitter.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/code_splitter.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/contextual_compression.ipynb b/docs/versioned_docs/version-0.2.x/how_to/contextual_compression.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/contextual_compression.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/contextual_compression.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/custom_retriever.ipynb b/docs/versioned_docs/version-0.2.x/how_to/custom_retriever.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/custom_retriever.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/custom_retriever.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/csv.mdx b/docs/versioned_docs/version-0.2.x/how_to/document_loader_csv.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/csv.mdx rename to docs/versioned_docs/version-0.2.x/how_to/document_loader_csv.mdx diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/file_directory.mdx b/docs/versioned_docs/version-0.2.x/how_to/document_loader_directory.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/file_directory.mdx rename to docs/versioned_docs/version-0.2.x/how_to/document_loader_directory.mdx diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/html.mdx b/docs/versioned_docs/version-0.2.x/how_to/document_loader_html.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/html.mdx rename to docs/versioned_docs/version-0.2.x/how_to/document_loader_html.mdx diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/json.mdx b/docs/versioned_docs/version-0.2.x/how_to/document_loader_json.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/json.mdx rename to docs/versioned_docs/version-0.2.x/how_to/document_loader_json.mdx diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/markdown.mdx b/docs/versioned_docs/version-0.2.x/how_to/document_loader_markdown.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/markdown.mdx rename to docs/versioned_docs/version-0.2.x/how_to/document_loader_markdown.mdx diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/office_file.mdx b/docs/versioned_docs/version-0.2.x/how_to/document_loader_office_file.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/office_file.mdx rename to docs/versioned_docs/version-0.2.x/how_to/document_loader_office_file.mdx diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/pdf.mdx b/docs/versioned_docs/version-0.2.x/how_to/document_loader_pdf.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_loaders/pdf.mdx rename to docs/versioned_docs/version-0.2.x/how_to/document_loader_pdf.mdx diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/ensemble.ipynb b/docs/versioned_docs/version-0.2.x/how_to/ensemble_retriever.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/ensemble.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/ensemble_retriever.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/long_context_reorder.ipynb b/docs/versioned_docs/version-0.2.x/how_to/long_context_reorder.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/long_context_reorder.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/long_context_reorder.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/markdown_header_metadata.ipynb b/docs/versioned_docs/version-0.2.x/how_to/markdown_header_metadata_splitter.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/markdown_header_metadata.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/markdown_header_metadata_splitter.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/multi_vector.ipynb b/docs/versioned_docs/version-0.2.x/how_to/multi_vector.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/multi_vector.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/multi_vector.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/parent_document_retriever.ipynb b/docs/versioned_docs/version-0.2.x/how_to/parent_document_retriever.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/parent_document_retriever.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/parent_document_retriever.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/recursive_json_splitter.ipynb b/docs/versioned_docs/version-0.2.x/how_to/recursive_json_splitter.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/recursive_json_splitter.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/recursive_json_splitter.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/recursive_text_splitter.ipynb b/docs/versioned_docs/version-0.2.x/how_to/recursive_text_splitter.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/recursive_text_splitter.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/recursive_text_splitter.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/self_query.ipynb b/docs/versioned_docs/version-0.2.x/how_to/self_query.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/self_query.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/self_query.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/semantic-chunker.ipynb b/docs/versioned_docs/version-0.2.x/how_to/semantic-chunker.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/semantic-chunker.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/semantic-chunker.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/split_by_token.ipynb b/docs/versioned_docs/version-0.2.x/how_to/split_by_token.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/document_transformers/split_by_token.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/split_by_token.ipynb diff --git a/docs/versioned_docs/version-0.2.x/how_to/structured_output.ipynb b/docs/versioned_docs/version-0.2.x/how_to/structured_output.ipynb index aa0c956ee10..a362c337f9c 100644 --- a/docs/versioned_docs/version-0.2.x/how_to/structured_output.ipynb +++ b/docs/versioned_docs/version-0.2.x/how_to/structured_output.ipynb @@ -15,70 +15,86 @@ "id": "6e3f0f72", "metadata": {}, "source": [ - "# [beta] Structured Output\n", + "# How to return structured data from a model\n", "\n", - "It is often crucial to have LLMs return structured output. This is because oftentimes the outputs of the LLMs are used in downstream applications, where specific arguments are required. Having the LLM return structured output reliably is necessary for that.\n", + "It is often useful to have a model return output that matches some specific schema - for example, you may be using the model alongside another system that requires specific parameters. This guide will show you a few different strategies to do this.\n", "\n", - "There are a few different high level strategies that are used to do this:\n", + "## The `.with_structured_output()` method\n", "\n", - "- Prompting: This is when you ask the LLM (very nicely) to return output in the desired format (JSON, XML). This is nice because it works with all LLMs. It is not nice because there is no guarantee that the LLM returns the output in the right format.\n", - "- Function calling: This is when the LLM is fine-tuned to be able to not just generate a completion, but also generate a function call. The functions the LLM can call are generally passed as extra parameters to the model API. The function names and descriptions should be treated as part of the prompt (they usually count against token counts, and are used by the LLM to decide what to do).\n", - "- Tool calling: A technique similar to function calling, but it allows the LLM to call multiple functions at the same time.\n", - "- JSON mode: This is when the LLM is guaranteed to return JSON.\n", + "There are [several strategies](/docs/concepts/structured_output/) that models can use under the hood. For some of the most popular model providers, including [OpenAI](/docs/integrations/platforms/openai/), [Anthropic](/docs/integrations/platforms/anthropic/), and [Mistral](https://python.langchain.com/docs/integrations/providers/mistralai/), LangChain implements a common interface that abstracts away these strategies called `.with_structured_output`.\n", "\n", + "By invoking this method (and passing in a JSON schema or a Pydantic model) the model will add whatever model parameters + output parsers are necessary to get back structured output matching the requested schema. If the model supports more than one way to do this (e.g., function calling vs JSON mode) - you can configure which method to use by passing into that method.\n", "\n", + "You can find the [current list of models that support this method here](/docs/integrations/chat/).\n", "\n", - "Different models may support different variants of these, with slightly different parameters. In order to make it easy to get LLMs to return structured output, we have added a common interface to LangChain models: `.with_structured_output`. \n", + "Let's look at some examples of this in action! We'll use Pydantic to create a simple response schema.\n", "\n", - "By invoking this method (and passing in a JSON schema or a Pydantic model) the model will add whatever model parameters + output parsers are necessary to get back the structured output. There may be more than one way to do this (e.g., function calling vs JSON mode) - you can configure which method to use by passing into that method.\n", + "```{=mdx}\n", + "import ChatModelTabs from \"@theme/ChatModelTabs\";\n", "\n", - "Let's look at some examples of this in action!\n", + "\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6d55008f", + "metadata": {}, + "outputs": [], + "source": [ + "# | output: false\n", + "# | echo: false\n", "\n", - "We will use Pydantic to easily structure the response schema." + "from langchain_openai import ChatOpenAI\n", + "\n", + "model = ChatOpenAI(\n", + " model=\"gpt-4-0125-preview\",\n", + " temperature=0,\n", + ")" ] }, { "cell_type": "code", "execution_count": 2, - "id": "08029f4e", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_core.pydantic_v1 import BaseModel, Field" - ] - }, - { - "cell_type": "code", - "execution_count": 3, "id": "070bf702", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jacoblee/.pyenv/versions/3.10.5/lib/python3.10/site-packages/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The function `with_structured_output` is in beta. It is actively being worked on, so the API may change.\n", + " warn_beta(\n" + ] + }, + { + "data": { + "text/plain": [ + "Joke(setup='Why was the cat sitting on the computer?', punchline='Because it wanted to keep an eye on the mouse!', rating=None)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ + "from typing import Optional\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "\n", + "\n", "class Joke(BaseModel):\n", " setup: str = Field(description=\"The setup of the joke\")\n", - " punchline: str = Field(description=\"The punchline to the joke\")" - ] - }, - { - "cell_type": "markdown", - "id": "98f6edfa", - "metadata": {}, - "source": [ - "## OpenAI\n", + " punchline: str = Field(description=\"The punchline to the joke\")\n", + " rating: Optional[int] = Field(description=\"How funny the joke is, from 1 to 10\")\n", "\n", - "OpenAI exposes a few different ways to get structured outputs. \n", "\n", - "[API reference](https://api.python.langchain.com/en/latest/chat_models/langchain_openai.chat_models.base.ChatOpenAI.html#langchain_openai.chat_models.base.ChatOpenAI.with_structured_output)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "3fe7caf0", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_openai import ChatOpenAI" + "structured_llm = model.with_structured_output(Joke)\n", + "\n", + "structured_llm.invoke(\"Tell me a joke about cats\")" ] }, { @@ -86,432 +102,109 @@ "id": "deddb6d3", "metadata": {}, "source": [ - "#### Tool/function Calling\n", + "The result is a Pydantic model.\n", "\n", - "By default, we will use `function_calling`" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "6700994a", - "metadata": {}, - "outputs": [], - "source": [ - "model = ChatOpenAI(model=\"gpt-3.5-turbo-0125\", temperature=0)\n", - "structured_llm = model.with_structured_output(Joke)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "c55a61b8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Joke(setup='Why was the cat sitting on the computer?', punchline='It wanted to keep an eye on the mouse!')" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "structured_llm.invoke(\"Tell me a joke about cats\")" - ] - }, - { - "cell_type": "markdown", - "id": "39d7a555", - "metadata": {}, - "source": [ - "#### JSON Mode\n", - "\n", - "We also support JSON mode. Note that we need to specify in the prompt the format that it should respond in." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "df0370e3", - "metadata": {}, - "outputs": [], - "source": [ - "structured_llm = model.with_structured_output(Joke, method=\"json_mode\")" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "23844a26", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Joke(setup=\"Why don't cats play poker in the jungle?\", punchline='Too many cheetahs!')" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "structured_llm.invoke(\n", - " \"Tell me a joke about cats, respond in JSON with `setup` and `punchline` keys\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "8f3cce9e", - "metadata": {}, - "source": [ - "## Fireworks\n", - "\n", - "[Fireworks](https://fireworks.ai/) similarly supports function calling and JSON mode for select models.\n", - "\n", - "[API reference](https://api.python.langchain.com/en/latest/chat_models/langchain_fireworks.chat_models.ChatFireworks.html#langchain_fireworks.chat_models.ChatFireworks.with_structured_output)" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "ad45fdd8", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_fireworks import ChatFireworks" - ] - }, - { - "cell_type": "markdown", - "id": "36270ed5", - "metadata": {}, - "source": [ - "#### Tool/function Calling\n", - "\n", - "By default, we will use `function_calling`" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "49a20847", - "metadata": {}, - "outputs": [], - "source": [ - "model = ChatFireworks(model=\"accounts/fireworks/models/firefunction-v1\")\n", - "structured_llm = model.with_structured_output(Joke)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "e3093a6c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Joke(setup=\"Why don't cats play poker in the jungle?\", punchline='Too many cheetahs!')" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "structured_llm.invoke(\"Tell me a joke about cats\")" - ] - }, - { - "cell_type": "markdown", - "id": "ddb6b3ba", - "metadata": {}, - "source": [ - "#### JSON Mode\n", - "\n", - "We also support JSON mode. Note that we need to specify in the prompt the format that it should respond in." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "ea0c22c1", - "metadata": {}, - "outputs": [], - "source": [ - "structured_llm = model.with_structured_output(Joke, method=\"json_mode\")" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "649f9632", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Joke(setup='Why did the dog sit in the shade?', punchline='To avoid getting burned.')" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "structured_llm.invoke(\n", - " \"Tell me a joke about dogs, respond in JSON with `setup` and `punchline` keys\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "ff70609a", - "metadata": {}, - "source": [ - "## Mistral\n", - "\n", - "We also support structured output with Mistral models, although we only support function calling.\n", - "\n", - "[API reference](https://api.python.langchain.com/en/latest/chat_models/langchain_mistralai.chat_models.ChatMistralAI.html#langchain_mistralai.chat_models.ChatMistralAI.with_structured_output)" + "We can also pass in an OpenAI-style JSON schema dict if you prefer not to use Pydantic. In this case, the response is a dict:" ] }, { "cell_type": "code", "execution_count": 3, - "id": "bffd3fad", + "id": "6700994a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'setup': 'Why was the cat sitting on the computer?',\n", + " 'punchline': 'To keep an eye on the mouse!'}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "from langchain_mistralai import ChatMistralAI" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "c8bd7549", - "metadata": {}, - "outputs": [], - "source": [ - "model = ChatMistralAI(model=\"mistral-large-latest\")\n", - "structured_llm = model.with_structured_output(Joke)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "17b15816", - "metadata": {}, - "outputs": [], - "source": [ - "structured_llm.invoke(\"Tell me a joke about cats\")" - ] - }, - { - "cell_type": "markdown", - "id": "6bbbb698", - "metadata": {}, - "source": [ - "## Together\n", - "\n", - "Since [TogetherAI](https://www.together.ai/) is just a drop in replacement for OpenAI, we can just use the OpenAI integration" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "9b9617e3", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "from langchain_openai import ChatOpenAI" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "90549664", - "metadata": {}, - "outputs": [], - "source": [ - "model = ChatOpenAI(\n", - " base_url=\"https://api.together.xyz/v1\",\n", - " api_key=os.environ[\"TOGETHER_API_KEY\"],\n", - " model=\"mistralai/Mixtral-8x7B-Instruct-v0.1\",\n", + "structured_llm = model.with_structured_output(\n", + " {\n", + " \"name\": \"joke\",\n", + " \"description\": \"Joke to tell user.\",\n", + " \"parameters\": {\n", + " \"title\": \"Joke\",\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"setup\": {\"type\": \"string\", \"description\": \"The setup for the joke\"},\n", + " \"punchline\": {\"type\": \"string\", \"description\": \"The joke's punchline\"},\n", + " },\n", + " \"required\": [\"setup\", \"punchline\"],\n", + " },\n", + " }\n", ")\n", - "structured_llm = model.with_structured_output(Joke)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "01da39be", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Joke(setup='Why did the cat sit on the computer?', punchline='To keep an eye on the mouse!')" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ + "\n", "structured_llm.invoke(\"Tell me a joke about cats\")" ] }, { "cell_type": "markdown", - "id": "6214781d", + "id": "3da57988", "metadata": {}, "source": [ - "## Groq\n", + "### Choosing between multiple schemas\n", "\n", - "Groq provides an OpenAI-compatible function calling API.\n", - "\n", - "[API reference](https://api.python.langchain.com/en/latest/chat_models/langchain_groq.chat_models.ChatGroq.html#langchain_groq.chat_models.ChatGroq.with_structured_output)" + "If you have multiple schemas that are valid outputs for the model, you can use Pydantic's `Union` type:" ] }, { "cell_type": "code", - "execution_count": 11, - "id": "70511bc3", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_groq import ChatGroq" - ] - }, - { - "cell_type": "markdown", - "id": "6b7e97a6", - "metadata": {}, - "source": [ - "#### Tool/function Calling\n", - "\n", - "By default, we will use `function_calling`" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "be9fdf04", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/reag/src/langchain/libs/core/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The function `with_structured_output` is in beta. It is actively being worked on, so the API may change.\n", - " warn_beta(\n" - ] - } - ], - "source": [ - "model = ChatGroq()\n", - "structured_llm = model.with_structured_output(Joke)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "e13f4676", + "execution_count": 4, + "id": "9194bcf2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Joke(setup=\"Why don't cats play poker in the jungle?\", punchline='Too many cheetahs!')" + "Response(output=Joke(setup='Why was the cat sitting on the computer?', punchline='Because it wanted to keep an eye on the mouse!'))" ] }, - "execution_count": 7, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "from typing import Union\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "\n", + "\n", + "class Joke(BaseModel):\n", + " setup: str = Field(description=\"The setup of the joke\")\n", + " punchline: str = Field(description=\"The punchline to the joke\")\n", + "\n", + "\n", + "class ConversationalResponse(BaseModel):\n", + " response: str = Field(description=\"A conversational response to the user's query\")\n", + "\n", + "\n", + "class Response(BaseModel):\n", + " output: Union[Joke, ConversationalResponse]\n", + "\n", + "\n", + "structured_llm = model.with_structured_output(Response)\n", + "\n", "structured_llm.invoke(\"Tell me a joke about cats\")" ] }, - { - "cell_type": "markdown", - "id": "a82c2f55", - "metadata": {}, - "source": [ - "#### JSON Mode\n", - "\n", - "We also support JSON mode. Note that we need to specify in the prompt the format that it should respond in." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "86574fb8", - "metadata": {}, - "outputs": [], - "source": [ - "structured_llm = model.with_structured_output(Joke, method=\"json_mode\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "01dced9c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Joke(setup=\"Why don't cats play poker in the jungle?\", punchline='Too many cheetahs!')" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "structured_llm.invoke(\n", - " \"Tell me a joke about cats, respond in JSON with `setup` and `punchline` keys\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "f94e9c7a-bfbd-409c-b3a6-59e485e4ea5b", - "metadata": {}, - "source": [ - "## Anthropic\n", - "\n", - "Anthropic's tool-calling API can be used for structuring outputs. Note that there is currently no way to force a tool-call via the API, so prompting the model correctly is still important.\n", - "\n", - "[API reference](https://api.python.langchain.com/en/latest/chat_models/langchain_anthropic.chat_models.ChatAnthropic.html#langchain_anthropic.chat_models.ChatAnthropic.with_structured_output)" - ] - }, { "cell_type": "code", "execution_count": 5, - "id": "12682237-6689-4408-88b1-3595feac447f", + "id": "84d86132", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Joke(setup='What do you call a cat that loves to bowl?', punchline='An alley cat!')" + "Response(output=ConversationalResponse(response=\"I'm just a collection of code, so I don't have feelings, but thanks for asking! How can I assist you today?\"))" ] }, "execution_count": 5, @@ -520,56 +213,350 @@ } ], "source": [ - "from langchain_anthropic import ChatAnthropic\n", - "\n", - "model = ChatAnthropic(model=\"claude-3-opus-20240229\", temperature=0)\n", - "structured_llm = model.with_structured_output(Joke)\n", - "structured_llm.invoke(\"Tell me a joke about cats. Make sure to call the Joke function.\")" + "structured_llm.invoke(\"How are you today?\")" ] }, { "cell_type": "markdown", - "id": "6c797e2d-3115-4ca2-9c2f-e853bdc7956d", + "id": "e28c14d3", "metadata": {}, "source": [ - "## Google Vertex AI\n", + "If you are using JSON Schema, you can take advantage of other more complex schema descriptions to create a similar effect.\n", "\n", - "Google's Gemini models support [function-calling](https://ai.google.dev/docs/function_calling), which we can access via Vertex AI and use for structuring outputs.\n", + "You can also use tool calling directly to allow the model to choose between options, if your chosen model supports it. This involves a bit more parsing and setup. See [this guide](/docs/how_to/tools_multiple/) for more details." + ] + }, + { + "cell_type": "markdown", + "id": "39d7a555", + "metadata": {}, + "source": [ + "### Specifying the output method (Advanced)\n", "\n", - "[API reference](https://api.python.langchain.com/en/latest/chat_models/langchain_google_vertexai.chat_models.ChatVertexAI.html#langchain_google_vertexai.chat_models.ChatVertexAI.with_structured_output)" + "For models that support more than one means of outputting data, you can specify the preferred one like this:" ] }, { "cell_type": "code", - "execution_count": 7, - "id": "24421189-02bf-4589-a91a-197584c4a696", + "execution_count": 6, + "id": "df0370e3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Joke(setup='A cat-ch', punchline='What do you call a cat that loves to play fetch?')" + "Joke(setup='Why was the cat sitting on the computer?', punchline='Because it wanted to keep an eye on the mouse!')" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "from langchain_google_vertexai import ChatVertexAI\n", + "structured_llm = model.with_structured_output(Joke, method=\"json_mode\")\n", "\n", - "llm = ChatVertexAI(model=\"gemini-pro\", temperature=0)\n", - "structured_llm = llm.with_structured_output(Joke)\n", - "structured_llm.invoke(\"Tell me a joke about cats\")" + "structured_llm.invoke(\n", + " \"Tell me a joke about cats, respond in JSON with `setup` and `punchline` keys\"\n", + ")" ] + }, + { + "cell_type": "markdown", + "id": "5e92a98a", + "metadata": {}, + "source": [ + "In the above example, we use OpenAI's alternate JSON mode capability along with a more specific prompt.\n", + "\n", + "For specifics about the model you choose, peruse its entry in the [API reference pages](https://api.python.langchain.com/en/latest/langchain_api_reference.html).\n", + "\n", + "## Prompting techniques\n", + "\n", + "You can also prompt models to outputting information in a given format. This approach relies on designing good prompts and then parsing the output of the models. This is the only option for models that don't support `.with_structured_output()` or other built-in approaches.\n", + "\n", + "### Using `PydanticOutputParser`\n", + "\n", + "The following example uses the built-in `PydanticOutputParser` to parse the output of a chat model prompted to match a the given Pydantic schema. Note that we are adding `format_instructions` from a method on the parser directly to the prompt:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "6e514455", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import List\n", + "\n", + "from langchain.output_parsers import PydanticOutputParser\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "\n", + "\n", + "class Person(BaseModel):\n", + " \"\"\"Information about a person.\"\"\"\n", + "\n", + " name: str = Field(..., description=\"The name of the person\")\n", + " height_in_meters: float = Field(\n", + " ..., description=\"The height of the person expressed in meters.\"\n", + " )\n", + "\n", + "\n", + "class People(BaseModel):\n", + " \"\"\"Identifying information about all people in a text.\"\"\"\n", + "\n", + " people: List[Person]\n", + "\n", + "\n", + "# Set up a parser\n", + "parser = PydanticOutputParser(pydantic_object=People)\n", + "\n", + "# Prompt\n", + "prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\n", + " \"system\",\n", + " \"Answer the user query. Wrap the output in `json` tags\\n{format_instructions}\",\n", + " ),\n", + " (\"human\", \"{query}\"),\n", + " ]\n", + ").partial(format_instructions=parser.get_format_instructions())" + ] + }, + { + "cell_type": "markdown", + "id": "082fa166", + "metadata": {}, + "source": [ + "Let’s take a look at what information is sent to the model:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3d73d33d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "System: Answer the user query. Wrap the output in `json` tags\n", + "The output should be formatted as a JSON instance that conforms to the JSON schema below.\n", + "\n", + "As an example, for the schema {\"properties\": {\"foo\": {\"title\": \"Foo\", \"description\": \"a list of strings\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"foo\"]}\n", + "the object {\"foo\": [\"bar\", \"baz\"]} is a well-formatted instance of the schema. The object {\"properties\": {\"foo\": [\"bar\", \"baz\"]}} is not well-formatted.\n", + "\n", + "Here is the output schema:\n", + "```\n", + "{\"description\": \"Identifying information about all people in a text.\", \"properties\": {\"people\": {\"title\": \"People\", \"type\": \"array\", \"items\": {\"$ref\": \"#/definitions/Person\"}}}, \"required\": [\"people\"], \"definitions\": {\"Person\": {\"title\": \"Person\", \"description\": \"Information about a person.\", \"type\": \"object\", \"properties\": {\"name\": {\"title\": \"Name\", \"description\": \"The name of the person\", \"type\": \"string\"}, \"height_in_meters\": {\"title\": \"Height In Meters\", \"description\": \"The height of the person expressed in meters.\", \"type\": \"number\"}}, \"required\": [\"name\", \"height_in_meters\"]}}}\n", + "```\n", + "Human: Anna is 23 years old and she is 6 feet tall\n" + ] + } + ], + "source": [ + "query = \"Anna is 23 years old and she is 6 feet tall\"\n", + "\n", + "print(prompt.format_prompt(query=query).to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "081956b9", + "metadata": {}, + "source": [ + "And now let's invoke it:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8d6b3d17", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "People(people=[Person(name='Anna', height_in_meters=1.8288)])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chain = prompt | model | parser\n", + "\n", + "chain.invoke({\"query\": query})" + ] + }, + { + "cell_type": "markdown", + "id": "6732dd87", + "metadata": {}, + "source": [ + "### Custom Parsing\n", + "\n", + "You can also create a custom prompt and parser with LangChain and LCEL, using a plain function to parse the output from the model:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e8d37e15", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import re\n", + "from typing import List\n", + "\n", + "from langchain_core.messages import AIMessage\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_core.pydantic_v1 import BaseModel, Field\n", + "\n", + "\n", + "class Person(BaseModel):\n", + " \"\"\"Information about a person.\"\"\"\n", + "\n", + " name: str = Field(..., description=\"The name of the person\")\n", + " height_in_meters: float = Field(\n", + " ..., description=\"The height of the person expressed in meters.\"\n", + " )\n", + "\n", + "\n", + "class People(BaseModel):\n", + " \"\"\"Identifying information about all people in a text.\"\"\"\n", + "\n", + " people: List[Person]\n", + "\n", + "\n", + "# Prompt\n", + "prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\n", + " \"system\",\n", + " \"Answer the user query. Output your answer as JSON that \"\n", + " \"matches the given schema: ```json\\n{schema}\\n```. \"\n", + " \"Make sure to wrap the answer in ```json and ``` tags\",\n", + " ),\n", + " (\"human\", \"{query}\"),\n", + " ]\n", + ").partial(schema=People.schema())\n", + "\n", + "\n", + "# Custom parser\n", + "def extract_json(message: AIMessage) -> List[dict]:\n", + " \"\"\"Extracts JSON content from a string where JSON is embedded between ```json and ``` tags.\n", + "\n", + " Parameters:\n", + " text (str): The text containing the JSON content.\n", + "\n", + " Returns:\n", + " list: A list of extracted JSON strings.\n", + " \"\"\"\n", + " text = message.content\n", + " # Define the regular expression pattern to match JSON blocks\n", + " pattern = r\"```json(.*?)```\"\n", + "\n", + " # Find all non-overlapping matches of the pattern in the string\n", + " matches = re.findall(pattern, text, re.DOTALL)\n", + "\n", + " # Return the list of matched JSON strings, stripping any leading or trailing whitespace\n", + " try:\n", + " return [json.loads(match.strip()) for match in matches]\n", + " except Exception:\n", + " raise ValueError(f\"Failed to parse: {message}\")" + ] + }, + { + "cell_type": "markdown", + "id": "9f1bc8f7", + "metadata": {}, + "source": [ + "Here is the prompt sent to the model:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "c8a30d0e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "System: Answer the user query. Output your answer as JSON that matches the given schema: ```json\n", + "{'title': 'People', 'description': 'Identifying information about all people in a text.', 'type': 'object', 'properties': {'people': {'title': 'People', 'type': 'array', 'items': {'$ref': '#/definitions/Person'}}}, 'required': ['people'], 'definitions': {'Person': {'title': 'Person', 'description': 'Information about a person.', 'type': 'object', 'properties': {'name': {'title': 'Name', 'description': 'The name of the person', 'type': 'string'}, 'height_in_meters': {'title': 'Height In Meters', 'description': 'The height of the person expressed in meters.', 'type': 'number'}}, 'required': ['name', 'height_in_meters']}}}\n", + "```. Make sure to wrap the answer in ```json and ``` tags\n", + "Human: Anna is 23 years old and she is 6 feet tall\n" + ] + } + ], + "source": [ + "query = \"Anna is 23 years old and she is 6 feet tall\"\n", + "\n", + "print(prompt.format_prompt(query=query).to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "ec018893", + "metadata": {}, + "source": [ + "And here's what it looks like when we invoke it:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e1e7baf6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'people': [{'name': 'Anna', 'height_in_meters': 1.8288}]}]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chain = prompt | model | extract_json\n", + "\n", + "chain.invoke({\"query\": query})" + ] + }, + { + "cell_type": "markdown", + "id": "7a39221a", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "Now you've learned a few methods to make a model output structured data.\n", + "\n", + "To learn more, check out the other how-to guides in this section, or the conceptual guide on tool calling." + ] + }, + { + "cell_type": "markdown", + "id": "6e3759e2", + "metadata": {}, + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "poetry-venv-2", + "display_name": "Python 3", "language": "python", - "name": "poetry-venv-2" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -581,7 +568,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.1" + "version": "3.10.5" } }, "nbformat": 4, diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/text_embedding/caching_embeddings.ipynb b/docs/versioned_docs/version-0.2.x/how_to/text_embedding.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/text_embedding/caching_embeddings.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/text_embedding.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/time_weighted_vectorstore.ipynb b/docs/versioned_docs/version-0.2.x/how_to/time_weighted_vectorstore.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/time_weighted_vectorstore.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/time_weighted_vectorstore.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/vectorstore.ipynb b/docs/versioned_docs/version-0.2.x/how_to/vectorstore_retriever.ipynb similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/retrievers/vectorstore.ipynb rename to docs/versioned_docs/version-0.2.x/how_to/vectorstore_retriever.ipynb diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/vectorstores/index.mdx b/docs/versioned_docs/version-0.2.x/how_to/vectorstores.mdx similarity index 100% rename from docs/versioned_docs/version-0.2.x/modules/data_connection/vectorstores/index.mdx rename to docs/versioned_docs/version-0.2.x/how_to/vectorstores.mdx diff --git a/docs/versioned_docs/version-0.2.x/how_to_guides.md b/docs/versioned_docs/version-0.2.x/how_to_guides.md index b4af5052bfd..4ea67351b6e 100644 --- a/docs/versioned_docs/version-0.2.x/how_to_guides.md +++ b/docs/versioned_docs/version-0.2.x/how_to_guides.md @@ -6,7 +6,7 @@ However, these guides will help you quickly accomplish common tasks. ## Core Functionality -- How to return structured data from an LLM +- [How to return structured data from an LLM](/docs/how_to/structured_output) - How to use an LLM to call tools - [How to stream](/docs/how_to/streaming) - How to see what is going on inside your LLM application @@ -79,44 +79,44 @@ However, these guides will help you quickly accomplish common tasks. - [How to write a custom output parser class](/docs/how_to/output_parser_custom) ### Document Loaders -- [How to load CSV data](/docs/modules/data_connection/document_loaders/csv) -- [How to load data from a directory](/docs/modules/data_connection/document_loaders/file_directory) -- [How to load HTML data](/docs/modules/data_connection/document_loaders/html) -- [How to load JSON data](/docs/modules/data_connection/document_loaders/json) -- [How to load Markdown data](/docs/modules/data_connection/document_loaders/markdown) -- [How to load Microsoft Office data](/docs/modules/data_connection/document_loaders/office_file) -- [How to load PDF files](/docs/modules/data_connection/document_loaders/pdf) -- [How to write a custom document loader](/docs/modules/data_connection/document_loaders/custom) +- [How to load CSV data](/docs/how_to/document_loader_csv) +- [How to load data from a directory](/docs/how_to/document_loader_directory) +- [How to load HTML data](/docs/how_to/document_loader_html) +- [How to load JSON data](/docs/how_to/document_loader_json) +- [How to load Markdown data](/docs/how_to/document_loader_markdown) +- [How to load Microsoft Office data](/docs/how_to/document_loader_office_file) +- [How to load PDF files](/docs/how_to/document_loader_pdf) +- [How to write a custom document loader](/docs/how_to/document_loader_custom) ### Text Splitter -- [How to recursively split text](/docs/modules/data_connection/document_transformers/recursive_text_splitter) -- [How to split by HTML headers](/docs/modules/data_connection/document_transformers/HTML_header_metadata) -- [How to split by HTML sections](/docs/modules/data_connection/document_transformers/HTML_section_aware_splitter) -- [How to split by character](/docs/modules/data_connection/document_transformers/character_text_splitter) -- [How to split code](/docs/modules/data_connection/document_transformers/code_splitter) -- [How to split Markdown by headers](/docs/modules/data_connection/document_transformers/markdown_header_metadata) -- [How to recursively split JSON](/docs/modules/data_connection/document_transformers/recursive_json_splitter) -- [How to split text into semantic chunks](/docs/modules/data_connection/document_transformers/semantic-chunker) -- [How to split by tokens](/docs/modules/data_connection/document_transformers/split_by_token) +- [How to recursively split text](/docs/how_to/recursive_text_splitter) +- [How to split by HTML headers](/docs/how_to/HTML_header_metadata_splitter) +- [How to split by HTML sections](/docs/how_to/HTML_section_aware_splitter) +- [How to split by character](/docs/how_to/character_text_splitter) +- [How to split code](/docs/how_to/code_splitter) +- [How to split Markdown by headers](/docs/how_to/markdown_header_metadata_splitter) +- [How to recursively split JSON](/docs/how_to/recursive_json_splitter) +- [How to split text into semantic chunks](/docs/how_to/semantic-chunker) +- [How to split by tokens](/docs/how_to/split_by_token) ### Embedding Models -- [How to embed text data](/docs/modules/data_connection/text_embedding) -- [How to cache embedding results](/docs/modules/data_connection/text_embedding/caching_embeddings) +- [How to embed text data](/docs/how_to/text_embedding) +- [How to cache embedding results](/docs/how_to/caching_embeddings) ### Vector Stores -- [How to use a vector store to retrieve data](/docs/modules/data_connection/vectorstores) +- [How to use a vector store to retrieve data](/docs/how_to/vectorstores) ### Retrievers -- [How use a vector store to retrieve data](/docs/modules/data_connection/retrievers/vectorstore) -- [How to generate multiple queries to retrieve data for](/docs/modules/data_connection/retrievers/MultiQueryRetriever) -- [How to use contextual compression to compress the data retrieved](/docs/modules/data_connection/retrievers/contextual_compression) -- [How to write a custom retriever class](/docs/modules/data_connection/retrievers/custom_retriever) -- [How to combine the results from multiple retrievers](/docs/modules/data_connection/retrievers/ensemble) -- [How to reorder retrieved results to put most relevant documents not in the middle](/docs/modules/data_connection/retrievers/long_context_reorder) -- [How to generate multiple embeddings per document](/docs/modules/data_connection/retrievers/multi_vector) -- [How to retrieve the whole document for a chunk](/docs/modules/data_connection/retrievers/parent_document_retriever) -- [How to generate metadata filters](/docs/modules/data_connection/retrievers/self_query) -- [How to create a time-weighted retriever](/docs/modules/data_connection/retrievers/time_weighted_vectorstore) +- [How use a vector store to retrieve data](/docs/how_to/vectorstore_retriever.ipynb) +- [How to generate multiple queries to retrieve data for](/docs/how_to/MultiQueryRetriever) +- [How to use contextual compression to compress the data retrieved](/docs/how_to/contextual_compression) +- [How to write a custom retriever class](/docs/how_to/custom_retriever) +- [How to combine the results from multiple retrievers](/docs/how_to/ensemble_retriever) +- [How to reorder retrieved results to put most relevant documents not in the middle](/docs/how_to/long_context_reorder) +- [How to generate multiple embeddings per document](/docs/how_to/multi_vector) +- [How to retrieve the whole document for a chunk](/docs/how_to/parent_document_retriever) +- [How to generate metadata filters](/docs/how_to/self_query) +- [How to create a time-weighted retriever](/docs/how_to/time_weighted_vectorstore) ### Indexing - [How to reindex data to keep your vectorstore in-sync with the underlying data source](/docs/modules/data_connection/indexing) diff --git a/docs/versioned_docs/version-0.2.x/modules/data_connection/text_embedding/index.mdx b/docs/versioned_docs/version-0.2.x/modules/data_connection/text_embedding/index.mdx deleted file mode 100644 index d3d45993260..00000000000 --- a/docs/versioned_docs/version-0.2.x/modules/data_connection/text_embedding/index.mdx +++ /dev/null @@ -1,129 +0,0 @@ ---- -sidebar_position: 2 -sidebar_class_name: hidden ---- -# Text embedding models - -:::info -Head to [Integrations](/docs/integrations/text_embedding/) for documentation on built-in integrations with text embedding model providers. -::: - -The Embeddings class is a class designed for interfacing with text embedding models. There are lots of embedding model providers (OpenAI, Cohere, Hugging Face, etc) - this class is designed to provide a standard interface for all of them. - -Embeddings create a vector representation of a piece of text. This is useful because it means we can think about text in the vector space, and do things like semantic search where we look for pieces of text that are most similar in the vector space. - -The base Embeddings class in LangChain provides two methods: one for embedding documents and one for embedding a query. The former takes as input multiple texts, while the latter takes a single text. The reason for having these as two separate methods is that some embedding providers have different embedding methods for documents (to be searched over) vs queries (the search query itself). - -## Get started - -### Setup - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - - -To start we'll need to install the OpenAI partner package: - -```bash -pip install langchain-openai -``` - -Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running: - -```bash -export OPENAI_API_KEY="..." -``` - -If you'd prefer not to set an environment variable you can pass the key in directly via the `api_key` named parameter when initiating the OpenAI LLM class: - -```python -from langchain_openai import OpenAIEmbeddings - -embeddings_model = OpenAIEmbeddings(api_key="...") -``` - -Otherwise you can initialize without any params: -```python -from langchain_openai import OpenAIEmbeddings - -embeddings_model = OpenAIEmbeddings() -``` - - - - -To start we'll need to install the Cohere SDK package: - -```bash -pip install langchain-cohere -``` - -Accessing the API requires an API key, which you can get by creating an account and heading [here](https://dashboard.cohere.com/api-keys). Once we have a key we'll want to set it as an environment variable by running: - -```shell -export COHERE_API_KEY="..." -``` - -If you'd prefer not to set an environment variable you can pass the key in directly via the `cohere_api_key` named parameter when initiating the Cohere LLM class: - -```python -from langchain_cohere import CohereEmbeddings - -embeddings_model = CohereEmbeddings(cohere_api_key="...") -``` - -Otherwise you can initialize without any params: -```python -from langchain_cohere import CohereEmbeddings - -embeddings_model = CohereEmbeddings() -``` - - - - -### `embed_documents` -#### Embed list of texts - -```python -embeddings = embeddings_model.embed_documents( - [ - "Hi there!", - "Oh, hello!", - "What's your name?", - "My friends call me World", - "Hello World!" - ] -) -len(embeddings), len(embeddings[0]) -``` - - - -``` -(5, 1536) -``` - - - -### `embed_query` -#### Embed single query -Embed a single piece of text for the purpose of comparing to other embedded pieces of texts. - -```python -embedded_query = embeddings_model.embed_query("What was the name mentioned in the conversation?") -embedded_query[:5] -``` - - - -``` -[0.0053587136790156364, - -0.0004999046213924885, - 0.038883671164512634, - -0.003001077566295862, - -0.00900818221271038] -``` - -