*   [](/v0.2/)
*   [How-to guides](/v0.2/docs/how_to/)
*   How to create a dynamic (self-constructing) chain

How to create a dynamic (self-constructing) chain
=================================================

Prerequisites

This guide assumes familiarity with the following:

*   [LangChain Expression Language (LCEL)](/v0.2/docs/concepts/#langchain-expression-language)
*   [How to turn any function into a runnable](/v0.2/docs/how_to/functions/)

Sometimes we want to construct parts of a chain at runtime, depending on the chain inputs ([routing](/v0.2/docs/how_to/routing/) is the most common example of this). We can create dynamic chains like this using a very useful property of RunnableLambda's, which is that if a RunnableLambda returns a Runnable, that Runnable is itself invoked. Let's see an example.

*   OpenAI
*   Anthropic
*   Azure
*   Google
*   Cohere
*   FireworksAI
*   Groq
*   MistralAI
*   TogetherAI

    pip install -qU langchain-openai

    import getpassimport osos.environ["OPENAI_API_KEY"] = getpass.getpass()from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-3.5-turbo-0125")

    pip install -qU langchain-anthropic

    import getpassimport osos.environ["ANTHROPIC_API_KEY"] = getpass.getpass()from langchain_anthropic import ChatAnthropicllm = ChatAnthropic(model="claude-3-sonnet-20240229")

    pip install -qU langchain-openai

    import getpassimport osos.environ["AZURE_OPENAI_API_KEY"] = getpass.getpass()from langchain_openai import AzureChatOpenAIllm = AzureChatOpenAI(    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],    azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],    openai_api_version=os.environ["AZURE_OPENAI_API_VERSION"],)

    pip install -qU langchain-google-vertexai

    import getpassimport osos.environ["GOOGLE_API_KEY"] = getpass.getpass()from langchain_google_vertexai import ChatVertexAIllm = ChatVertexAI(model="gemini-pro")

    pip install -qU langchain-cohere

    import getpassimport osos.environ["COHERE_API_KEY"] = getpass.getpass()from langchain_cohere import ChatCoherellm = ChatCohere(model="command-r")

    pip install -qU langchain-fireworks

    import getpassimport osos.environ["FIREWORKS_API_KEY"] = getpass.getpass()from langchain_fireworks import ChatFireworksllm = ChatFireworks(model="accounts/fireworks/models/mixtral-8x7b-instruct")

    pip install -qU langchain-groq

    import getpassimport osos.environ["GROQ_API_KEY"] = getpass.getpass()from langchain_groq import ChatGroqllm = ChatGroq(model="llama3-8b-8192")

    pip install -qU langchain-mistralai

    import getpassimport osos.environ["MISTRAL_API_KEY"] = getpass.getpass()from langchain_mistralai import ChatMistralAIllm = ChatMistralAI(model="mistral-large-latest")

    pip install -qU langchain-openai

    import getpassimport osos.environ["TOGETHER_API_KEY"] = getpass.getpass()from langchain_openai import ChatOpenAIllm = ChatOpenAI(    base_url="https://api.together.xyz/v1",    api_key=os.environ["TOGETHER_API_KEY"],    model="mistralai/Mixtral-8x7B-Instruct-v0.1",)

    # | echo: falsefrom langchain_anthropic import ChatAnthropicllm = ChatAnthropic(model="claude-3-sonnet-20240229")

**API Reference:**[ChatAnthropic](https://api.python.langchain.com/en/latest/chat_models/langchain_anthropic.chat_models.ChatAnthropic.html)

    from langchain_core.output_parsers import StrOutputParserfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_core.runnables import Runnable, RunnablePassthrough, chaincontextualize_instructions = """Convert the latest user question into a standalone question given the chat history. Don't answer the question, return the question and nothing else (no descriptive text)."""contextualize_prompt = ChatPromptTemplate.from_messages(    [        ("system", contextualize_instructions),        ("placeholder", "{chat_history}"),        ("human", "{question}"),    ])contextualize_question = contextualize_prompt | llm | StrOutputParser()qa_instructions = (    """Answer the user question given the following context:\n\n{context}.""")qa_prompt = ChatPromptTemplate.from_messages(    [("system", qa_instructions), ("human", "{question}")])@chaindef contextualize_if_needed(input_: dict) -> Runnable:    if input_.get("chat_history"):        # NOTE: This is returning another Runnable, not an actual output.        return contextualize_question    else:        return RunnablePassthrough()@chaindef fake_retriever(input_: dict) -> str:    return "egypt's population in 2024 is about 111 million"full_chain = (    RunnablePassthrough.assign(question=contextualize_if_needed).assign(        context=fake_retriever    )    | qa_prompt    | llm    | StrOutputParser())full_chain.invoke(    {        "question": "what about egypt",        "chat_history": [            ("human", "what's the population of indonesia"),            ("ai", "about 276 million"),        ],    })

**API Reference:**[StrOutputParser](https://api.python.langchain.com/en/latest/output_parsers/langchain_core.output_parsers.string.StrOutputParser.html) | [ChatPromptTemplate](https://api.python.langchain.com/en/latest/prompts/langchain_core.prompts.chat.ChatPromptTemplate.html) | [Runnable](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.base.Runnable.html) | [RunnablePassthrough](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.passthrough.RunnablePassthrough.html) | [chain](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.base.chain.html)

    "According to the context provided, Egypt's population in 2024 is estimated to be about 111 million."

The key here is that `contextualize_if_needed` returns another Runnable and not an actual output. This returned Runnable is itself run when the full chain is executed.

Looking at the trace we can see that, since we passed in chat\_history, we executed the contextualize\_question chain as part of the full chain: [https://smith.langchain.com/public/9e0ae34c-4082-4f3f-beed-34a2a2f4c991/r](https://smith.langchain.com/public/9e0ae34c-4082-4f3f-beed-34a2a2f4c991/r)

Note that the streaming, batching, etc. capabilities of the returned Runnable are all preserved

    for chunk in contextualize_if_needed.stream(    {        "question": "what about egypt",        "chat_history": [            ("human", "what's the population of indonesia"),            ("ai", "about 276 million"),        ],    }):    print(chunk)

    What is the population of Egypt?

[Edit this page](https://github.com/langchain-ai/langchain/edit/master/docs/docs/how_to/dynamic_chain.ipynb)

* * *

#### Was this page helpful?

  

#### You can also leave detailed feedback [on GitHub](https://github.com/langchain-ai/langchain/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 load PDFs

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

Next

Text embedding models

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