Overview

LangChain offers tooling to create custom LLM pipelines for complex decision-making. Through LangChain, you can manage your LLM and prompts, and combine them with advanced techniques like RAG and multi-stage prompting, and sub-chains. The library also offers components for output parsing, complex document loading, and callbacks.

Note: Vocode does not support actions with LangChain agents.*

Installation

Make sure to install the langchain optional dependencies by running

poetry install -E langchain -E langchain-extras

or

poetry install -E all

Default Chain

Vocode Core’s LangChain agent defaults to using the init_chat_model() method described here. This implementation allows users to create a LangChain agent using a variety of different model providers by passing in the relevant model and provider params into the LangchainAgentConfig. For example, if I want to use an OpenAI agent, I would pass in an agent config like:

from vocode.streaming.models.agent import LangchainAgentConfig

agent_config = LangchainAgentConfig(
    ...
    model_name = "gpt-4o"
    provider = "openai"
    ...
)

Note: Vocode Core includes the OpenAI, Anthropic, and Google VertexAI LangChain packages when you install the langchain extras in Poetry. If you want to use other LLM providers like AWS Bedrock, Cohere, Mistral, etc, you will need to manually install their LangChain integration packages.

Using Custom Chains

Our LangchainAgent is designed to make it easy to plug in your own custom LangChain chains. You can either:

  1. Manually pass in a chain to the LangchainAgent
  2. Subclass the LangchainAgent and build custom processing to create a chain based off a LangchainAgentConfig

Manually pass in a chain

The LangchainAgent constructor has a chain parameter where you can directly pass your chain. So, to use this in a conversation, you can create a custom AgentFactory that builds your chain when initializing the langchain agent.

For example, we will design a factory which makes a custom chain querying Anthropic Claude Opus to make a poem at each agent turn:

from vocode.streaming.agent.abstract_factory import AbstractAgentFactory
from vocode.streaming.models.agent import LangchainAgentConfig
from vocode.streaming.agent.langchain_agent import LangchainAgent
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate

class PoemAgentFactory(AbstractAgentFactory):
    def create_agent(
        self, agent_config: AgentConfig, logger: Optional[logging.Logger] = None
    ) -> BaseAgent:
        if isinstance(agent_config, LangchainAgentConfig):
            prompt_template = ChatPromptTemplate.from_template("Make a random poem")
            model = ChatAnthropic(model='claude-3-opus-20240229')
            chain = prompt_template | model
            return LangchainAgent(
                agent_config = agent_config,
                chain = chain,
            )
        else:
            raise Exception("Invalid agent config")

Creating custom chains from LangchainAgentConfig

In some scenarios, you may want to create a complex chain from a config, where you can have different models and providers. For these cases, we recommend creating a subclass of the LangchainAgent and overwriting the self.create_chain() method. This method is called when a LangchainAgent is initialized without a chain manually passed into the constructor. Within this method, you can directly access the agent config at self.agent_config and build your own chain using its fields.

For example below, we will design agent that builds a custom chain to query a Gemini LLM to generate a poem on a topic. The topic and LLM setup (provider and model name) will all be passed in via the config, allowing for strong customization. As a further example of this customizability, we will confirm the LLM provider is set to Google GenAI and raise an error otherwise.

from vocode.streaming.agent.abstract_factory import AbstractAgentFactory
from vocode.streaming.models.agent import LangchainAgentConfig
from vocode.streaming.agent.langchain_agent import LangchainAgent
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.prompts import ChatPromptTemplate

class PoemLangchainAgentConfig(LangchainAgentConfig):
    poem_topic: str

class PoemLangchainAgent(LangchainAgent):
    def create_chain(self):
        if self.agent_config.provider != "google_genai":
            raise Exception("PoemLangchainAgent only supports Google Generative AI models")

        prompt_template = ChatPromptTemplate.from_template(f"Make a random poem about {self.agent_config.poem_topic}")
        model = ChatGoogleGenerativeAI(
            model=self.agent_config.model_name,
            temperature=self.agent_config.temperature,
            max_output_tokens=self.agent_config.max_tokens
        )
        chain = prompt_template | model
        return chain


class MyAgentFactory(AbstractAgentFactory):
    def create_agent(
        self, agent_config: AgentConfig, logger: Optional[logging.Logger] = None
    ) -> BaseAgent:
        if isinstance(agent_config, PoemLangchainAgentConfig):
            return PoemLangchainAgent(
                agent_config=agent_config
            )
        elif isinstance(agent_config, LangchainAgentConfig):
            return LangchainAgent(
                agent_config=agent_config,
            )
        else:
            raise Exception("Invalid agent config")

Then, we can use the following agent config in conversations to use make poems about Vocode!

from vocode.streaming.models.agent import LangchainAgentConfig

agent_config = LangchainAgentConfig(
    ...
    model_name = "Vocode"
    provider = "poem"
    ...
)