!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)

LangChain v0.2 is coming soon! Preview the new docs [here](/v0.2/docs/introduction/).

[

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

](/v0.1/)[Docs](/v0.1/docs/get_started/introduction/)[Use cases](/v0.1/docs/use_cases/)[Integrations](/v0.1/docs/integrations/platforms/)[API Reference](https://api.js.langchain.com)

[More](#)

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

[v0.1](#)

*   [v0.2](https://js.langchain.com/v0.2/docs/introduction)
*   [v0.1](/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

*   [Get started](/v0.1/docs/get_started/)
    
    *   [Introduction](/v0.1/docs/get_started/introduction/)
    *   [Installation](/v0.1/docs/get_started/installation/)
    *   [Quickstart](/v0.1/docs/get_started/quickstart/)
*   [LangChain Expression Language](/v0.1/docs/expression_language/)
    
    *   [Get started](/v0.1/docs/expression_language/get_started/)
    *   [Why use LCEL?](/v0.1/docs/expression_language/why/)
    *   [Interface](/v0.1/docs/expression_language/interface/)
    *   [Streaming](/v0.1/docs/expression_language/streaming/)
    *   [How to](/v0.1/docs/expression_language/how_to/routing/)
        
    *   [Cookbook](/v0.1/docs/expression_language/cookbook/)
        
    *   [LangChain Expression Language (LCEL)](/v0.1/docs/expression_language/)
*   [Modules](/v0.1/docs/modules/)
    
    *   [Model I/O](/v0.1/docs/modules/model_io/)
        
    *   [Retrieval](/v0.1/docs/modules/data_connection/)
        
    *   [Chains](/v0.1/docs/modules/chains/)
    *   [Agents](/v0.1/docs/modules/agents/)
        
    *   [More](/v0.1/docs/modules/memory/)
        
*   [Security](/v0.1/docs/security/)
*   [Guides](/v0.1/docs/guides/)
    
*   [Ecosystem](/v0.1/docs/ecosystem/)
    
*   [LangGraph](/v0.1/docs/langgraph/)
*   * * *
    

*   [](/v0.1/)
*   [LangChain Expression Language](/v0.1/docs/expression_language/)
*   Get started

On this page

Get started
===========

LCEL makes it easy to build complex chains from basic components, and supports out of the box functionality such as streaming, parallelism, and logging.

Basic example: prompt + model + output parser[​](#basic-example-prompt--model--output-parser "Direct link to Basic example: prompt + model + output parser")
------------------------------------------------------------------------------------------------------------------------------------------------------------

The most basic and common use case is chaining a prompt template and a model together. To see how this works, let's create a chain that takes a topic and generates a joke:

tip

See [this section for general instructions on installing integration packages](/v0.1/docs/get_started/installation/#installing-integration-packages).

*   npm
*   Yarn
*   pnpm

    npm install @langchain/openai @langchain/community

    yarn add @langchain/openai @langchain/community

    pnpm add @langchain/openai @langchain/community

tip

We're unifying model params across all packages. We now suggest using `model` instead of `modelName`, and `apiKey` for API keys.

    import { ChatOpenAI } from "@langchain/openai";import { ChatPromptTemplate } from "@langchain/core/prompts";import { StringOutputParser } from "@langchain/core/output_parsers";const prompt = ChatPromptTemplate.fromMessages([  ["human", "Tell me a short joke about {topic}"],]);const model = new ChatOpenAI({});const outputParser = new StringOutputParser();const chain = prompt.pipe(model).pipe(outputParser);const response = await chain.invoke({  topic: "ice cream",});console.log(response);/**Why did the ice cream go to the gym?Because it wanted to get a little "cone"ditioning! */

#### API Reference:

*   [ChatOpenAI](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html) from `@langchain/openai`
*   [ChatPromptTemplate](https://api.js.langchain.com/classes/langchain_core_prompts.ChatPromptTemplate.html) from `@langchain/core/prompts`
*   [StringOutputParser](https://api.js.langchain.com/classes/langchain_core_output_parsers.StringOutputParser.html) from `@langchain/core/output_parsers`

tip

[LangSmith trace](https://smith.langchain.com/public/dcac6d79-5254-4889-a974-4b3abaf605b4/r)

Notice in this line we're chaining our prompt, LLM model and output parser together:

    const chain = prompt.pipe(model).pipe(outputParser);

The `.pipe()` method allows for chaining together any number of runnables. It will pass the output of one through to the input of the next.

Here, the prompt is passed a `topic` and when invoked it returns a formatted string with the `{topic}` input variable replaced with the string we passed to the invoke call. That string is then passed as the input to the LLM which returns a `BaseMessage` object. Finally, the output parser takes that `BaseMessage` object and returns the content of that object as a string.

### 1\. Prompt[​](#1-prompt "Direct link to 1. Prompt")

`prompt` is a `BasePromptTemplate`, which means it takes in an object of template variables and produces a `PromptValue`. A `PromptValue` is a wrapper around a completed prompt that can be passed to either an `LLM` (which takes a string as input) or `ChatModel` (which takes a sequence of messages as input). It can work with either language model type because it defines logic both for producing BaseMessages and for producing a string.

    import { ChatPromptTemplate } from "@langchain/core/prompts";const prompt = ChatPromptTemplate.fromMessages([  ["human", "Tell me a short joke about {topic}"],]);const promptValue = await prompt.invoke({ topic: "ice cream" });console.log(promptValue);/**ChatPromptValue {  messages: [    HumanMessage {      content: 'Tell me a short joke about ice cream',      name: undefined,      additional_kwargs: {}    }  ]} */const promptAsMessages = promptValue.toChatMessages();console.log(promptAsMessages);/**[  HumanMessage {    content: 'Tell me a short joke about ice cream',    name: undefined,    additional_kwargs: {}  }] */const promptAsString = promptValue.toString();console.log(promptAsString);/**Human: Tell me a short joke about ice cream */

#### API Reference:

*   [ChatPromptTemplate](https://api.js.langchain.com/classes/langchain_core_prompts.ChatPromptTemplate.html) from `@langchain/core/prompts`

### 2\. Model[​](#2-model "Direct link to 2. Model")

The `PromptValue` is then passed to `model`. In this case our `model` is a `ChatModel`, meaning it will output a `BaseMessage`.

    import { ChatOpenAI } from "@langchain/openai";const model = new ChatOpenAI({});const promptAsString = "Human: Tell me a short joke about ice cream";const response = await model.invoke(promptAsString);console.log(response);/**AIMessage {  content: 'Sure, here you go: Why did the ice cream go to school? Because it wanted to get a little "sundae" education!',  name: undefined,  additional_kwargs: { function_call: undefined, tool_calls: undefined }} */

#### API Reference:

*   [ChatOpenAI](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html) from `@langchain/openai`

If our model was an LLM, it would output a string.

    import { OpenAI } from "@langchain/openai";const model = new OpenAI({});const promptAsString = "Human: Tell me a short joke about ice cream";const response = await model.invoke(promptAsString);console.log(response);/**Why did the ice cream go to therapy?Because it was feeling a little rocky road. */

#### API Reference:

*   [OpenAI](https://api.js.langchain.com/classes/langchain_openai.OpenAI.html) from `@langchain/openai`

### 3\. Output parser[​](#3-output-parser "Direct link to 3. Output parser")

And lastly we pass our `model` output to the `outputParser`, which is a `BaseOutputParser` meaning it takes either a string or a `BaseMessage` as input. The `StringOutputParser` specifically simple converts any input into a string.

    import { AIMessage } from "@langchain/core/messages";import { StringOutputParser } from "@langchain/core/output_parsers";const outputParser = new StringOutputParser();const message = new AIMessage(  'Sure, here you go: Why did the ice cream go to school? Because it wanted to get a little "sundae" education!');const parsed = await outputParser.invoke(message);console.log(parsed);/**Sure, here you go: Why did the ice cream go to school? Because it wanted to get a little "sundae" education! */

#### API Reference:

*   [AIMessage](https://api.js.langchain.com/classes/langchain_core_messages.AIMessage.html) from `@langchain/core/messages`
*   [StringOutputParser](https://api.js.langchain.com/classes/langchain_core_output_parsers.StringOutputParser.html) from `@langchain/core/output_parsers`

RAG Search Example[​](#rag-search-example "Direct link to RAG Search Example")
------------------------------------------------------------------------------

For our next example, we want to run a retrieval-augmented generation chain to add some context when responding to questions.

    import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";import { HNSWLib } from "@langchain/community/vectorstores/hnswlib";import { Document } from "@langchain/core/documents";import { ChatPromptTemplate } from "@langchain/core/prompts";import {  RunnableLambda,  RunnableMap,  RunnablePassthrough,} from "@langchain/core/runnables";import { StringOutputParser } from "@langchain/core/output_parsers";const vectorStore = await HNSWLib.fromDocuments(  [    new Document({ pageContent: "Harrison worked at Kensho" }),    new Document({ pageContent: "Bears like to eat honey." }),  ],  new OpenAIEmbeddings());const retriever = vectorStore.asRetriever(1);const prompt = ChatPromptTemplate.fromMessages([  [    "ai",    `Answer the question based on only the following context:  {context}`,  ],  ["human", "{question}"],]);const model = new ChatOpenAI({});const outputParser = new StringOutputParser();const setupAndRetrieval = RunnableMap.from({  context: new RunnableLambda({    func: (input: string) =>      retriever.invoke(input).then((response) => response[0].pageContent),  }).withConfig({ runName: "contextRetriever" }),  question: new RunnablePassthrough(),});const chain = setupAndRetrieval.pipe(prompt).pipe(model).pipe(outputParser);const response = await chain.invoke("Where did Harrison work?");console.log(response);/**Harrison worked at Kensho. */

#### API Reference:

*   [ChatOpenAI](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html) from `@langchain/openai`
*   [OpenAIEmbeddings](https://api.js.langchain.com/classes/langchain_openai.OpenAIEmbeddings.html) from `@langchain/openai`
*   [HNSWLib](https://api.js.langchain.com/classes/langchain_community_vectorstores_hnswlib.HNSWLib.html) from `@langchain/community/vectorstores/hnswlib`
*   [Document](https://api.js.langchain.com/classes/langchain_core_documents.Document.html) from `@langchain/core/documents`
*   [ChatPromptTemplate](https://api.js.langchain.com/classes/langchain_core_prompts.ChatPromptTemplate.html) from `@langchain/core/prompts`
*   [RunnableLambda](https://api.js.langchain.com/classes/langchain_core_runnables.RunnableLambda.html) from `@langchain/core/runnables`
*   [RunnableMap](https://api.js.langchain.com/classes/langchain_core_runnables.RunnableMap.html) from `@langchain/core/runnables`
*   [RunnablePassthrough](https://api.js.langchain.com/classes/langchain_core_runnables.RunnablePassthrough.html) from `@langchain/core/runnables`
*   [StringOutputParser](https://api.js.langchain.com/classes/langchain_core_output_parsers.StringOutputParser.html) from `@langchain/core/output_parsers`

tip

[LangSmith trace](https://smith.langchain.com/public/f0205e20-c46f-47cd-a3a4-6a95451f8a25/r)

In this chain we add some extra logic around retrieving context from a vector store.

We first instantiated our model, vector store and output parser. Then we defined our prompt, which takes in two input variables:

*   `context` -> this is a string which is returned from our vector store based on a semantic search from the input.
*   `question` -> this is the question we want to ask.

Next we created a `setupAndRetriever` runnable. This has two components which return the values required by our prompt:

*   `context` -> this is a `RunnableLambda` which takes the input from the `.invoke()` call, makes a request to our vector store, and returns the first result.
*   `question` -> this uses a `RunnablePassthrough` which simply passes whatever the input was through to the next step, and in our case it returns it to the key in the object we defined.

Both of these are wrapped inside a `RunnableMap`. This is a special type of runnable that takes an object of runnables and executes them all in parallel. It then returns an object with the same keys as the input object, but with the values replaced with the output of the runnables.

Finally, we pass the output of the `setupAndRetriever` to our `prompt` and then to our `model` and `outputParser` as before.

* * *

#### Help us out by providing feedback on this documentation page:

[

Previous

LangChain Expression Language (LCEL)

](/v0.1/docs/expression_language/)[

Next

Why use LCEL?

](/v0.1/docs/expression_language/why/)

*   [Basic example: prompt + model + output parser](#basic-example-prompt--model--output-parser)
    *   [1\. Prompt](#1-prompt)
    *   [2\. Model](#2-model)
    *   [3\. Output parser](#3-output-parser)
*   [RAG Search Example](#rag-search-example)

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.