Short #14 | How does Langchain Expression Language (LCEL) work ?
Classic use of Polymorphism and Operator overloading
As per official Langchain documentation: “LangChain Expression Language (LCEL), is a declarative way to easily compose chains together.”
(This is not a tutorial on how to use LCEL, but a simplistic explanation of how something like this would work behind the scenes)
What is a chain ? An example would be:
The line to focus on here is the “chain” - where the output of one component - “prompt” gets fed to another component - “model” and it propagates till the last component. Here the chain gets triggered upon calling the invoke ( ) method.
Doesn’t it seem magical? This is our good old pipe operator wearing the magical hat.
The “pipe” operator is generally used for chaining functions and its behavior is internally implemented using the __or__ dunder (Double UNDERscore) method.
This means that:
This is classic “operator overloading” where the “|” operator is overloaded using __or__ ( ).
Similarly, there are other operators that can be overloaded using their corresponding dunder methods:
This means that we can make 2+3=6 by modifying the __add__( ) method and making it work like multiplication instead of addition. This would be overloading the “+” operator.
Let’s revisit the chain above and try to implement its first part - “prompt | model” which can be translated using the __or__( ) method as follows:
This implies that the Prompt class should have a __or__( ) method that should take the model object as the input and give the output. The code would be:
This might look a bit unintuitive at first but it’s the model object that processes the prompt text and not the other way around - which makes sense.
Going ahead in the chain - Model class should have a process ( ) method that takes some text (prompt) as the input and gives some output. Hence the entire code would look something like this:
The output of the above chain would be:
"Parsed output: Processed by model: This is a test prompt."
And that’s it - this was just a simple example of how something like LCEL would work. Notice that we haven’t used the invoke ( ) method here as shown in the first LCEL example. But that would work on similar lines. LCEL in itself is more complex than this.
This should give you an idea if you plan to have your own custom Expression Language :)