!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}(),document.documentElement.setAttribute("data-announcement-bar-initially-dismissed",function(){try{return"true"===localStorage.getItem("docusaurus.announcement.dismiss")}catch(t){}return!1}())

[Skip to main content](#__docusaurus_skipToContent_fallback)

You are viewing the **preview** v0.2 docs. View the **stable** v0.1 docs [here](/v0.1/docs/get_started/introduction/). Leave feedback on the v0.2 docs [here](https://github.com/langchain-ai/langchainjs/discussions/5386).

[

![🦜️🔗 Langchain](/v0.2/img/brand/wordmark.png)![🦜️🔗 Langchain](/v0.2/img/brand/wordmark-dark.png)

](/v0.2/)[Integrations](/v0.2/docs/integrations/platforms/)[API Reference](https://v02.api.js.langchain.com)

[More](#)

*   [People](/v0.2/docs/people/)
*   [Community](/v0.2/docs/community)
*   [Tutorials](/v0.2/docs/additional_resources/tutorials)
*   [Contributing](/v0.2/docs/contributing)

[v0.2](#)

*   [v0.2](/v0.2/docs/introduction)
*   [v0.1](https://js.langchain.com/v0.1/docs/get_started/introduction)

[🦜🔗](#)

*   [LangSmith](https://smith.langchain.com)
*   [LangSmith Docs](https://docs.smith.langchain.com)
*   [LangChain Hub](https://smith.langchain.com/hub)
*   [LangServe](https://github.com/langchain-ai/langserve)
*   [Python Docs](https://python.langchain.com/)

[Chat](https://chatjs.langchain.com)[](https://github.com/langchain-ai/langchainjs)

Search

*   [Introduction](/v0.2/docs/introduction)
*   [Tutorials](/v0.2/docs/tutorials/)
    
    *   [Build a Question Answering application over a Graph Database](/v0.2/docs/tutorials/graph)
    *   [Tutorials](/v0.2/docs/tutorials/)
    *   [Build a Simple LLM Application](/v0.2/docs/tutorials/llm_chain)
    *   [Build a Query Analysis System](/v0.2/docs/tutorials/query_analysis)
    *   [Build a Chatbot](/v0.2/docs/tutorials/chatbot)
    *   [Build an Agent](/v0.2/docs/tutorials/agents)
    *   [Build an Extraction Chain](/v0.2/docs/tutorials/extraction)
    *   [Summarize Text](/v0.2/docs/tutorials/summarization)
    *   [Tagging](/v0.2/docs/tutorials/classification)
    *   [Build a Local RAG Application](/v0.2/docs/tutorials/local_rag)
    *   [Conversational RAG](/v0.2/docs/tutorials/qa_chat_history)
    *   [Build a Retrieval Augmented Generation (RAG) App](/v0.2/docs/tutorials/rag)
    *   [Build a Question/Answering system over SQL data](/v0.2/docs/tutorials/sql_qa)
*   [How-to guides](/v0.2/docs/how_to/)
    
    *   [How-to guides](/v0.2/docs/how_to/)
    *   [How to use example selectors](/v0.2/docs/how_to/example_selectors)
    *   [Installation](/v0.2/docs/how_to/installation)
    *   [How to stream responses from an LLM](/v0.2/docs/how_to/streaming_llm)
    *   [How to stream chat model responses](/v0.2/docs/how_to/chat_streaming)
    *   [How to embed text data](/v0.2/docs/how_to/embed_text)
    *   [How to use few shot examples in chat models](/v0.2/docs/how_to/few_shot_examples_chat)
    *   [How to cache model responses](/v0.2/docs/how_to/llm_caching)
    *   [How to cache chat model responses](/v0.2/docs/how_to/chat_model_caching)
    *   [How to create a custom LLM class](/v0.2/docs/how_to/custom_llm)
    *   [How to use few shot examples](/v0.2/docs/how_to/few_shot_examples)
    *   [How to use output parsers to parse an LLM response into structured format](/v0.2/docs/how_to/output_parser_structured)
    *   [How to return structured data from a model](/v0.2/docs/how_to/structured_output)
    *   [How to add ad-hoc tool calling capability to LLMs and Chat Models](/v0.2/docs/how_to/tools_prompting)
    *   [How to create a custom chat model class](/v0.2/docs/how_to/custom_chat)
    *   [How to do per-user retrieval](/v0.2/docs/how_to/qa_per_user)
    *   [How to track token usage](/v0.2/docs/how_to/chat_token_usage_tracking)
    *   [How to track token usage](/v0.2/docs/how_to/llm_token_usage_tracking)
    *   [How to pass through arguments from one step to the next](/v0.2/docs/how_to/passthrough)
    *   [How to compose prompts together](/v0.2/docs/how_to/prompts_composition)
    *   [How to use legacy LangChain Agents (AgentExecutor)](/v0.2/docs/how_to/agent_executor)
    *   [How to add values to a chain's state](/v0.2/docs/how_to/assign)
    *   [How to attach runtime arguments to a Runnable](/v0.2/docs/how_to/binding)
    *   [How to cache embedding results](/v0.2/docs/how_to/caching_embeddings)
    *   [How to split by character](/v0.2/docs/how_to/character_text_splitter)
    *   [How to manage memory](/v0.2/docs/how_to/chatbots_memory)
    *   [How to do retrieval](/v0.2/docs/how_to/chatbots_retrieval)
    *   [How to use tools](/v0.2/docs/how_to/chatbots_tools)
    *   [How to split code](/v0.2/docs/how_to/code_splitter)
    *   [How to do retrieval with contextual compression](/v0.2/docs/how_to/contextual_compression)
    *   [How to write a custom retriever class](/v0.2/docs/how_to/custom_retriever)
    *   [How to create custom Tools](/v0.2/docs/how_to/custom_tools)
    *   [How to debug your LLM apps](/v0.2/docs/how_to/debugging)
    *   [How to load CSV data](/v0.2/docs/how_to/document_loader_csv)
    *   [How to write a custom document loader](/v0.2/docs/how_to/document_loader_custom)
    *   [How to load data from a directory](/v0.2/docs/how_to/document_loader_directory)
    *   [How to load PDF files](/v0.2/docs/how_to/document_loader_pdf)
    *   [How to load JSON data](/v0.2/docs/how_to/document_loaders_json)
    *   [How to select examples by length](/v0.2/docs/how_to/example_selectors_length_based)
    *   [How to select examples by similarity](/v0.2/docs/how_to/example_selectors_similarity)
    *   [How to use reference examples](/v0.2/docs/how_to/extraction_examples)
    *   [How to handle long text](/v0.2/docs/how_to/extraction_long_text)
    *   [How to do extraction without using function calling](/v0.2/docs/how_to/extraction_parse)
    *   [Fallbacks](/v0.2/docs/how_to/fallbacks)
    *   [Few Shot Prompt Templates](/v0.2/docs/how_to/few_shot)
    *   [How to run custom functions](/v0.2/docs/how_to/functions)
    *   [How to construct knowledge graphs](/v0.2/docs/how_to/graph_constructing)
    *   [How to map values to a database](/v0.2/docs/how_to/graph_mapping)
    *   [How to improve results with prompting](/v0.2/docs/how_to/graph_prompting)
    *   [How to add a semantic layer over the database](/v0.2/docs/how_to/graph_semantic)
    *   [How to reindex data to keep your vectorstore in-sync with the underlying data source](/v0.2/docs/how_to/indexing)
    *   [How to get log probabilities](/v0.2/docs/how_to/logprobs)
    *   [How to add message history](/v0.2/docs/how_to/message_history)
    *   [How to generate multiple embeddings per document](/v0.2/docs/how_to/multi_vector)
    *   [How to generate multiple queries to retrieve data for](/v0.2/docs/how_to/multiple_queries)
    *   [How to parse JSON output](/v0.2/docs/how_to/output_parser_json)
    *   [How to retry when output parsing errors occur](/v0.2/docs/how_to/output_parser_retry)
    *   [How to parse XML output](/v0.2/docs/how_to/output_parser_xml)
    *   [How to invoke runnables in parallel](/v0.2/docs/how_to/parallel)
    *   [How to retrieve the whole document for a chunk](/v0.2/docs/how_to/parent_document_retriever)
    *   [How to partially format prompt templates](/v0.2/docs/how_to/prompts_partial)
    *   [How to add chat history to a question-answering chain](/v0.2/docs/how_to/qa_chat_history_how_to)
    *   [How to return citations](/v0.2/docs/how_to/qa_citations)
    *   [How to return sources](/v0.2/docs/how_to/qa_sources)
    *   [How to stream from a question-answering chain](/v0.2/docs/how_to/qa_streaming)
    *   [How to construct filters](/v0.2/docs/how_to/query_constructing_filters)
    *   [How to add examples to the prompt](/v0.2/docs/how_to/query_few_shot)
    *   [How to deal with high cardinality categorical variables](/v0.2/docs/how_to/query_high_cardinality)
    *   [How to handle multiple queries](/v0.2/docs/how_to/query_multiple_queries)
    *   [How to handle multiple retrievers](/v0.2/docs/how_to/query_multiple_retrievers)
    *   [How to handle cases where no queries are generated](/v0.2/docs/how_to/query_no_queries)
    *   [How to recursively split text by characters](/v0.2/docs/how_to/recursive_text_splitter)
    *   [How to reduce retrieval latency](/v0.2/docs/how_to/reduce_retrieval_latency)
    *   [How to route execution within a chain](/v0.2/docs/how_to/routing)
    *   [How to chain runnables](/v0.2/docs/how_to/sequence)
    *   [How to split text by tokens](/v0.2/docs/how_to/split_by_token)
    *   [How to deal with large databases](/v0.2/docs/how_to/sql_large_db)
    *   [How to use prompting to improve results](/v0.2/docs/how_to/sql_prompting)
    *   [How to do query validation](/v0.2/docs/how_to/sql_query_checking)
    *   [How to stream](/v0.2/docs/how_to/streaming)
    *   [How to create a time-weighted retriever](/v0.2/docs/how_to/time_weighted_vectorstore)
    *   [How to use a chat model to call tools](/v0.2/docs/how_to/tool_calling)
    *   [How to call tools with multi-modal data](/v0.2/docs/how_to/tool_calls_multi_modal)
    *   [How to use LangChain tools](/v0.2/docs/how_to/tools_builtin)
    *   [How use a vector store to retrieve data](/v0.2/docs/how_to/vectorstore_retriever)
    *   [How to create and query vector stores](/v0.2/docs/how_to/vectorstores)
*   [Conceptual guide](/v0.2/docs/concepts)
*   Ecosystem
    
    *   [🦜🛠️ LangSmith](/v0.2/docs/langsmith/)
        
    *   [🦜🕸️LangGraph.js](/v0.2/docs/langgraph)
*   Versions
    
    *   [Overview](/v0.2/docs/versions/overview)
    *   [v0.2](/v0.2/docs/versions/v0_2)
    *   [Release Policy](/v0.2/docs/versions/release_policy)
    *   [Packages](/v0.2/docs/versions/packages)
*   [Security](/v0.2/docs/security)

*   [](/v0.2/)
*   [How-to guides](/v0.2/docs/how_to/)
*   How to stream from a question-answering chain

On this page

How to stream from a question-answering chain
=============================================

Prerequisites

This guide assumes familiarity with the following:

*   [Retrieval-augmented generation](/v0.2/docs/tutorials/rag/)

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.

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.

Setup[​](#setup "Direct link to Setup")
---------------------------------------

### Dependencies[​](#dependencies "Direct link to Dependencies")

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](/v0.2/docs/concepts/#chat-models) or [LLM](/v0.2/docs/concepts#llms), [Embeddings](/v0.2/docs/concepts#embedding-models), and [VectorStore](/v0.2/docs/concepts#vectorstores) or [Retriever](/v0.2/docs/concepts#retrievers).

We’ll use the following packages:

    npm install --save langchain @langchain/openai cheerio

We need to set environment variable `OPENAI_API_KEY`:

    export OPENAI_API_KEY=YOUR_KEY

### LangSmith[​](#langsmith "Direct link to LangSmith")

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/).

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:

    export LANGCHAIN_TRACING_V2=trueexport LANGCHAIN_API_KEY=YOUR_KEY

Chain with sources[​](#chain-with-sources "Direct link to Chain with sources")
------------------------------------------------------------------------------

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](/v0.2/docs/how_to/qa_sources/) guide:

    import "cheerio";import { CheerioWebBaseLoader } from "langchain/document_loaders/web/cheerio";import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";import { MemoryVectorStore } from "langchain/vectorstores/memory";import { OpenAIEmbeddings, ChatOpenAI } from "@langchain/openai";import { pull } from "langchain/hub";import { ChatPromptTemplate } from "@langchain/core/prompts";import { formatDocumentsAsString } from "langchain/util/document";import {  RunnableSequence,  RunnablePassthrough,  RunnableMap,} from "@langchain/core/runnables";import { StringOutputParser } from "@langchain/core/output_parsers";const loader = new CheerioWebBaseLoader(  "https://lilianweng.github.io/posts/2023-06-23-agent/");const docs = await loader.load();const textSplitter = new RecursiveCharacterTextSplitter({  chunkSize: 1000,  chunkOverlap: 200,});const splits = await textSplitter.splitDocuments(docs);const vectorStore = await MemoryVectorStore.fromDocuments(  splits,  new OpenAIEmbeddings());// Retrieve and generate using the relevant snippets of the blog.const retriever = vectorStore.asRetriever();const prompt = await pull<ChatPromptTemplate>("rlm/rag-prompt");const llm = new ChatOpenAI({ model: "gpt-3.5-turbo", temperature: 0 });const ragChainFromDocs = RunnableSequence.from([  RunnablePassthrough.assign({    context: (input) => formatDocumentsAsString(input.context),  }),  prompt,  llm,  new StringOutputParser(),]);let ragChainWithSource = new RunnableMap({  steps: { context: retriever, question: new RunnablePassthrough() },});ragChainWithSource = ragChainWithSource.assign({ answer: ragChainFromDocs });await ragChainWithSource.invoke("What is Task Decomposition");

    {  question: "What is Task Decomposition",  context: [    Document {      pageContent: "Fig. 1. Overview of a LLM-powered autonomous agent system.\n" +        "Component One: Planning#\n" +        "A complicated ta"... 898 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    },    Document {      pageContent: 'Task decomposition can be done (1) by LLM with simple prompting like "Steps for XYZ.\\n1.", "What are'... 887 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    },    Document {      pageContent: "Agent System Overview\n" +        "                \n" +        "                    Component One: Planning\n" +        "                 "... 850 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    },    Document {      pageContent: "Resources:\n" +        "1. Internet access for searches and information gathering.\n" +        "2. Long Term memory management"... 456 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    }  ],  answer: "Task decomposition is a technique used to break down complex tasks into smaller and simpler steps fo"... 230 more characters}

Let’s see what this prompt actually looks like. You can also view it [in the LangChain prompt hub](https://smith.langchain.com/hub/rlm/rag-prompt):

    console.log(prompt.promptMessages.map((msg) => msg.prompt.template).join("\n"));

    You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.Question: {question}Context: {context}Answer:

Streaming final outputs[​](#streaming-final-outputs "Direct link to Streaming final outputs")
---------------------------------------------------------------------------------------------

With [LCEL](/v0.2/docs/concepts#langchain-expression-language), we can stream outputs as they are generated:

    for await (const chunk of await ragChainWithSource.stream(  "What is task decomposition?")) {  console.log(chunk);}

    { question: "What is task decomposition?" }{  context: [    Document {      pageContent: "Fig. 1. Overview of a LLM-powered autonomous agent system.\n" +        "Component One: Planning#\n" +        "A complicated ta"... 898 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    },    Document {      pageContent: 'Task decomposition can be done (1) by LLM with simple prompting like "Steps for XYZ.\\n1.", "What are'... 887 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    },    Document {      pageContent: "Agent System Overview\n" +        "                \n" +        "                    Component One: Planning\n" +        "                 "... 850 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    },    Document {      pageContent: "(3) Task execution: Expert models execute on the specific tasks and log results.\n" +        "Instruction:\n" +        "\n" +        "With "... 539 more characters,      metadata: {        source: "https://lilianweng.github.io/posts/2023-06-23-agent/",        loc: { lines: [Object] }      }    }  ]}{ answer: "" }{ answer: "Task" }{ answer: " decomposition" }{ answer: " is" }{ answer: " a" }{ answer: " technique" }{ answer: " used" }{ answer: " to" }{ answer: " break" }{ answer: " down" }{ answer: " complex" }{ answer: " tasks" }{ answer: " into" }{ answer: " smaller" }{ answer: " and" }{ answer: " simpler" }{ answer: " steps" }{ answer: "." }{ answer: " It" }{ answer: " can" }{ answer: " be" }{ answer: " done" }{ answer: " through" }{ answer: " various" }{ answer: " methods" }{ answer: " such" }{ answer: " as" }{ answer: " using" }{ answer: " prompting" }{ answer: " techniques" }{ answer: "," }{ answer: " task" }{ answer: "-specific" }{ answer: " instructions" }{ answer: "," }{ answer: " or" }{ answer: " human" }{ answer: " inputs" }{ answer: "." }{ answer: " Another" }{ answer: " approach" }{ answer: " involves" }{ answer: " outsourcing" }{ answer: " the" }{ answer: " planning" }{ answer: " step" }{ answer: " to" }{ answer: " an" }{ answer: " external" }{ answer: " classical" }{ answer: " planner" }{ answer: "." }{ answer: "" }

We can add some logic to compile our stream as it’s being returned:

    const output = {};let currentKey: string | null = null;for await (const chunk of await ragChainWithSource.stream(  "What is task decomposition?")) {  for (const key of Object.keys(chunk)) {    if (output[key] === undefined) {      output[key] = chunk[key];    } else {      output[key] += chunk[key];    }    if (key !== currentKey) {      console.log(`\n\n${key}: ${JSON.stringify(chunk[key])}`);    } else {      console.log(chunk[key]);    }    currentKey = key;  }}

    question: "What is task decomposition?"context: [{"pageContent":"Fig. 1. Overview of a LLM-powered autonomous agent system.\nComponent One: Planning#\nA complicated task usually involves many steps. An agent needs to know what they are and plan ahead.\nTask Decomposition#\nChain of thought (CoT; Wei et al. 2022) has become a standard prompting technique for enhancing model performance on complex tasks. The model is instructed to “think step by step” to utilize more test-time computation to decompose hard tasks into smaller and simpler steps. CoT transforms big tasks into multiple manageable tasks and shed lights into an interpretation of the model’s thinking process.\nTree of Thoughts (Yao et al. 2023) extends CoT by exploring multiple reasoning possibilities at each step. It first decomposes the problem into multiple thought steps and generates multiple thoughts per step, creating a tree structure. The search process can be BFS (breadth-first search) or DFS (depth-first search) with each state evaluated by a classifier (via a prompt) or majority vote.","metadata":{"source":"https://lilianweng.github.io/posts/2023-06-23-agent/","loc":{"lines":{"from":176,"to":181}}}},{"pageContent":"Task decomposition can be done (1) by LLM with simple prompting like \"Steps for XYZ.\\n1.\", \"What are the subgoals for achieving XYZ?\", (2) by using task-specific instructions; e.g. \"Write a story outline.\" for writing a novel, or (3) with human inputs.\nAnother quite distinct approach, LLM+P (Liu et al. 2023), involves relying on an external classical planner to do long-horizon planning. This approach utilizes the Planning Domain Definition Language (PDDL) as an intermediate interface to describe the planning problem. In this process, LLM (1) translates the problem into “Problem PDDL”, then (2) requests a classical planner to generate a PDDL plan based on an existing “Domain PDDL”, and finally (3) translates the PDDL plan back into natural language. Essentially, the planning step is outsourced to an external tool, assuming the availability of domain-specific PDDL and a suitable planner which is common in certain robotic setups but not in many other domains.\nSelf-Reflection#","metadata":{"source":"https://lilianweng.github.io/posts/2023-06-23-agent/","loc":{"lines":{"from":182,"to":184}}}},{"pageContent":"Agent System Overview\n                \n                    Component One: Planning\n                        \n                \n                    Task Decomposition\n                \n                    Self-Reflection\n                \n                \n                    Component Two: Memory\n                        \n                \n                    Types of Memory\n                \n                    Maximum Inner Product Search (MIPS)\n                \n                \n                    Component Three: Tool Use\n                \n                    Case Studies\n                        \n                \n                    Scientific Discovery Agent\n                \n                    Generative Agents Simulation\n                \n                    Proof-of-Concept Examples\n                \n                \n                    Challenges\n                \n                    Citation\n                \n                    References","metadata":{"source":"https://lilianweng.github.io/posts/2023-06-23-agent/","loc":{"lines":{"from":112,"to":146}}}},{"pageContent":"(3) Task execution: Expert models execute on the specific tasks and log results.\nInstruction:\n\nWith the input and the inference results, the AI assistant needs to describe the process and results. The previous stages can be formed as - User Input: {{ User Input }}, Task Planning: {{ Tasks }}, Model Selection: {{ Model Assignment }}, Task Execution: {{ Predictions }}. You must first answer the user's request in a straightforward manner. Then describe the task process and show your analysis and model inference results to the user in the first person. If inference results contain a file path, must tell the user the complete file path.","metadata":{"source":"https://lilianweng.github.io/posts/2023-06-23-agent/","loc":{"lines":{"from":277,"to":280}}}}]answer: ""Task decomposition is a technique used to break down complex tasks into smaller and simpler steps. It can be done through various methods such as using prompting techniques, task-specific instructions, or human inputs. Another approach involves outsourcing the planning step to an external classical planner.

    "answer"

Next steps[​](#next-steps "Direct link to Next steps")
------------------------------------------------------

You’ve now learned how to stream responses from a QA chain.

Next, check out some of the other how-to guides around RAG, such as [how to add chat history](/v0.2/docs/how_to/qa_chat_history_how_to).

* * *

#### Was this page helpful?

  

#### You can leave detailed feedback [on GitHub](https://github.com/langchain-ai/langchainjs/issues/new?assignees=&labels=03+-+Documentation&projects=&template=documentation.yml&title=DOC%3A+%3CPlease+write+a+comprehensive+title+after+the+%27DOC%3A+%27+prefix%3E).

[

Previous

How to return sources

](/v0.2/docs/how_to/qa_sources)[

Next

How to construct filters

](/v0.2/docs/how_to/query_constructing_filters)

*   [Setup](#setup)
    *   [Dependencies](#dependencies)
    *   [LangSmith](#langsmith)
*   [Chain with sources](#chain-with-sources)
*   [Streaming final outputs](#streaming-final-outputs)
*   [Next steps](#next-steps)

Community

*   [Discord](https://discord.gg/cU2adEyC7w)
*   [Twitter](https://twitter.com/LangChainAI)

GitHub

*   [Python](https://github.com/langchain-ai/langchain)
*   [JS/TS](https://github.com/langchain-ai/langchainjs)

More

*   [Homepage](https://langchain.com)
*   [Blog](https://blog.langchain.dev)

Copyright © 2024 LangChain, Inc.