Runnables and Expression Language

Discover how the LangChain framework allows us to execute a sequence of calls to LLMs.

Problem-solving typically involves a series of steps. When using LLMs, some applications have relatively complex requirements and a sequence of calls for performing an operation. Here’s when runnables come into play.

This functionality was previously fulfilled by the LLMChain class; however, that class was deprecated in version 0.1.17. We now use runnable instead.

What is a runnable?

In LangChain, runnables are powerful abstractions representing any callable unit of work. They encapsulate and manage various tasks, including LLM calls, database queries, and calls to external APIs.

This allows us to chain together diverse operations consistently and manageably, making it easy to construct complex workflows within LangChain applications.

We have been using the ChatGroq ChatModel with the invoke() method to send our queries to the model. The chat model class is a type of runnable component. Runnable components use a runnable interface that enables them to work consistently. Methods like invoke(), batch(), and stream() are common for all runnable components.

  • invoke() processes a single input and returns a single output, ideal for individual requests.

  • batch () allows us to process a list of inputs simultaneously and return a list of corresponding outputs, which is much more efficient for handling multiple requests at once.

  • stream() processes a single input but returns an output as a stream of chunks, which is useful for displaying real-time progress or handling very large outputs.

So far, we have used the Prompt , ChatModel, and OutputParser. These are all types of runnables. If you were paying attention, you might have noticed that we were using the output of one component as the input for another.

  1. The PromptValue output from the PromptTemplate was passed as input to the ChatModel.

  2. The string output from the ChatModel was passed as input to the OutputParser.

Essentially, runnable components take an input and produce an output. Now, imagine a more complex workflow. It would become challenging to create and manage ...