šŸ“• Build AI Agents using LangGraph.js is now out!

Custom Functions with RunnableLambda in LangChain JS

Each node in a chain made with LCEL (LangChain Expression Language) needs to implement the Runnable interface interface.

One direct child of Runnable is RunnableLambda.

The RunnableLambda is used to add custom functions to LCEL chains, allowing us to manipulate the data that flows between the links of that chain.

A Simple JavaScript Example with RunnableLambda

Let's start with a simple RunnableLambda example:

import { RunnablePassthrough } from "@langchain/core/runnables"

const chain1 = new RunnablePassthrough()
                .pipe(new RunnablePassthrough())
                .pipe(new RunnablePassthrough())

const result1 = await chain1.invoke('Hi there, friend šŸ‘‹ !!!')
console.log(result1)

// will ouput: Hi there, friend šŸ‘‹ !!!

The RunnablePassthrough just passes the data to the next link in the chain. The above three-link chain will return the same data as the initial input.

But what if we need to change the initial Hi there, friend šŸ‘‹ !!! string, like converting it to uppercase? This is where a JavaScript function comes in handy.

To add a custom JavaScript function to a chain, we need to wrap it in a RunnableLambda. This will expose methods such as pipe() or invoke(), making the function integrable within an LCEL chain.

Take a look at the below code:

import { 
    RunnableLambda, RunnablePassthrough 
} from "@langchain/core/runnables"

const toUpperCase = input => input.toUpperCase()

const chain2 = new RunnablePassthrough()
                    .pipe(new RunnableLambda({
                        func: toUpperCase
                    }))
                    .pipe(new RunnablePassthrough())

const result2 = await chain2.invoke('Hi there, friend šŸ‘‹ !!!')
console.log(result2)

// will ouput: HI THERE, FRIEND šŸ‘‹ !!!

Later update: someone was kind enough to show me on the LangChain subreddit a more ergonomic way of passing down the function using RunnableLambda.from(). Therefore, the above chain2 can also be written as:

const toUpperCase = input => input.toUpperCase()
const chain2 = new RunnablePassthrough()
 .pipe(RunnableLambda.from(toUpperCase))
 .pipe(new RunnablePassthrough())

Fixing the TypeError: this.func is not a function

Note that the custom function needs to be provided via the func parameter. Failing to do so will throw the TypeError: this.func is not a function error.

// ā›”ļø throws TypeError: this.func is not a function
new RunnableLambda(myCustomFunction)

// šŸ‘ works ok
new RunnableLambda({
    func: myCustomFunction
})

Using Chains in a RunnableLambda Custom Function

The above example was simple and isolated. However, we can use RunnableLambda in more complex scenarios. For example, we can use other chains within the custom function:

import { ChatOpenAI } from "@langchain/openai"
import { StringOutputParser } from "@langchain/core/output_parsers"
import { ChatPromptTemplate } from "@langchain/core/prompts"
import { RunnableLambda } from "@langchain/core/runnables"
import * as dotenv from "dotenv"

dotenv.config()
const model = new ChatOpenAI({ modelName: "gpt-4o"})

const cityPromt = ChatPromptTemplate.fromTemplate(
  "What is the biggest city in {country}"
)

const factPrompt = ChatPromptTemplate.fromTemplate(
  "Tell me an interestign fact about {city}"
)

const composedChain = new RunnableLambda({
  func: async input => {
    const chain = cityPromt
            .pipe(model)
            .pipe(new StringOutputParser())
    const result = await chain.invoke(input)
    return { city: result }
  }
})
  .pipe(factPrompt)
  .pipe(model)
  .pipe(new StringOutputParser())

console.log(await composedChain.invoke({ country: "Spain" }))

The above code will output something like this:
RunnableLambda LangChain JS example output

As always you can see the full code of these examples on my GitHub. Happy coding!

šŸ“– Build a full trivia game app with LangChain

Learn by doing with this FREE ebook! This 35-page guide walks you through every step of building your first fully functional AI-powered app using JavaScript and LangChain.js

šŸ“– Build a full trivia game app with LangChain

Learn by doing with this FREE ebook! This 35-page guide walks you through every step of building your first fully functional AI-powered app using JavaScript and LangChain.js


Leave a Reply

Your email address will not be published. Required fields are marked *