{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "keywords: [recursivecharactertextsplitter]\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to recursively split text by characters\n",
    "\n",
    ":::info Prerequisites\n",
    "\n",
    "This guide assumes familiarity with the following concepts:\n",
    "\n",
    "- [Text splitters](/docs/concepts#text-splitters)\n",
    "\n",
    ":::\n",
    "\n",
    "This text splitter is the recommended one for generic text. It is parameterized by a list of characters. It tries to split on them in order until the chunks are small enough. The default list is `[\"\\n\\n\", \"\\n\", \" \", \"\"]`. This has the effect of trying to keep all paragraphs (and then sentences, and then words) together as long as possible, as those would generically seem to be the strongest semantically related pieces of text.\n",
    "\n",
    "1. How the text is split: by list of characters.\n",
    "2. How the chunk size is measured: by number of characters.\n",
    "\n",
    "Below we show example usage.\n",
    "\n",
    "To obtain the string content directly, use `.splitText`.\n",
    "\n",
    "To create LangChain [Document](https://api.js.langchain.com/classes/langchain_core.documents.Document.html) objects (e.g., for use in downstream tasks), use `.createDocuments`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "  Document {\n",
      "    pageContent: \"Hi.\",\n",
      "    metadata: { loc: { lines: { from: 1, to: 1 } } }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"I'm\",\n",
      "    metadata: { loc: { lines: { from: 3, to: 3 } } }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"Harrison.\",\n",
      "    metadata: { loc: { lines: { from: 3, to: 3 } } }\n",
      "  }\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "import { RecursiveCharacterTextSplitter } from \"@langchain/textsplitters\";\n",
    "\n",
    "const text = `Hi.\\n\\nI'm Harrison.\\n\\nHow? Are? You?\\nOkay then f f f f.\n",
    "This is a weird text to write, but gotta test the splittingggg some how.\\n\\n\n",
    "Bye!\\n\\n-H.`;\n",
    "const splitter = new RecursiveCharacterTextSplitter({\n",
    "  chunkSize: 10,\n",
    "  chunkOverlap: 1,\n",
    "});\n",
    "\n",
    "const output = await splitter.createDocuments([text]);\n",
    "\n",
    "console.log(output.slice(0, 3));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You'll note that in the above example we are splitting a raw text string and getting back a list of documents. We can also split documents directly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "  Document {\n",
      "    pageContent: \"Hi.\",\n",
      "    metadata: { loc: { lines: { from: 1, to: 1 } } }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"I'm\",\n",
      "    metadata: { loc: { lines: { from: 3, to: 3 } } }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"Harrison.\",\n",
      "    metadata: { loc: { lines: { from: 3, to: 3 } } }\n",
      "  }\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "import { Document } from \"@langchain/core/documents\";\n",
    "import { RecursiveCharacterTextSplitter } from \"@langchain/textsplitters\";\n",
    "\n",
    "const text = `Hi.\\n\\nI'm Harrison.\\n\\nHow? Are? You?\\nOkay then f f f f.\n",
    "This is a weird text to write, but gotta test the splittingggg some how.\\n\\n\n",
    "Bye!\\n\\n-H.`;\n",
    "const splitter = new RecursiveCharacterTextSplitter({\n",
    "  chunkSize: 10,\n",
    "  chunkOverlap: 1,\n",
    "});\n",
    "\n",
    "const docOutput = await splitter.splitDocuments([\n",
    "  new Document({ pageContent: text }),\n",
    "]);\n",
    "\n",
    "console.log(docOutput.slice(0, 3));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can customize the `RecursiveCharacterTextSplitter` with arbitrary separators by passing a `separators` parameter like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "  Document {\n",
      "    pageContent: \"Some other considerations include:\",\n",
      "    metadata: { loc: { lines: { from: 1, to: 1 } } }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"- Do you deploy your backend and frontend together\",\n",
      "    metadata: { loc: { lines: { from: 3, to: 3 } } }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"r, or separately?\",\n",
      "    metadata: { loc: { lines: { from: 3, to: 3 } } }\n",
      "  }\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "import { RecursiveCharacterTextSplitter } from \"langchain/text_splitter\";\n",
    "import { Document } from \"@langchain/core/documents\";\n",
    "\n",
    "const text = `Some other considerations include:\n",
    "\n",
    "- Do you deploy your backend and frontend together, or separately?\n",
    "- Do you deploy your backend co-located with your database, or separately?\n",
    "\n",
    "**Production Support:** As you move your LangChains into production, we'd love to offer more hands-on support.\n",
    "Fill out [this form](https://airtable.com/appwQzlErAS2qiP0L/shrGtGaVBVAz7NcV2) to share more about what you're building, and our team will get in touch.\n",
    "\n",
    "## Deployment Options\n",
    "\n",
    "See below for a list of deployment options for your LangChain app. If you don't see your preferred option, please get in touch and we can add it to this list.`;\n",
    "\n",
    "const splitter = new RecursiveCharacterTextSplitter({\n",
    "  chunkSize: 50,\n",
    "  chunkOverlap: 1,\n",
    "  separators: [\"|\", \"##\", \">\", \"-\"],\n",
    "});\n",
    "\n",
    "const docOutput = await splitter.splitDocuments([\n",
    "  new Document({ pageContent: text }),\n",
    "]);\n",
    "\n",
    "console.log(docOutput.slice(0, 3));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next steps\n",
    "\n",
    "You've now learned a method for splitting text by character.\n",
    "\n",


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "38831021-76ed-48b3-9f62-d1241a68b6ad",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_position: 3\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a745f98b-c495-44f6-a882-757c38992d76",
   "metadata": {},
   "source": [
    "# How to use output parsers to parse an LLM response into structured format\n",
    "\n",
    ":::info Prerequisites\n",
    "\n",
    "This guide assumes familiarity with the following concepts:\n",
    "\n",
    "- [Output parsers](/docs/concepts#output-parsers)\n",
    "- [Chat models](/docs/concepts#chat-models)\n",
    "\n",
    ":::\n",
    "\n",
    "Language models output text. But there are times where you want to get more structured information than just text back. While some model providers support [built-in ways to return structured output](/docs/how_to/structured_output), not all do. For these providers, you must use prompting to encourage the model to return structured data in the desired format.\n",
    "\n",
    "LangChain has [output parsers](/docs/concepts#output-parsers) which can help parse model outputs into usable objects. We'll go over a few examples below.\n",
    "\n",
    "## Get started\n",
    "\n",
    "The primary type of output parser for working with structured data in model responses is the [`StructuredOutputParser`](https://api.js.langchain.com/classes/langchain_core.output_parsers.StructuredOutputParser.html). In the below example, we define a schema for the type of output we expect from the model using [`zod`](https://zod.dev).\n",
    "\n",
    "First, let's see the default formatting instructions we'll plug into the prompt:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b62367da",
   "metadata": {},
   "source": [
    "```{=mdx}\n",
    "import ChatModelTabs from \"@theme/ChatModelTabs\";\n",
    "\n",
    "<ChatModelTabs />\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1594b2bf-2a6f-47bb-9a81-38930f8e606b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You must format your output as a JSON value that adheres to a given \"JSON Schema\" instance.\n",
      "\n",
      "\"JSON Schema\" is a declarative language that allows you to annotate and validate JSON documents.\n",
      "\n",
      "For example, the example \"JSON Schema\" instance {{\"properties\": {{\"foo\": {{\"description\": \"a list of test words\", \"type\": \"array\", \"items\": {{\"type\": \"string\"}}}}}}, \"required\": [\"foo\"]}}}}\n",
      "would match an object with one required property, \"foo\". The \"type\" property specifies \"foo\" must be an \"array\", and the \"description\" property semantically describes it as \"a list of test words\". The items within \"foo\" must be strings.\n",
      "Thus, the object {{\"foo\": [\"bar\", \"baz\"]}} is a well-formatted instance of this example \"JSON Schema\". The object {{\"properties\": {{\"foo\": [\"bar\", \"baz\"]}}}} is not well-formatted.\n",
      "\n",
      "Your output will be parsed and type-checked according to the provided schema instance, so make sure all fields in your output match the schema exactly and there are no trailing commas!\n",
      "\n",
      "Here is the JSON Schema instance your output must adhere to. Include the enclosing markdown codeblock:\n",
      "```json\n",
      "{\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\",\"description\":\"answer to the user's question\"},\"source\":{\"type\":\"string\",\"description\":\"source used to answer the user's question, should be a website.\"}},\"required\":[\"answer\",\"source\"],\"additionalProperties\":false,\"$schema\":\"http://json-schema.org/draft-07/schema#\"}\n",
      "```\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import { z } from \"zod\";\n",
    "import { RunnableSequence } from \"@langchain/core/runnables\";\n",
    "import { StructuredOutputParser } from \"@langchain/core/output_parsers\";\n",
    "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
    "\n",
    "const zodSchema = z.object({\n",
    "  answer: z.string().describe(\"answer to the user's question\"),\n",
    "  source: z.string().describe(\"source used to answer the user's question, should be a website.\"),\n",
    "})\n",
    "\n",
    "const parser = StructuredOutputParser.fromZodSchema(zodSchema);\n",
    "\n",
    "const chain = RunnableSequence.from([\n",
    "  ChatPromptTemplate.fromTemplate(\n",
    "    \"Answer the users question as best as possible.\\n{format_instructions}\\n{question}\"\n",
    "  ),\n",
    "  model,\n",
    "  parser,\n",
    "]);\n",
    "\n",
    "console.log(parser.getFormatInstructions());\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2bd357c5",
   "metadata": {},
   "source": [
    "Next, let's invoke the chain:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "301471a0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  answer: \"The capital of France is Paris.\",\n",
      "  source: \"https://en.wikipedia.org/wiki/Paris\"\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "const response = await chain.invoke({\n",
    "  question: \"What is the capital of France?\",\n",
    "  format_instructions: parser.getFormatInstructions(),\n",
    "});\n",
    "\n",
    "console.log(response);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75976cd6-78e2-458b-821f-3ddf3683466b",
   "metadata": {},
   "source": [
    "Output parsers implement the [Runnable interface](/docs/how_to/#langchain-expression-language-lcel), the basic building block of [LangChain Expression Language (LCEL)](/docs/how_to/#langchain-expression-language-lcel). This means they support `invoke`, `stream`, `batch`, `streamLog` calls.\n",
    "\n",
    "## Validation\n",
    "\n",
    "One feature of the `StructuredOutputParser` is that it supports stricter Zod validations. For example, if you pass a simulated model output that does not conform to the schema, we get a detailed type error:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "475f1ae5",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "Failed to parse. Text: \"{\"badfield\": \"foo\"}\". Error: [\n  {\n    \"code\": \"invalid_type\",\n    \"expected\": \"string\",\n    \"received\": \"undefined\",\n    \"path\": [\n      \"answer\"\n    ],\n    \"message\": \"Required\"\n  },\n  {\n    \"code\": \"invalid_type\",\n    \"expected\": \"string\",\n    \"received\": \"undefined\",\n    \"path\": [\n      \"source\"\n    ],\n    \"message\": \"Required\"\n  }\n]",
     "output_type": "error",
     "traceback": [
      "Stack trace:",
      "Error: Failed to parse. Text: \"{\"badfield\": \"foo\"}\". Error: [",
      "  {",
      "    \"code\": \"invalid_type\",",
      "    \"expected\": \"string\",",
      "    \"received\": \"undefined\",",
      "    \"path\": [",
      "      \"answer\"",
      "    ],",
      "    \"message\": \"Required\"",
      "  },",
      "  {",
      "    \"code\": \"invalid_type\",",
      "    \"expected\": \"string\",",
      "    \"received\": \"undefined\",",


"{ query: \u001b[32m\"books about aliens\"\u001b[39m, author: \u001b[32m\"jess knight\"\u001b[39m }"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "await queryAnalyzer.invoke(\"what are books about aliens by jess knight\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0b60b7c2",
      "metadata": {},
      "source": [
        "### Add in all values\n",
        "\n",
        "One way around this is to add ALL possible values to the prompt. That will generally guide the query in the right direction"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "98788a94",
      "metadata": {},
      "outputs": [],
      "source": [
        "const systemTemplate = `Generate a relevant search query for a library system using the 'search' tool.\n",
        "\n",
        "The 'author' you return to the user MUST be one of the following authors:\n",
        "\n",
        "{authors}\n",
        "\n",
        "Do NOT hallucinate author name!`\n",
        "const basePrompt = ChatPromptTemplate.fromMessages(\n",
        "    [\n",
        "      [\"system\", systemTemplate],\n",
        "      [\"human\", \"{question}\"],\n",
        "    ]\n",
        ")\n",
        "const promptWithAuthors = await basePrompt.partial({ authors: names.join(\", \") })\n",
        "\n",
        "const queryAnalyzerAll = RunnableSequence.from([\n",
        "  {\n",
        "    question: new RunnablePassthrough(),\n",
        "  },\n",
        "  promptWithAuthors,\n",
        "  llmWithTools\n",
        "])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e639285a",
      "metadata": {},
      "source": [
        "However... if the list of categoricals is long enough, it may error!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "696b000f",
      "metadata": {},
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Error: 400 This model's maximum context length is 16385 tokens. However, your messages resulted in 50197 tokens (50167 in the messages, 30 in the functions). Please reduce the length of the messages or functions.\n",
            "    at Function.generate (file:///Users/jacoblee/Library/Caches/deno/npm/registry.npmjs.org/openai/4.47.1/error.mjs:41:20)\n",
            "    at OpenAI.makeStatusError (file:///Users/jacoblee/Library/Caches/deno/npm/registry.npmjs.org/openai/4.47.1/core.mjs:256:25)\n",
            "    at OpenAI.makeRequest (file:///Users/jacoblee/Library/Caches/deno/npm/registry.npmjs.org/openai/4.47.1/core.mjs:299:30)\n",
            "    at eventLoopTick (ext:core/01_core.js:63:7)\n",
            "    at async file:///Users/jacoblee/Library/Caches/deno/npm/registry.npmjs.org/@langchain/openai/0.0.31/dist/chat_models.js:756:29\n",
            "    at async RetryOperation._fn (file:///Users/jacoblee/Library/Caches/deno/npm/registry.npmjs.org/p-retry/4.6.2/index.js:50:12) {\n",
            "  status: 400,\n",
            "  headers: {\n",
            "    \"alt-svc\": 'h3=\":443\"; ma=86400',\n",
            "    \"cf-cache-status\": \"DYNAMIC\",\n",
            "    \"cf-ray\": \"885f794b3df4fa52-SJC\",\n",
            "    \"content-length\": \"340\",\n",
            "    \"content-type\": \"application/json\",\n",
            "    date: \"Sat, 18 May 2024 23:02:16 GMT\",\n",
            "    \"openai-organization\": \"langchain\",\n",
            "    \"openai-processing-ms\": \"230\",\n",
            "    \"openai-version\": \"2020-10-01\",\n",
            "    server: \"cloudflare\",\n",
            "    \"set-cookie\": \"_cfuvid=F_c9lnRuQDUhKiUE2eR2PlsxHPldf1OAVMonLlHTjzM-1716073336256-0.0.1.1-604800000; path=/; domain=\"... 48 more characters,\n",
            "    \"strict-transport-security\": \"max-age=15724800; includeSubDomains\",\n",
            "    \"x-ratelimit-limit-requests\": \"10000\",\n",
            "    \"x-ratelimit-limit-tokens\": \"2000000\",\n",
            "    \"x-ratelimit-remaining-requests\": \"9999\",\n",
            "    \"x-ratelimit-remaining-tokens\": \"1958402\",\n",
            "    \"x-ratelimit-reset-requests\": \"6ms\",\n",
            "    \"x-ratelimit-reset-tokens\": \"1.247s\",\n",
            "    \"x-request-id\": \"req_7b88677d6883fac1520e44543f68c839\"\n",
            "  },\n",
            "  request_id: \"req_7b88677d6883fac1520e44543f68c839\",\n",
            "  error: {\n",
            "    message: \"This model's maximum context length is 16385 tokens. However, your messages resulted in 50197 tokens\"... 101 more characters,\n",
            "    type: \"invalid_request_error\",\n",
            "    param: \"messages\",\n",
            "    code: \"context_length_exceeded\"\n",
            "  },\n",
            "  code: \"context_length_exceeded\",\n",
            "  param: \"messages\",\n",
            "  type: \"invalid_request_error\",\n",
            "  attemptNumber: 1,\n",
            "  retriesLeft: 6\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "try {\n",
        "    const res = await queryAnalyzerAll.invoke(\"what are books about aliens by jess knight\")\n",
        "} catch (e) {\n",
        "    console.error(e)\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1d5d7891",
      "metadata": {},
      "source": [
        "We can try to use a longer context window... but with so much information in there, it is not guaranteed to pick it up reliably"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "618a9762",
      "metadata": {},
      "source": [
        "```{=mdx}\n",
        "<ChatModelTabs customVarName=\"llmLong\" openaiParams={`{ model: \"gpt-4-turbo-preview\" }`} />\n",
        "```"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "64817a0f",
      "metadata": {},
      "outputs": [],
      "source": [
        "// @lc-docs-hide-cell\n",
        "import { ChatOpenAI } from '@langchain/openai';\n",
        "\n",
        "const llmLong = new ChatOpenAI({\n",
        "  model: \"gpt-4o\",\n",
        "  temperature: 0,\n",
        "})"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "0f0d0757",
      "metadata": {},
      "outputs": [],
      "source": [
        "const structuredLlmLong = llmLong.withStructuredOutput(searchSchema, {\n",
        "  name: \"Search\"\n",
        "});\n",
        "const queryAnalyzerAllLong = RunnableSequence.from([\n",
        "  {\n",
        "    question: new RunnablePassthrough(),\n",
        "  },\n",
        "  prompt,\n",
        "  structuredLlmLong\n",
        "]);"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "03e5b7b2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [


{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# How to stream from a question-answering chain\n",
        "\n",
        ":::info Prerequisites\n",
        "\n",
        "This guide assumes familiarity with the following:\n",
        "\n",
        "- [Retrieval-augmented generation](/docs/tutorials/rag/)\n",
        "\n",
        ":::\n",
        "\n",
        "Often in Q&A applications it's important to show users the sources that were used to generate the answer. The simplest way to do this is for the chain to return the Documents that were retrieved in each generation.\n",
        "\n",
        "We'll be using the [LLM Powered Autonomous Agents](https://lilianweng.github.io/posts/2023-06-23-agent/) blog post by Lilian Weng for retrieval content this notebook."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Setup\n",
        "### Dependencies\n",
        "\n",
        "We’ll use an OpenAI chat model and embeddings and a Memory vector store in this walkthrough, but everything shown here works with any [ChatModel](/docs/concepts/#chat-models) or [LLM](/docs/concepts#llms), [Embeddings](/docs/concepts#embedding-models), and [VectorStore](/docs/concepts#vectorstores) or [Retriever](/docs/concepts#retrievers).\n",
        "\n",
        "We’ll use the following packages:\n",
        "\n",
        "```bash\n",
        "npm install --save langchain @langchain/openai cheerio\n",
        "```\n",
        "\n",
        "We need to set environment variable `OPENAI_API_KEY`:\n",
        "\n",
        "```bash\n",
        "export OPENAI_API_KEY=YOUR_KEY\n",
        "```\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### LangSmith\n",
        "\n",
        "Many of the applications you build with LangChain will contain multiple steps with multiple invocations of LLM calls. As these applications get more and more complex, it becomes crucial to be able to inspect what exactly is going on inside your chain or agent. The best way to do this is with [LangSmith](https://smith.langchain.com/).\n",
        "\n",
        "Note that LangSmith is not needed, but it is helpful. If you do want to use LangSmith, after you sign up at the link above, make sure to set your environment variables to start logging traces:\n",
        "\n",
        "\n",
        "```bash\n",
        "export LANGCHAIN_TRACING_V2=true\n",
        "export LANGCHAIN_API_KEY=YOUR_KEY\n",
        "\n",
        "# Reduce tracing latency if you are not in a serverless environment\n",
        "# export LANGCHAIN_CALLBACKS_BACKGROUND=true\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Chain with sources\n",
        "\n",
        "Here is Q&A app with sources we built over the [LLM Powered Autonomous Agents](https://lilianweng.github.io/posts/2023-06-23-agent/) blog post by Lilian Weng in the [Returning sources](/docs/how_to/qa_sources/) guide:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{\n",
              "  question: \u001b[32m\"What is Task Decomposition\"\u001b[39m,\n",
              "  context: [\n",
              "    Document {\n",
              "      pageContent: \u001b[32m\"Fig. 1. Overview of a LLM-powered autonomous agent system.\\n\"\u001b[39m +\n",
              "        \u001b[32m\"Component One: Planning#\\n\"\u001b[39m +\n",
              "        \u001b[32m\"A complicated ta\"\u001b[39m... 898 more characters,\n",
              "      metadata: {\n",
              "        source: \u001b[32m\"https://lilianweng.github.io/posts/2023-06-23-agent/\"\u001b[39m,\n",
              "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
              "      }\n",
              "    },\n",
              "    Document {\n",
              "      pageContent: \u001b[32m'Task decomposition can be done (1) by LLM with simple prompting like \"Steps for XYZ.\\\\n1.\", \"What are'\u001b[39m... 887 more characters,\n",
              "      metadata: {\n",
              "        source: \u001b[32m\"https://lilianweng.github.io/posts/2023-06-23-agent/\"\u001b[39m,\n",
              "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
              "      }\n",
              "    },\n",
              "    Document {\n",
              "      pageContent: \u001b[32m\"Agent System Overview\\n\"\u001b[39m +\n",
              "        \u001b[32m\"                \\n\"\u001b[39m +\n",
              "        \u001b[32m\"                    Component One: Planning\\n\"\u001b[39m +\n",
              "        \u001b[32m\"                 \"\u001b[39m... 850 more characters,\n",
              "      metadata: {\n",
              "        source: \u001b[32m\"https://lilianweng.github.io/posts/2023-06-23-agent/\"\u001b[39m,\n",
              "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
              "      }\n",
              "    },\n",
              "    Document {\n",
              "      pageContent: \u001b[32m\"Resources:\\n\"\u001b[39m +\n",
              "        \u001b[32m\"1. Internet access for searches and information gathering.\\n\"\u001b[39m +\n",
              "        \u001b[32m\"2. Long Term memory management\"\u001b[39m... 456 more characters,\n",
              "      metadata: {\n",
              "        source: \u001b[32m\"https://lilianweng.github.io/posts/2023-06-23-agent/\"\u001b[39m,\n",
              "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
              "      }\n",
              "    }\n",
              "  ],\n",
              "  answer: \u001b[32m\"Task decomposition is a technique used to break down complex tasks into smaller and simpler steps fo\"\u001b[39m... 230 more characters\n",
              "}"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "import \"cheerio\";\n",
        "import { CheerioWebBaseLoader } from \"@langchain/community/document_loaders/web/cheerio\";\n",
        "import { RecursiveCharacterTextSplitter } from \"langchain/text_splitter\";\n",
        "import { MemoryVectorStore } from \"langchain/vectorstores/memory\"\n",
        "import { OpenAIEmbeddings, ChatOpenAI } from \"@langchain/openai\";\n",
        "import { pull } from \"langchain/hub\";\n",
        "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
        "import { formatDocumentsAsString } from \"langchain/util/document\";\n",
        "import { RunnableSequence, RunnablePassthrough, RunnableMap } from \"@langchain/core/runnables\";\n",
        "import { StringOutputParser } from \"@langchain/core/output_parsers\";\n",
        "\n",
        "const loader = new CheerioWebBaseLoader(\n",
        "  \"https://lilianweng.github.io/posts/2023-06-23-agent/\"\n",
        ");\n",
        "\n",
        "const docs = await loader.load();\n",
        "\n",
        "const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000, chunkOverlap: 200 });\n",
        "const splits = await textSplitter.splitDocuments(docs);\n",


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "afaf8039",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "sidebar_label: Azure OpenAI\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a3d6f34",
   "metadata": {},
   "source": [
    "# AzureOpenAIEmbeddings\n",
    "\n",
    "[Azure OpenAI](https://azure.microsoft.com/products/ai-services/openai-service/) is a cloud service to help you quickly develop generative AI experiences with a diverse set of prebuilt and curated models from OpenAI, Meta and beyond.\n",
    "\n",
    "LangChain.js supports integration with [Azure OpenAI](https://azure.microsoft.com/products/ai-services/openai-service/) using the new Azure integration in the [OpenAI SDK](https://github.com/openai/openai-node).\n",
    "\n",
    "You can learn more about Azure OpenAI and its difference with the OpenAI API on [this page](https://learn.microsoft.com/azure/ai-services/openai/overview). If you don't have an Azure account, you can [create a free account](https://azure.microsoft.com/free/) to get started.\n",
    "\n",
    "This will help you get started with AzureOpenAIEmbeddings [embedding models](/docs/concepts#embedding-models) using LangChain. For detailed documentation on `AzureOpenAIEmbeddings` features and configuration options, please refer to the [API reference](https://api.js.langchain.com/classes/langchain_openai.AzureOpenAIEmbeddings.html).\n",
    "\n",
    "\n",
    "```{=mdx}\n",
    "\n",
    ":::info\n",
    "\n",
    "Previously, LangChain.js supported integration with Azure OpenAI using the dedicated [Azure OpenAI SDK](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/openai/openai). This SDK is now deprecated in favor of the new Azure integration in the OpenAI SDK, which allows to access the latest OpenAI models and features the same day they are released, and allows seamless transition between the OpenAI API and Azure OpenAI.\n",
    "\n",
    "If you are using Azure OpenAI with the deprecated SDK, see the [migration guide](#migration-from-azure-openai-sdk) to update to the new API.\n",
    "\n",
    ":::\n",
    "\n",
    "```\n",
    "\n",
    "## Overview\n",
    "### Integration details\n",
    "\n",
    "| Class | Package | Local | [Py support](https://python.langchain.com/docs/integrations/text_embedding/azureopenai/) | Package downloads | Package latest |\n",
    "| :--- | :--- | :---: | :---: |  :---: | :---: |\n",
    "| [AzureOpenAIEmbeddings](https://api.js.langchain.com/classes/langchain_openai.AzureOpenAIEmbeddings.html) | [@langchain/openai](https://api.js.langchain.com/modules/langchain_openai.html) | ❌ | ✅ | ![NPM - Downloads](https://img.shields.io/npm/dm/@langchain/openai?style=flat-square&label=%20&) | ![NPM - Version](https://img.shields.io/npm/v/@langchain/openai?style=flat-square&label=%20&) |\n",
    "\n",
    "## Setup\n",
    "\n",
    "To access Azure OpenAI embedding models you'll need to create an Azure account, get an API key, and install the `@langchain/openai` integration package.\n",
    "\n",
    "### Credentials\n",
    "\n",
    "You'll need to have an Azure OpenAI instance deployed. You can deploy a version on Azure Portal following [this guide](https://learn.microsoft.com/azure/ai-services/openai/how-to/create-resource?pivots=web-portal).\n",
    "\n",
    "Once you have your instance running, make sure you have the name of your instance and key. You can find the key in the Azure Portal, under the \"Keys and Endpoint\" section of your instance.\n",
    "\n",
    "If you're using Node.js, you can define the following environment variables to use the service:\n",
    "\n",
    "```bash\n",
    "AZURE_OPENAI_API_INSTANCE_NAME=<YOUR_INSTANCE_NAME>\n",
    "AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME=<YOUR_EMBEDDINGS_DEPLOYMENT_NAME>\n",
    "AZURE_OPENAI_API_KEY=<YOUR_KEY>\n",
    "AZURE_OPENAI_API_VERSION=\"2024-02-01\"\n",
    "```\n",
    "\n",
    "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n",
    "\n",
    "```bash\n",
    "# export LANGCHAIN_TRACING_V2=\"true\"\n",
    "# export LANGCHAIN_API_KEY=\"your-api-key\"\n",
    "```\n",
    "\n",
    "### Installation\n",
    "\n",
    "The LangChain AzureOpenAIEmbeddings integration lives in the `@langchain/openai` package:\n",
    "\n",
    "```{=mdx}\n",
    "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/openai @langchain/core\n",
    "</Npm2Yarn>\n",
    "\n",
    ":::info\n",
    "\n",
    "You can find the list of supported API versions in the [Azure OpenAI documentation](https://learn.microsoft.com/azure/ai-services/openai/reference).\n",
    "\n",
    ":::\n",
    "\n",
    ":::tip\n",
    "\n",
    "If `AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME` is not defined, it will fall back to the value of `AZURE_OPENAI_API_DEPLOYMENT_NAME` for the deployment name. The same applies to the `azureOpenAIApiEmbeddingsDeploymentName` parameter in the `AzureOpenAIEmbeddings` constructor, which will fall back to the value of `azureOpenAIApiDeploymentName` if not defined.\n",
    "\n",
    ":::\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45dd1724",
   "metadata": {},
   "source": [
    "## Instantiation\n",
    "\n",
    "Now we can instantiate our model object and embed text:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9ea7a09b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import { AzureOpenAIEmbeddings } from \"@langchain/openai\";\n",
    "\n",
    "const embeddings = new AzureOpenAIEmbeddings({\n",
    "  azureOpenAIApiKey: \"<your_key>\", // In Node.js defaults to process.env.AZURE_OPENAI_API_KEY\n",
    "  azureOpenAIApiInstanceName: \"<your_instance_name>\", // In Node.js defaults to process.env.AZURE_OPENAI_API_INSTANCE_NAME\n",
    "  azureOpenAIApiEmbeddingsDeploymentName: \"<your_embeddings_deployment_name>\", // In Node.js defaults to process.env.AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME\n",
    "  azureOpenAIApiVersion: \"<api_version>\", // In Node.js defaults to process.env.AZURE_OPENAI_API_VERSION\n",
    "  maxRetries: 1,\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77d271b6",
   "metadata": {},
   "source": [
    "## Indexing and Retrieval\n",
    "\n",
    "Embedding models are often used in retrieval-augmented generation (RAG) flows, both as part of indexing data as well as later retrieving it. For more detailed instructions, please see our RAG tutorials under the [working with external knowledge tutorials](/docs/tutorials/#working-with-external-knowledge).\n",
    "\n",
    "Below, see how to index and retrieve data using the `embeddings` object we initialized above. In this example, we will index and retrieve a sample document using the demo [`MemoryVectorStore`](/docs/integrations/vectorstores/memory)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d817716b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "afaf8039",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "sidebar_label: HNSWLib\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e49f1e0d",
   "metadata": {},
   "source": [
    "# HNSWLib\n",
    "\n",
    "This guide will help you getting started with such a retriever backed by a [HNSWLib vector store](/docs/integrations/vectorstores/hnswlib). For detailed documentation of all features and configurations head to the [API reference](https://api.js.langchain.com/classes/langchain.retrievers_self_query.SelfQueryRetriever.html).\n",
    "\n",
    "## Overview\n",
    "\n",
    "A [self-query retriever](/docs/how_to/self_query/) retrieves documents by dynamically generating metadata filters based on some input query. This allows the retriever to account for underlying document metadata in addition to pure semantic similarity when fetching results.\n",
    "\n",
    "It uses a module called a `Translator` that generates a filter based on information about metadata fields and the query language that a given vector store supports.\n",
    "\n",
    "### Integration details\n",
    "\n",
    "| Backing vector store | Self-host | Cloud offering | Package | Py support |\n",
    "| :--- | :--- | :---: | :---: | :---: |\n",
    "[`HNSWLib`](https://api.js.langchain.com/classes/langchain_community_vectorstores_hnswlib.HNSWLib.html) | ✅ | ❌ | [`@langchain/community`](https://www.npmjs.com/package/@langchain/community) | ❌ |\n",
    "\n",
    "## Setup\n",
    "\n",
    "Set up a HNSWLib instance as documented [here](/docs/integrations/vectorstores/hnswlib).\n",
    "\n",
    "If you want to get automated tracing from individual queries, you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n",
    "\n",
    "```typescript\n",
    "// process.env.LANGSMITH_API_KEY = \"<YOUR API KEY HERE>\";\n",
    "// process.env.LANGSMITH_TRACING = \"true\";\n",
    "```\n",
    "\n",
    "### Installation\n",
    "\n",
    "The vector store lives in the `@langchain/community` package. You'll also need to install the `langchain` package to import the main `SelfQueryRetriever` class.\n",
    "\n",
    "For this example, we'll also use OpenAI embeddings, so you'll need to install the `@langchain/openai` package and [obtain an API key](https://platform.openai.com):\n",
    "\n",
    "```{=mdx}\n",
    "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/community langchain @langchain/openai @langchain/core\n",
    "</Npm2Yarn>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a38cde65-254d-4219-a441-068766c0d4b5",
   "metadata": {},
   "source": [
    "## Instantiation\n",
    "\n",
    "First, initialize your HNSWLib vector store with some documents that contain metadata:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e7fd15a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import { OpenAIEmbeddings } from \"@langchain/openai\";\n",
    "import { HNSWLib } from \"@langchain/community/vectorstores/hnswlib\";\n",
    "import { Document } from \"@langchain/core/documents\";\n",
    "import type { AttributeInfo } from \"langchain/chains/query_constructor\";\n",
    "\n",
    "/**\n",
    " * First, we create a bunch of documents. You can load your own documents here instead.\n",
    " * Each document has a pageContent and a metadata field. Make sure your metadata matches the AttributeInfo below.\n",
    " */\n",
    "const docs = [\n",
    "  new Document({\n",
    "    pageContent:\n",
    "      \"A bunch of scientists bring back dinosaurs and mayhem breaks loose\",\n",
    "    metadata: { year: 1993, rating: 7.7, genre: \"science fiction\" },\n",
    "  }),\n",
    "  new Document({\n",
    "    pageContent:\n",
    "      \"Leo DiCaprio gets lost in a dream within a dream within a dream within a ...\",\n",
    "    metadata: { year: 2010, director: \"Christopher Nolan\", rating: 8.2 },\n",
    "  }),\n",
    "  new Document({\n",
    "    pageContent:\n",
    "      \"A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea\",\n",
    "    metadata: { year: 2006, director: \"Satoshi Kon\", rating: 8.6 },\n",
    "  }),\n",
    "  new Document({\n",
    "    pageContent:\n",
    "      \"A bunch of normal-sized women are supremely wholesome and some men pine after them\",\n",
    "    metadata: { year: 2019, director: \"Greta Gerwig\", rating: 8.3 },\n",
    "  }),\n",
    "  new Document({\n",
    "    pageContent: \"Toys come alive and have a blast doing so\",\n",
    "    metadata: { year: 1995, genre: \"animated\" },\n",
    "  }),\n",
    "  new Document({\n",
    "    pageContent: \"Three men walk into the Zone, three men walk out of the Zone\",\n",
    "    metadata: {\n",
    "      year: 1979,\n",
    "      director: \"Andrei Tarkovsky\",\n",
    "      genre: \"science fiction\",\n",
    "      rating: 9.9,\n",
    "    },\n",
    "  }),\n",
    "];\n",
    "\n",
    "/**\n",
    " * Next, we define the attributes we want to be able to query on.\n",
    " * in this case, we want to be able to query on the genre, year, director, rating, and length of the movie.\n",
    " * We also provide a description of each attribute and the type of the attribute.\n",
    " * This is used to generate the query prompts.\n",
    " */\n",
    "const attributeInfo: AttributeInfo[] = [\n",
    "  {\n",
    "    name: \"genre\",\n",
    "    description: \"The genre of the movie\",\n",
    "    type: \"string or array of strings\",\n",
    "  },\n",
    "  {\n",
    "    name: \"year\",\n",
    "    description: \"The year the movie was released\",\n",
    "    type: \"number\",\n",
    "  },\n",
    "  {\n",
    "    name: \"director\",\n",
    "    description: \"The director of the movie\",\n",
    "    type: \"string\",\n",
    "  },\n",
    "  {\n",
    "    name: \"rating\",\n",
    "    description: \"The rating of the movie (1-10)\",\n",
    "    type: \"number\",\n",
    "  },\n",
    "  {\n",
    "    name: \"length\",\n",
    "    description: \"The length of the movie in minutes\",\n",
    "    type: \"number\",\n",
    "  },\n",
    "];\n",
    "\n",
    "/**\n",
    " * Next, we instantiate a vector store. This is where we store the embeddings of the documents.\n",
    " * We also need to provide an embeddings object. This is used to embed the documents.\n",
    " */\n",
    "const embeddings = new OpenAIEmbeddings();\n",
    "const vectorStore = await HNSWLib.fromDocuments(docs, embeddings);"
   ]
  },
  {


---
keywords: [azure]
---

import CodeBlock from "@theme/CodeBlock";

# Microsoft

All functionality related to `Microsoft Azure` and other `Microsoft` products.

## Chat Models

### Azure OpenAI

See a [usage example](/docs/integrations/chat/azure)

import AzureChatOpenAI from "@examples/models/chat/integration_azure_openai.ts";

<UnifiedModelParamsTooltip></UnifiedModelParamsTooltip>

<CodeBlock language="typescript">{AzureChatOpenAI}</CodeBlock>

## LLM

### Azure OpenAI

> [Microsoft Azure](https://en.wikipedia.org/wiki/Microsoft_Azure), often referred to as `Azure` is a cloud computing platform run by `Microsoft`, which offers access, management, and development of applications and services through global data centers. It provides a range of capabilities, including software as a service (SaaS), platform as a service (PaaS), and infrastructure as a service (IaaS). `Microsoft Azure` supports many programming languages, tools, and frameworks, including Microsoft-specific and third-party software and systems.

> [Azure OpenAI](https://azure.microsoft.com/products/ai-services/openai-service/) is a cloud service to help you quickly develop generative AI experiences with a diverse set of prebuilt and curated models from OpenAI, Meta and beyond.

LangChain.js supports integration with [Azure OpenAI](https://azure.microsoft.com/products/ai-services/openai-service/) using the new Azure integration in the [OpenAI SDK](https://github.com/openai/openai-node).

You can learn more about Azure OpenAI and its difference with the OpenAI API on [this page](https://learn.microsoft.com/azure/ai-services/openai/overview). If you don't have an Azure account, you can [create a free account](https://azure.microsoft.com/free/) to get started.

You'll need to have an Azure OpenAI instance deployed. You can deploy a version on Azure Portal following [this guide](https://learn.microsoft.com/azure/ai-services/openai/how-to/create-resource?pivots=web-portal).

Once you have your instance running, make sure you have the name of your instance and key. You can find the key in the Azure Portal, under the "Keys and Endpoint" section of your instance.

If you're using Node.js, you can define the following environment variables to use the service:

```bash
AZURE_OPENAI_API_INSTANCE_NAME=<YOUR_INSTANCE_NAME>
AZURE_OPENAI_API_DEPLOYMENT_NAME=<YOUR_DEPLOYMENT_NAME>
AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME=<YOUR_EMBEDDINGS_DEPLOYMENT_NAME>
AZURE_OPENAI_API_KEY=<YOUR_KEY>
AZURE_OPENAI_API_VERSION="2024-02-01"
```

:::info

You can find the list of supported API versions in the [Azure OpenAI documentation](https://learn.microsoft.com/azure/ai-services/openai/reference).

:::

import IntegrationInstallTooltip from "@mdx_components/integration_install_tooltip.mdx";

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/openai @langchain/core
```

See a [usage example](/docs/integrations/llms/azure).

import AzureOpenAI from "@examples/models/llm/azure_openai.ts";

import UnifiedModelParamsTooltip from "@mdx_components/unified_model_params_tooltip.mdx";

<UnifiedModelParamsTooltip></UnifiedModelParamsTooltip>

<CodeBlock language="typescript">{AzureOpenAI}</CodeBlock>

## Text Embedding Models

### Azure OpenAI

See a [usage example](/docs/integrations/text_embedding/azure_openai)

import AzureOpenAIEmbeddings from "@examples/models/embeddings/azure_openai.ts";

<UnifiedModelParamsTooltip></UnifiedModelParamsTooltip>

<CodeBlock language="typescript">{AzureOpenAIEmbeddings}</CodeBlock>

## Vector stores

### Azure AI Search

> [Azure AI Search](https://azure.microsoft.com/products/ai-services/ai-search) (formerly known as Azure Search and Azure Cognitive Search) is a distributed, RESTful search engine optimized for speed and relevance on production-scale workloads on Azure. It supports also vector search using the [k-nearest neighbor](https://en.wikipedia.org/wiki/Nearest_neighbor_search) (kNN) algorithm and also [semantic search](https://learn.microsoft.com/azure/search/semantic-search-overview).

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install -S @langchain/community @langchain/core @azure/search-documents
```

See a [usage example](/docs/integrations/vectorstores/azure_aisearch).

```typescript
import { AzureAISearchVectorStore } from "@langchain/community/vectorstores/azure_aisearch";
```

### Azure Cosmos DB for NoSQL

> [Azure Cosmos DB for NoSQL](https://learn.microsoft.com/azure/cosmos-db/nosql/) provides support for querying items with flexible schemas and native support for JSON. It now offers vector indexing and search. This feature is designed to handle high-dimensional vectors, enabling efficient and accurate vector search at any scale. You can now store vectors directly in the documents alongside your data. Each document in your database can contain not only traditional schema-free data, but also high-dimensional vectors as other properties of the documents.

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/azure-cosmosdb @langchain/core
```

See a [usage example](/docs/integrations/vectorstores/azure_cosmosdb_nosql).

```typescript
import { AzureCosmosDBNoSQLVectorStore } from "@langchain/azure-cosmosdb";
```

### Azure Cosmos DB for MongoDB vCore

> [Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/) makes it easy to create a database with full native MongoDB support. You can apply your MongoDB experience and continue to use your favorite MongoDB drivers, SDKs, and tools by pointing your application to the API for MongoDB vCore account’s connection string. Use vector search in Azure Cosmos DB for MongoDB vCore to seamlessly integrate your AI-based applications with your data that’s stored in Azure Cosmos DB.

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/azure-cosmosdb @langchain/core
```

See a [usage example](/docs/integrations/vectorstores/azure_cosmosdb_mongodb).

```typescript
import { AzureCosmosDBMongoDBVectorStore } from "@langchain/azure-cosmosdb";
```

## Document loaders

### Azure Blob Storage

> [Azure Blob Storage](https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction) is Microsoft's object storage solution for the cloud. Blob Storage is optimized for storing massive amounts of unstructured data. Unstructured data is data that doesn't adhere to a particular data model or definition, such as text or binary data.

> [Azure Files](https://learn.microsoft.com/azure/storage/files/storage-files-introduction) offers fully managed
> file shares in the cloud that are accessible via the industry standard Server Message Block (`SMB`) protocol,
> Network File System (`NFS`) protocol, and `Azure Files REST API`. `Azure Files` are based on the `Azure Blob Storage`.

`Azure Blob Storage` is designed for:

- Serving images or documents directly to a browser.
- Storing files for distributed access.
- Streaming video and audio.
- Writing to log files.
- Storing data for backup and restore, disaster recovery, and archiving.
- Storing data for analysis by an on-premises or Azure-hosted service.

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/community @langchain/core @azure/storage-blob
```

See a [usage example for the Azure Blob Storage](/docs/integrations/document_loaders/web_loaders/azure_blob_storage_container).

```typescript
import { AzureBlobStorageContainerLoader } from "@langchain/community/document_loaders/web/azure_blob_storage_container";
```

See a [usage example for the Azure Files](/docs/integrations/document_loaders/web_loaders/azure_blob_storage_file).

```typescript
import { AzureBlobStorageFileLoader } from "@langchain/community/document_loaders/web/azure_blob_storage_file";
```

## Tools

### Azure Container Apps Dynamic Sessions

> [Azure Container Apps dynamic sessions](https://learn.microsoft.com/azure/container-apps/sessions) provide fast access to secure sandboxed environments that are ideal for running code or applications that require strong isolation from other workloads.

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/azure-dynamic-sessions @langchain/core
```

See a [usage example](/docs/integrations/tools/azure_dynamic_sessions).

```typescript
import { SessionsPythonREPLTool } from "@langchain/azure-dynamic-sessions";
```


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "afaf8039",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "sidebar_label: Azure OpenAI\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e49f1e0d",
   "metadata": {},
   "source": [
    "# AzureChatOpenAI\n",
    "\n",
    "Azure OpenAI is a Microsoft Azure service that provides powerful language models from OpenAI.\n",
    "\n",
    "This will help you getting started with AzureChatOpenAI [chat models](/docs/concepts/#chat-models). For detailed documentation of all AzureChatOpenAI features and configurations head to the [API reference](https://api.js.langchain.com/classes/langchain_openai.AzureChatOpenAI.html).\n",
    "\n",
    "## Overview\n",
    "### Integration details\n",
    "\n",
    "| Class | Package | Local | Serializable | [PY support](https://python.langchain.com/docs/integrations/chat/azure_chat_openai) | Package downloads | Package latest |\n",
    "| :--- | :--- | :---: | :---: |  :---: | :---: | :---: |\n",
    "| [AzureChatOpenAI](https://api.js.langchain.com/classes/langchain_openai.AzureChatOpenAI.html) | [`@langchain/openai`](https://www.npmjs.com/package/@langchain/openai) | ❌ | ✅ | ✅ | ![NPM - Downloads](https://img.shields.io/npm/dm/@langchain/openai?style=flat-square&label=%20&) | ![NPM - Version](https://img.shields.io/npm/v/@langchain/openai?style=flat-square&label=%20&) |\n",
    "\n",
    "### Model features\n",
    "\n",
    "See the links in the table headers below for guides on how to use specific features.\n",
    "\n",
    "| [Tool calling](/docs/how_to/tool_calling) | [Structured output](/docs/how_to/structured_output/) | JSON mode | [Image input](/docs/how_to/multimodal_inputs/) | Audio input | Video input | [Token-level streaming](/docs/how_to/chat_streaming/) | [Token usage](/docs/how_to/chat_token_usage_tracking/) | [Logprobs](/docs/how_to/logprobs/) |\n",
    "| :---: | :---: | :---: | :---: |  :---: | :---: | :---: | :---: | :---: |\n",
    "| ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | \n",
    "\n",
    "## Setup\n",
    "\n",
    "[Azure OpenAI](https://azure.microsoft.com/products/ai-services/openai-service/) is a cloud service to help you quickly develop generative AI experiences with a diverse set of prebuilt and curated models from OpenAI, Meta and beyond.\n",
    "\n",
    "LangChain.js supports integration with [Azure OpenAI](https://azure.microsoft.com/products/ai-services/openai-service/) using the new Azure integration in the [OpenAI SDK](https://github.com/openai/openai-node).\n",
    "\n",
    "You can learn more about Azure OpenAI and its difference with the OpenAI API on [this page](https://learn.microsoft.com/azure/ai-services/openai/overview).\n",
    "\n",
    "### Credentials\n",
    "\n",
    "If you don't have an Azure account, you can [create a free account](https://azure.microsoft.com/free/) to get started.\n",
    "\n",
    "You'll also need to have an Azure OpenAI instance deployed. You can deploy a version on Azure Portal following [this guide](https://learn.microsoft.com/azure/ai-services/openai/how-to/create-resource?pivots=web-portal).\n",
    "\n",
    "Once you have your instance running, make sure you have the name of your instance and key. You can find the key in the Azure Portal, under the \"Keys and Endpoint\" section of your instance. Then, if using Node.js, you can set your credentials as environment variables:\n",
    "\n",
    "```bash\n",
    "AZURE_OPENAI_API_INSTANCE_NAME=<YOUR_INSTANCE_NAME>\n",
    "AZURE_OPENAI_API_DEPLOYMENT_NAME=<YOUR_DEPLOYMENT_NAME>\n",
    "AZURE_OPENAI_API_KEY=<YOUR_KEY>\n",
    "AZURE_OPENAI_API_VERSION=\"2024-02-01\"\n",
    "```\n",
    "\n",
    "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n",
    "\n",
    "```bash\n",
    "# export LANGCHAIN_TRACING_V2=\"true\"\n",
    "# export LANGCHAIN_API_KEY=\"your-api-key\"\n",
    "```\n",
    "\n",
    "### Installation\n",
    "\n",
    "The LangChain AzureChatOpenAI integration lives in the `@langchain/openai` package:\n",
    "\n",
    "```{=mdx}\n",
    "\n",
    "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/openai @langchain/core\n",
    "</Npm2Yarn>\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a38cde65-254d-4219-a441-068766c0d4b5",
   "metadata": {},
   "source": [
    "## Instantiation\n",
    "\n",
    "Now we can instantiate our model object and generate chat completions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "cb09c344-1836-4e0c-acf8-11d13ac1dbae",
   "metadata": {},
   "outputs": [],
   "source": [
    "import { AzureChatOpenAI } from \"@langchain/openai\" \n",
    "\n",
    "const llm = new AzureChatOpenAI({\n",
    "    model: \"gpt-4o\",\n",
    "    temperature: 0,\n",
    "    maxTokens: undefined,\n",
    "    maxRetries: 2,\n",
    "    azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY, // In Node.js defaults to process.env.AZURE_OPENAI_API_KEY\n",
    "    azureOpenAIApiInstanceName: process.env.AZURE_OPENAI_API_INSTANCE_NAME, // In Node.js defaults to process.env.AZURE_OPENAI_API_INSTANCE_NAME\n",
    "    azureOpenAIApiDeploymentName: process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME, // In Node.js defaults to process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME\n",
    "    azureOpenAIApiVersion: process.env.AZURE_OPENAI_API_VERSION, // In Node.js defaults to process.env.AZURE_OPENAI_API_VERSION\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b4f3e15",
   "metadata": {},
   "source": [
    "## Invocation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "62e0dbc3",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AIMessage {\n",
      "  \"id\": \"chatcmpl-9qrWKByvVrzWMxSn8joRZAklHoB32\",\n",
      "  \"content\": \"J'adore la programmation.\",\n",
      "  \"additional_kwargs\": {},\n",
      "  \"response_metadata\": {\n",
      "    \"tokenUsage\": {\n",
      "      \"completionTokens\": 8,\n",
      "      \"promptTokens\": 31,\n",
      "      \"totalTokens\": 39\n",
      "    },\n",
      "    \"finish_reason\": \"stop\"\n",
      "  },\n",
      "  \"tool_calls\": [],\n",
      "  \"invalid_tool_calls\": [],\n",
      "  \"usage_metadata\": {\n",
      "    \"input_tokens\": 31,\n",
      "    \"output_tokens\": 8,\n",
      "    \"total_tokens\": 39\n",
      "  }\n",


"}\n"
     ]
    }
   ],
   "source": [
    "const aiMsg = await llm.invoke([\n",
    "    [\n",
    "        \"system\",\n",
    "        \"You are a helpful assistant that translates English to French. Translate the user sentence.\",\n",
    "    ],\n",
    "    [\"human\", \"I love programming.\"],\n",
    "])\n",
    "aiMsg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d86145b3-bfef-46e8-b227-4dda5c9c2705",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "J'adore la programmation.\n"
     ]
    }
   ],
   "source": [
    "console.log(aiMsg.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18e2bfc0-7e78-4528-a73f-499ac150dca8",
   "metadata": {},
   "source": [
    "## Chaining\n",
    "\n",
    "We can [chain](/docs/how_to/sequence/) our model with a prompt template like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e197d1d7-a070-4c96-9f8a-a0e86d046e0b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AIMessage {\n",
      "  \"id\": \"chatcmpl-9qrWR7WiNjZ3leSG4Wd77cnKEVivv\",\n",
      "  \"content\": \"Ich liebe das Programmieren.\",\n",
      "  \"additional_kwargs\": {},\n",
      "  \"response_metadata\": {\n",
      "    \"tokenUsage\": {\n",
      "      \"completionTokens\": 6,\n",
      "      \"promptTokens\": 26,\n",
      "      \"totalTokens\": 32\n",
      "    },\n",
      "    \"finish_reason\": \"stop\"\n",
      "  },\n",
      "  \"tool_calls\": [],\n",
      "  \"invalid_tool_calls\": [],\n",
      "  \"usage_metadata\": {\n",
      "    \"input_tokens\": 26,\n",
      "    \"output_tokens\": 6,\n",
      "    \"total_tokens\": 32\n",
      "  }\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "import { ChatPromptTemplate } from \"@langchain/core/prompts\"\n",
    "\n",
    "const prompt = ChatPromptTemplate.fromMessages(\n",
    "    [\n",
    "        [\n",
    "            \"system\",\n",
    "            \"You are a helpful assistant that translates {input_language} to {output_language}.\",\n",
    "        ],\n",
    "        [\"human\", \"{input}\"],\n",
    "    ]\n",
    ")\n",
    "\n",
    "const chain = prompt.pipe(llm);\n",
    "await chain.invoke(\n",
    "    {\n",
    "        input_language: \"English\",\n",
    "        output_language: \"German\",\n",
    "        input: \"I love programming.\",\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1ee55bc-ffc8-4cfa-801c-993953a08cfd",
   "metadata": {},
   "source": [
    "## Using Azure Managed Identity\n",
    "\n",
    "If you're using Azure Managed Identity, you can configure the credentials like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d7f47b2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import {\n",
    "  DefaultAzureCredential,\n",
    "  getBearerTokenProvider,\n",
    "} from \"@azure/identity\";\n",
    "import { AzureChatOpenAI } from \"@langchain/openai\";\n",
    "\n",
    "const credentials = new DefaultAzureCredential();\n",
    "const azureADTokenProvider = getBearerTokenProvider(\n",
    "  credentials,\n",
    "  \"https://cognitiveservices.azure.com/.default\"\n",
    ");\n",
    "\n",
    "const llmWithManagedIdentity = new AzureChatOpenAI({\n",
    "  azureADTokenProvider,\n",
    "  azureOpenAIApiInstanceName: \"<your_instance_name>\",\n",
    "  azureOpenAIApiDeploymentName: \"<your_deployment_name>\",\n",
    "  azureOpenAIApiVersion: \"<api_version>\",\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a889856",
   "metadata": {},
   "source": [
    "## Using a different domain\n",
    "\n",
    "If your instance is hosted under a domain other than the default `openai.azure.com`, you'll need to use the alternate `AZURE_OPENAI_BASE_PATH` environment variable.\n",
    "For example, here's how you would connect to the domain `https://westeurope.api.microsoft.com/openai/deployments/{DEPLOYMENT_NAME}`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ace7f876",
   "metadata": {},
   "outputs": [],
   "source": [
    "import { AzureChatOpenAI } from \"@langchain/openai\";\n",
    "\n",
    "const llmWithDifferentDomain = new AzureChatOpenAI({\n",
    "  temperature: 0.9,\n",
    "  azureOpenAIApiKey: \"<your_key>\", // In Node.js defaults to process.env.AZURE_OPENAI_API_KEY\n",
    "  azureOpenAIApiDeploymentName: \"<your_deployment_name>\", // In Node.js defaults to process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME\n",
    "  azureOpenAIApiVersion: \"<api_version>\", // In Node.js defaults to process.env.AZURE_OPENAI_API_VERSION\n",
    "  azureOpenAIBasePath:\n",
    "    \"https://westeurope.api.microsoft.com/openai/deployments\", // In Node.js defaults to process.env.AZURE_OPENAI_BASE_PATH\n",
    "});\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "092e7a38",
   "metadata": {},
   "source": [
    "## Custom headers\n",
    "\n",
    "You can specify custom headers by passing in a `configuration` field:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43503a94",
   "metadata": {},
   "outputs": [],
   "source": [
    "import { AzureChatOpenAI } from \"@langchain/openai\";\n",
    "\n",
    "const llmWithCustomHeaders = new AzureChatOpenAI({\n",
    "  azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY, // In Node.js defaults to process.env.AZURE_OPENAI_API_KEY\n",
    "  azureOpenAIApiInstanceName: process.env.AZURE_OPENAI_API_INSTANCE_NAME, // In Node.js defaults to process.env.AZURE_OPENAI_API_INSTANCE_NAME\n",
    "  azureOpenAIApiDeploymentName: process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME, // In Node.js defaults to process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME\n",
    "  azureOpenAIApiVersion: process.env.AZURE_OPENAI_API_VERSION, // In Node.js defaults to process.env.AZURE_OPENAI_API_VERSION\n",
    "  configuration: {\n",
    "    defaultHeaders: {\n",
    "      \"x-custom-header\": `SOME_VALUE`,\n",
    "    },\n",
    "  },\n",
    "});\n",
    "\n",
    "await llmWithCustomHeaders.invoke(\"Hi there!\");"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a6b849d",
   "metadata": {},
   "source": [
    "The `configuration` field also accepts other `ClientOptions` parameters accepted by the official SDK.\n",
    "\n",
    "**Note:** The specific header `api-key` currently cannot be overridden in this manner and will pass through the value from `azureOpenAIApiKey`."
   ]
  },
  {


"cell_type": "markdown",
   "id": "0ac0310c",
   "metadata": {},
   "source": [
    "## Migration from Azure OpenAI SDK\n",
    "\n",
    "If you are using the deprecated Azure OpenAI SDK with the `@langchain/azure-openai` package, you can update your code to use the new Azure integration following these steps:\n",
    "\n",
    "1. Install the new `@langchain/openai` package and remove the previous `@langchain/azure-openai` package:\n",
    "\n",
    "```{=mdx}\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/openai\n",
    "</Npm2Yarn>\n",
    "\n",
    "```\n",
    "\n",
    "```bash\n",
    "npm uninstall @langchain/azure-openai\n",
    "```\n",
    "\n",
    "   \n",
    "2. Update your imports to use the new `AzureChatOpenAI` class from the `@langchain/openai` package:\n",
    "   ```typescript\n",
    "   import { AzureChatOpenAI } from \"@langchain/openai\";\n",
    "   ```\n",
    "3. Update your code to use the new `AzureChatOpenAI` class and pass the required parameters:\n",
    "\n",
    "   ```typescript\n",
    "   const model = new AzureChatOpenAI({\n",
    "     azureOpenAIApiKey: \"<your_key>\",\n",
    "     azureOpenAIApiInstanceName: \"<your_instance_name>\",\n",
    "     azureOpenAIApiDeploymentName: \"<your_deployment_name>\",\n",
    "     azureOpenAIApiVersion: \"<api_version>\",\n",
    "   });\n",
    "   ```\n",
    "\n",
    "   Notice that the constructor now requires the `azureOpenAIApiInstanceName` parameter instead of the `azureOpenAIEndpoint` parameter, and adds the `azureOpenAIApiVersion` parameter to specify the API version.\n",
    "\n",
    "   - If you were using Azure Managed Identity, you now need to use the `azureADTokenProvider` parameter to the constructor instead of `credentials`, see the [Azure Managed Identity](#using-azure-managed-identity) section for more details.\n",
    "\n",
    "   - If you were using environment variables, you now have to set the `AZURE_OPENAI_API_INSTANCE_NAME` environment variable instead of `AZURE_OPENAI_API_ENDPOINT`, and add the `AZURE_OPENAI_API_VERSION` environment variable to specify the API version.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3",
   "metadata": {},
   "source": [
    "## API reference\n",
    "\n",
    "For detailed documentation of all AzureChatOpenAI features and configurations head to the API reference: https://api.js.langchain.com/classes/langchain_openai.AzureChatOpenAI.html"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "TypeScript",
   "language": "typescript",
   "name": "tslab"
  },
  "language_info": {
   "codemirror_mode": {
    "mode": "typescript",
    "name": "javascript",
    "typescript": true
   },
   "file_extension": ".ts",
   "mimetype": "text/typescript",
   "name": "typescript",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}


"This property returns a list of \\`ToolCall\\`s. A \\`ToolCall\\` is an object with the following arguments:\n",
    "\n",
    "- \\`name\\`: The name of the tool that should be called.\n",
    "- \\`args\\`: The arguments to that tool.\n",
    "- \\`id\\`: The id of that tool call.\n",
    "\n",
    "#### SystemMessage\n",
    "\n",
    "This represents a system message, which tells the model how to behave. Not every model provider supports this.\n",
    "\n",
    "#### ToolMessage\n",
    "\n",
    "This represents the result of a tool call. In addition to \\`role\\` and \\`content\\`, this message has:\n",
    "\n",
    "- a \\`tool_call_id\\` field which conveys the id of the call to the tool that was called to produce this result.\n",
    "- an \\`artifact\\` field which can be used to pass along arbitrary artifacts of the tool execution which are useful to track but which should not be sent to the model.\n",
    "\n",
    "#### (Legacy) FunctionMessage\n",
    "\n",
    "This is a legacy message type, corresponding to OpenAI's legacy function-calling API. \\`ToolMessage\\` should be used instead to correspond to the updated tool-calling API.\n",
    "\n",
    "This represents the result of a function call. In addition to \\`role\\` and \\`content\\`, this message has a \\`name\\` parameter which conveys the name of the function that was called to produce this result.\n",
    "\n",
    "### Prompt templates\n",
    "\n",
    "\n",
    "\n",
    "Prompt templates help to translate user input and parameters into instructions for a language model.\n",
    "This can be used to guide a model's response, helping it understand the context and generate relevant and coherent language-based output.\n",
    "\n",
    "Prompt Templates take as input an object, where each key represents a variable in the prompt template to fill in.\n",
    "\n",
    "Prompt Templates output a PromptValue. This PromptValue can be passed to an LLM or a ChatModel, and can also be cast to a string or an array of messages.\n",
    "The reason this PromptValue exists is to make it easy to switch between strings and messages.\n",
    "\n",
    "There are a few different types of prompt templates:\n",
    "\n",
    "#### String PromptTemplates\n",
    "\n",
    "These prompt templates are used to format a single string, and generally are used for simpler inputs.\n",
    "For example, a common way to construct and use a PromptTemplate is as follows:\n",
    "\n",
    "\\`\\`\\`typescript\n",
    "import { PromptTemplate } from \"@langchain/core/prompts\";\n",
    "\n",
    "const promptTemplate = PromptTemplate.fromTemplate(\n",
    "  \"Tell me a joke about {topic}\"\n",
    ");\n",
    "\n",
    "await promptTemplate.invoke({ topic: \"cats\" });\n",
    "\\`\\`\\`\n",
    "\n",
    "#### ChatPromptTemplates\n",
    "\n",
    "These prompt templates are used to format an array of messages. These \"templates\" consist of an array of templates themselves.\n",
    "For example, a common way to construct and use a ChatPromptTemplate is as follows:\n",
    "\n",
    "\\`\\`\\`typescript\n",
    "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
    "\n",
    "const promptTemplate = ChatPromptTemplate.fromMessages([\n",
    "  [\"system\", \"You are a helpful assistant\"],\n",
    "  [\"user\", \"Tell me a joke about {topic}\"],\n",
    "]);\n",
    "\n",
    "await promptTemplate.invoke({ topic: \"cats\" });\n",
    "\\`\\`\\`\n",
    "\n",
    "In the above example, this ChatPromptTemplate will construct two messages when called.\n",
    "The first is a system message, that has no variables to format.\n",
    "The second is a HumanMessage, and will be formatted by the \\`topic\\` variable the user passes in.\n",
    "\n",
    "#### MessagesPlaceholder\n",
    "\n",
    "\n",
    "\n",
    "This prompt template is responsible for adding an array of messages in a particular place.\n",
    "In the above ChatPromptTemplate, we saw how we could format two messages, each one a string.\n",
    "But what if we wanted the user to pass in an array of messages that we would slot into a particular spot?\n",
    "This is how you use MessagesPlaceholder.\n",
    "\n",
    "\\`\\`\\`typescript\n",
    "import {\n",
    "  ChatPromptTemplate,\n",
    "  MessagesPlaceholder,\n",
    "} from \"@langchain/core/prompts\";\n",
    "import { HumanMessage } from \"@langchain/core/messages\";\n",
    "\n",
    "const promptTemplate = ChatPromptTemplate.fromMessages([\n",
    "  [\"system\", \"You are a helpful assistant\"],\n",
    "  new MessagesPlaceholder(\"msgs\"),\n",
    "]);\n",
    "\n",
    "promptTemplate.invoke({ msgs: [new HumanMessage({ content: \"hi!\" })] });\n",
    "\\`\\`\\`\n",
    "\n",
    "This will produce an array of two messages, the first one being a system message, and the second one being the HumanMessage we passed in.\n",
    "If we had passed in 5 messages, then it would have produced 6 messages in total (the system message plus the 5 passed in).\n",
    "This is useful for letting an array of messages be slotted into a particular spot.\n",
    "\n",
    "An alternative way to accomplish the same thing without using the \\`MessagesPlaceholder\\` class explicitly is:\n",
    "\n",
    "\\`\\`\\`typescript\n",
    "const promptTemplate = ChatPromptTemplate.fromMessages([\n",
    "  [\"system\", \"You are a helpful assistant\"],\n",
    "  [\"placeholder\", \"{msgs}\"], // <-- This is the changed part\n",
    "]);\n",
    "\\`\\`\\`\n",
    "\n",
    "For specifics on how to use prompt templates, see the [relevant how-to guides here](/docs/how_to/#prompt-templates).\n",
    "\n",
    "### Example Selectors\n",
    "\n",
    "One common prompting technique for achieving better performance is to include examples as part of the prompt.\n",
    "This gives the language model concrete examples of how it should behave.\n",
    "Sometimes these examples are hardcoded into the prompt, but for more advanced situations it may be nice to dynamically select them.\n",
    "Example Selectors are classes responsible for selecting and then formatting examples into prompts.\n",
    "\n",
    "For specifics on how to use example selectors, see the [relevant how-to guides here](/docs/how_to/#example-selectors).\n",
    "\n",
    "### Output parsers\n",
    "\n",
    "\n",
    "\n",
    ":::note\n",
    "\n",
    "The information here refers to parsers that take a text output from a model try to parse it into a more structured representation.\n",
    "More and more models are supporting function (or tool) calling, which handles this automatically.\n",
    "It is recommended to use function/tool calling rather than output parsing.\n",
    "See documentation for that [here](/docs/concepts/#function-tool-calling).\n",
    "\n",
    ":::\n",
    "\n",
    "Responsible for taking the output of a model and transforming it to a more suitable format for downstream tasks.\n",
    "Useful when you are using LLMs to generate structured data, or to normalize output from chat models and LLMs.\n",
    "\n",
    "There are two main methods an output parser must implement:\n",
    "\n",
    "- \"Get format instructions\": A method which returns a string containing instructions for how the output of a language model should be formatted.\n",
    "- \"Parse\": A method which takes in a string (assumed to be the response from a language model) and parses it into some structure.\n",
    "\n",
    "And then one optional one:\n",
    "\n",
    "- \"Parse with prompt\": A method which takes in a string (assumed to be the response from a language model) and a prompt (assumed to be the prompt that generated such a response) and parses it into some structure. The prompt is largely provided in the event the OutputParser wants to retry or fix the output in some way, and needs information from the prompt to do so.\n",


"Generally, such models are better at tool calling than non-fine-tuned models, and are recommended for use cases that require tool calling.\n",
    "Please see the [tool calling section](/docs/concepts/#functiontool-calling) for more information.\n",
    ":::\n",
    "\n",
    "For specifics on how to use chat models, see the [relevant how-to guides here](/docs/how_to/#chat-models).\n",
    "\n",
    "#### Multimodality\n",
    "\n",
    "Some chat models are multimodal, accepting images, audio and even video as inputs.\n",
    "These are still less common, meaning model providers haven't standardized on the \"best\" way to define the API.\n",
    "Multimodal outputs are even less common. As such, we've kept our multimodal abstractions fairly light weight\n",
    "and plan to further solidify the multimodal APIs and interaction patterns as the field matures.\n",
    "\n",
    "In LangChain, most chat models that support multimodal inputs also accept those values in OpenAI's content blocks format.\n",
    "So far this is restricted to image inputs. For models like Gemini which support video and other bytes input, the APIs also support the native, model-specific representations.\n",
    "\n",
    "For specifics on how to use multimodal models, see the [relevant how-to guides here](/docs/how_to/#multimodal).\n",
    "\n",
    "### LLMs\n",
    "\n",
    "\n",
    "\n",
    ":::caution\n",
    "Pure text-in/text-out LLMs tend to be older or lower-level. Many popular models are best used as [chat completion models](/docs/concepts/#chat-models),\n",
    "even for non-chat use cases.\n",
    "\n",
    "You are probably looking for [the section above instead](/docs/concepts/#chat-models).\n",
    ":::\n",
    "\n",
    "Language models that takes a string as input and returns a string.\n",
    "These are traditionally older models (newer models generally are [Chat Models](/docs/concepts/#chat-models), see above).\n",
    "\n",
    "Although the underlying models are string in, string out, the LangChain wrappers also allow these models to take messages as input.\n",
    "This gives them the same interface as [Chat Models](/docs/concepts/#chat-models).\n",
    "When messages are passed in as input, they will be formatted into a string under the hood before being passed to the underlying model.\n",
    "\n",
    "LangChain does not host any LLMs, rather we rely on third party integrations.\n",
    "\n",
    "For specifics on how to use LLMs, see the [relevant how-to guides here](/docs/how_to/#llms).\n",
    "\n",
    "### Message types\n",
    "\n",
    "Some language models take an array of messages as input and return a message.\n",
    "There are a few different types of messages.\n",
    "All messages have a \\`role\\`, \\`content\\`, and \\`response_metadata\\` property.\n",
    "\n",
    "The \\`role\\` describes WHO is saying the message.\n",
    "LangChain has different message classes for different roles.\n",
    "\n",
    "The \\`content\\` property describes the content of the message.\n",
    "This can be a few different things:\n",
    "\n",
    "- A string (most models deal this type of content)\n",
    "- A List of objects (this is used for multi-modal input, where the object contains information about that input type and that input location)\n",
    "\n",
    "#### HumanMessage\n",
    "\n",
    "This represents a message from the user.\n",
    "\n",
    "#### AIMessage\n",
    "\n",
    "This represents a message from the model. In addition to the \\`content\\` property, these messages also have:\n",
    "\n",
    "**\\`response_metadata\\`**\n",
    "\n",
    "The \\`response_metadata\\` property contains additional metadata about the response. The data here is often specific to each model provider.\n",
    "This is where information like log-probs and token usage may be stored.\n",
    "\n",
    "**\\`tool_calls\\`**\n",
    "\n",
    "These represent a decision from an language model to call a tool. They are included as part of an \\`AIMessage\\` output.\n",
    "They can be accessed from there with the \\`.tool_calls\\` property.\n",
    "\n",
    "This property returns a list of \\`ToolCall\\`s. A \\`ToolCall\\` is an object with the following arguments:\n",
    "\n",
    "- \\`name\\`: The name of the tool that should be called.\n",
    "- \\`args\\`: The arguments to that tool.\n",
    "- \\`id\\`: The id of that tool call.\n",
    "\n",
    "#### SystemMessage\n",
    "\n",
    "This represents a system message, which tells the model how to behave. Not every model provider supports this.\n",
    "\n",
    "#### ToolMessage\n",
    "\n",
    "This represents the result of a tool call. In addition to \\`role\\` and \\`content\\`, this message has:\n",
    "\n",
    "- a \\`tool_call_id\\` field which conveys the id of the call to the tool that was called to produce this result.\n",
    "- an \\`artifact\\` field which can be used to pass along arbitrary artifacts of the tool execution which are useful to track but which should not be sent to the model.\n",
    "\n",
    "#### (Legacy) FunctionMessage\n",
    "\n",
    "This is a legacy message type, corresponding to OpenAI's legacy function-calling API. \\`ToolMessage\\` should be used instead to correspond to the updated tool-calling API.\n",
    "\n",
    "This represents the result of a function call. In addition to \\`role\\` and \\`content\\`, this message has a \\`name\\` parameter which conveys the name of the function that was called to produce this result.\n",
    "\n",
    "### Prompt templates\n",
    "\n",
    "\n",
    "\n",
    "Prompt templates help to translate user input and parameters into instructions for a language model.\n",
    "This can be used to guide a model's response, helping it understand the context and generate relevant and coherent language-based output.\n",
    "\n",
    "Prompt Templates take as input an object, where each key represents a variable in the prompt template to fill in.\n",
    "\n",
    "Prompt Templates output a PromptValue. This PromptValue can be passed to an LLM or a ChatModel, and can also be cast to a string or an array of messages.\n",
    "The reason this PromptValue exists is to make it easy to switch between strings and messages.\n",
    "\n",
    "There are a few different types of prompt templates:\n",
    "\n",
    "#### String PromptTemplates\n",
    "\n",
    "These prompt templates are used to format a single string, and generally are used for simpler inputs.\n",
    "For example, a common way to construct and use a PromptTemplate is as follows:\n",
    "\n",
    "\\`\\`\\`typescript\n",
    "import { PromptTemplate } from \"@langchain/core/prompts\";\n",
    "\n",
    "const promptTemplate = PromptTemplate.fromTemplate(\n",
    "  \"Tell me a joke about {topic}\"\n",
    ");\n",
    "\n",
    "await promptTemplate.invoke({ topic: \"cats\" });\n",
    "\\`\\`\\`\n",
    "\n",
    "#### ChatPromptTemplates\n",
    "\n",
    "These prompt templates are used to format an array of messages. These \"templates\" consist of an array of templates themselves.\n",
    "For example, a common way to construct and use a ChatPromptTemplate is as follows:\n",
    "\n",
    "\\`\\`\\`typescript\n",
    "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
    "\n",
    "const promptTemplate = ChatPromptTemplate.fromMessages([\n",
    "  [\"system\", \"You are a helpful assistant\"],\n",
    "  [\"user\", \"Tell me a joke about {topic}\"],\n",
    "]);\n",
    "\n",
    "await promptTemplate.invoke({ topic: \"cats\" });\n",
    "\\`\\`\\`\n",
    "\n",
    "In the above example, this ChatPromptTemplate will construct two messages when called.\n",
    "The first is a system message, that has no variables to format.\n",


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "1957f5cb",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "sidebar_label: Chroma\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef1f0986",
   "metadata": {},
   "source": [
    "# Chroma\n",
    "\n",
    "[Chroma](https://docs.trychroma.com/getting-started) is a AI-native open-source vector database focused on developer productivity and happiness. Chroma is licensed under Apache 2.0.\n",
    "\n",
    "This guide provides a quick overview for getting started with Chroma [`vector stores`](/docs/concepts/#vectorstores). For detailed documentation of all `Chroma` features and configurations head to the [API reference](https://api.js.langchain.com/classes/langchain_community_vectorstores_chroma.Chroma.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c824838d",
   "metadata": {},
   "source": [
    "## Overview\n",
    "\n",
    "### Integration details\n",
    "\n",
    "| Class | Package | [PY support](https://python.langchain.com/docs/integrations/vectorstores/chroma/) | Package latest |\n",
    "| :--- | :--- | :---: | :---: |\n",
    "| [`Chroma`](https://api.js.langchain.com/classes/langchain_community_vectorstores_chroma.Chroma.html) | [`@langchain/community`](https://www.npmjs.com/package/@langchain/community) | ✅ |  ![NPM - Version](https://img.shields.io/npm/v/@langchain/community?style=flat-square&label=%20&) |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36fdc060",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "To use Chroma vector stores, you'll need to install the `@langchain/community` integration package along with the [Chroma JS SDK](https://www.npmjs.com/package/chromadb) as a peer dependency.\n",
    "\n",
    "This guide will also use [OpenAI embeddings](/docs/integrations/text_embedding/openai), which require you to install the `@langchain/openai` integration package. You can also use [other supported embeddings models](/docs/integrations/text_embedding) if you wish.\n",
    "\n",
    "```{=mdx}\n",
    "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/community @langchain/openai @langchain/core chromadb\n",
    "</Npm2Yarn>\n",
    "```\n",
    "\n",
    "Next, follow the following instructions to run Chroma with Docker on your computer:\n",
    "\n",
    "```\n",
    "docker pull chromadb/chroma \n",
    "docker run -p 8000:8000 chromadb/chroma\n",
    "```\n",
    "\n",
    "You can see alternative setup instructions [in this guide](https://docs.trychroma.com/getting-started).\n",
    "\n",
    "### Credentials\n",
    "\n",
    "If you are running Chroma through Docker, you do not need to provide any credentials.\n",
    "\n",
    "If you are using OpenAI embeddings for this guide, you'll need to set your OpenAI key as well:\n",
    "\n",
    "```typescript\n",
    "process.env.OPENAI_API_KEY = \"YOUR_API_KEY\";\n",
    "```\n",
    "\n",
    "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n",
    "\n",
    "```typescript\n",
    "// process.env.LANGCHAIN_TRACING_V2=\"true\"\n",
    "// process.env.LANGCHAIN_API_KEY=\"your-api-key\"\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93df377e",
   "metadata": {},
   "source": [
    "## Instantiation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "dc37144c-208d-4ab3-9f3a-0407a69fe052",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import { Chroma } from \"@langchain/community/vectorstores/chroma\";\n",
    "import { OpenAIEmbeddings } from \"@langchain/openai\";\n",
    "\n",
    "const embeddings = new OpenAIEmbeddings({\n",
    "  model: \"text-embedding-3-small\",\n",
    "});\n",
    "\n",
    "const vectorStore = new Chroma(embeddings, {\n",
    "  collectionName: \"a-test-collection\",\n",
    "  url: \"http://localhost:8000\", // Optional, will default to this value\n",
    "  collectionMetadata: {\n",
    "    \"hnsw:space\": \"cosine\",\n",
    "  }, // Optional, can be used to specify the distance method of the embedding space https://docs.trychroma.com/usage-guide#changing-the-distance-function\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ac6071d4",
   "metadata": {},
   "source": [
    "## Manage vector store\n",
    "\n",
    "### Add items to vector store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "17f5efc0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ '1', '2', '3', '4' ]\n"
     ]
    }
   ],
   "source": [
    "import type { Document } from \"@langchain/core/documents\";\n",
    "\n",
    "const document1: Document = {\n",
    "  pageContent: \"The powerhouse of the cell is the mitochondria\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "};\n",
    "\n",
    "const document2: Document = {\n",
    "  pageContent: \"Buildings are made out of brick\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "};\n",
    "\n",
    "const document3: Document = {\n",
    "  pageContent: \"Mitochondria are made out of lipids\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "};\n",
    "\n",
    "const document4: Document = {\n",
    "  pageContent: \"The 2024 Olympics are in Paris\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "}\n",
    "\n",
    "const documents = [document1, document2, document3, document4];\n",
    "\n",
    "await vectorStore.addDocuments(documents, { ids: [\"1\", \"2\", \"3\", \"4\"] });"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcf1b905",
   "metadata": {},
   "source": [
    "### Delete items from vector store\n",
    "\n",
    "You can delete documents from Chroma by id as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ef61e188",
   "metadata": {},
   "outputs": [],
   "source": [
    "await vectorStore.delete({ ids: [\"4\"] });"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3620501",
   "metadata": {},
   "source": [
    "## Query vector store\n",
    "\n",
    "Once your vector store has been created and the relevant documents have been added you will most likely wish to query it during the running of your chain or agent. \n",
    "\n",
    "### Query directly\n",
    "\n",
    "Performing a simple similarity search can be done as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "aa0a16fa",
   "metadata": {},


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "1957f5cb",
   "metadata": {
    "vscode": {
     "languageId": "raw"
    }
   },
   "source": [
    "---\n",
    "sidebar_label: HNSWLib\n",
    "sidebar_class_name: node-only\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef1f0986",
   "metadata": {},
   "source": [
    "# HNSWLib\n",
    "\n",
    "```{=mdx}\n",
    ":::tip Compatibility\n",
    "Only available on Node.js.\n",
    ":::\n",
    "```\n",
    "\n",
    "HNSWLib is an in-memory vector store that can be saved to a file. It uses the [HNSWLib library](https://github.com/nmslib/hnswlib).\n",
    "\n",
    "This guide provides a quick overview for getting started with HNSWLib [vector stores](/docs/concepts/#vectorstores). For detailed documentation of all `HNSWLib` features and configurations head to the [API reference](https://api.js.langchain.com/classes/langchain_community_vectorstores_hnswlib.HNSWLib.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c824838d",
   "metadata": {},
   "source": [
    "## Overview\n",
    "\n",
    "### Integration details\n",
    "\n",
    "| Class | Package | PY support |  Package latest |\n",
    "| :--- | :--- | :---: | :---: |\n",
    "| [`HNSWLib`](https://api.js.langchain.com/classes/langchain_community_vectorstores_hnswlib.HNSWLib.html) | [`@langchain/community`](https://npmjs.com/@langchain/community) | ❌ |  ![NPM - Version](https://img.shields.io/npm/v/@langchain/community?style=flat-square&label=%20&) |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36fdc060",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "To use HNSWLib vector stores, you'll need to install the `@langchain/community` integration package with the [`hnswlib-node`](https://www.npmjs.com/package/hnswlib-node) package as a peer dependency.\n",
    "\n",
    "This guide will also use [OpenAI embeddings](/docs/integrations/text_embedding/openai), which require you to install the `@langchain/openai` integration package. You can also use [other supported embeddings models](/docs/integrations/text_embedding) if you wish.\n",
    "\n",
    "```{=mdx}\n",
    "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/community hnswlib-node @langchain/openai @langchain/core\n",
    "</Npm2Yarn>\n",
    "```\n",
    "\n",
    "```{=mdx}\n",
    ":::caution\n",
    "\n",
    "**On Windows**, you might need to install [Visual Studio](https://visualstudio.microsoft.com/downloads/) first in order to properly build the `hnswlib-node` package.\n",
    "\n",
    ":::\n",
    "```\n",
    "\n",
    "### Credentials\n",
    "\n",
    "Because HNSWLib runs locally, you do not need any credentials to use it.\n",
    "\n",
    "If you are using OpenAI embeddings for this guide, you'll need to set your OpenAI key as well:\n",
    "\n",
    "```typescript\n",
    "process.env.OPENAI_API_KEY = \"YOUR_API_KEY\";\n",
    "```\n",
    "\n",
    "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n",
    "\n",
    "```typescript\n",
    "// process.env.LANGCHAIN_TRACING_V2=\"true\"\n",
    "// process.env.LANGCHAIN_API_KEY=\"your-api-key\"\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93df377e",
   "metadata": {},
   "source": [
    "## Instantiation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "dc37144c-208d-4ab3-9f3a-0407a69fe052",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import { HNSWLib } from \"@langchain/community/vectorstores/hnswlib\";\n",
    "import { OpenAIEmbeddings } from \"@langchain/openai\";\n",
    "\n",
    "const embeddings = new OpenAIEmbeddings({\n",
    "  model: \"text-embedding-3-small\",\n",
    "});\n",
    "\n",
    "const vectorStore = await HNSWLib.fromDocuments([], embeddings);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ac6071d4",
   "metadata": {},
   "source": [
    "## Manage vector store\n",
    "\n",
    "### Add items to vector store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "17f5efc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import type { Document } from \"@langchain/core/documents\";\n",
    "\n",
    "const document1: Document = {\n",
    "  pageContent: \"The powerhouse of the cell is the mitochondria\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "};\n",
    "\n",
    "const document2: Document = {\n",
    "  pageContent: \"Buildings are made out of brick\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "};\n",
    "\n",
    "const document3: Document = {\n",
    "  pageContent: \"Mitochondria are made out of lipids\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "};\n",
    "\n",
    "const document4: Document = {\n",
    "  pageContent: \"The 2024 Olympics are in Paris\",\n",
    "  metadata: { source: \"https://example.com\" }\n",
    "}\n",
    "\n",
    "const documents = [document1, document2, document3, document4];\n",
    "\n",
    "await vectorStore.addDocuments(documents);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3620501",
   "metadata": {},
   "source": [
    "Deletion and ids for individual documents are not currently supported.\n",
    "\n",
    "## Query vector store\n",
    "\n",
    "Once your vector store has been created and the relevant documents have been added you will most likely wish to query it during the running of your chain or agent. \n",
    "\n",
    "### Query directly\n",
    "\n",
    "Performing a simple similarity search can be done as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "aa0a16fa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* The powerhouse of the cell is the mitochondria [{\"source\":\"https://example.com\"}]\n",
      "* Mitochondria are made out of lipids [{\"source\":\"https://example.com\"}]\n"
     ]
    }
   ],
   "source": [
    "const filter = (doc) => doc.metadata.source === \"https://example.com\";\n",
    "\n",
    "const similaritySearchResults = await vectorStore.similaritySearch(\"biology\", 2, filter);\n",
    "\n",
    "for (const doc of similaritySearchResults) {\n",
    "  console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ed9d733",
   "metadata": {},
   "source": [