Skip to main content

LangChain Expression Language Cheatsheet

This is a quick reference for all the most important LCEL primitives. For more advanced usage see the LCEL how-to guides and the full API reference.

Invoke a runnable​

runnable.invoke()​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable = RunnableLambda.from((x: number) => x.toString());

await runnable.invoke(5);
"5"

Batch a runnable​

runnable.batch()​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable = RunnableLambda.from((x: number) => x.toString());

await runnable.batch([7, 8, 9]);
[ "7", "8", "9" ]

Stream a runnable​

runnable.stream()​

import { RunnableLambda } from "@langchain/core/runnables";

async function* generatorFn(x: number[]) {
for (const i of x) {
yield i.toString();
}
}

const runnable = RunnableLambda.from(generatorFn);

const stream = await runnable.stream([0, 1, 2, 3, 4]);

for await (const chunk of stream) {
console.log(chunk);
console.log("---");
}
0
---
1
---
2
---
3
---
4
---

Compose runnables​

runnable.pipe()​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable1 = RunnableLambda.from((x: any) => {
return { foo: x };
});

const runnable2 = RunnableLambda.from((x: any) => [x].concat([x]));

const chain = runnable1.pipe(runnable2);

await chain.invoke(2);
[ { foo: 2 }, { foo: 2 } ]

RunnableSequence.from()​

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

const runnable1 = RunnableLambda.from((x: any) => {
return { foo: x };
});

const runnable2 = RunnableLambda.from((x: any) => [x].concat([x]));

const chain = RunnableSequence.from([runnable1, runnable2]);

await chain.invoke(2);
[ { foo: 2 }, { foo: 2 } ]

Invoke runnables in parallel​

RunnableParallel​

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

const runnable1 = RunnableLambda.from((x: any) => {
return { foo: x };
});

const runnable2 = RunnableLambda.from((x: any) => [x].concat([x]));

const chain = RunnableParallel.from({
first: runnable1,
second: runnable2,
});

await chain.invoke(2);
{ first: { foo: 2 }, second: [ 2, 2 ] }

Turn a function into a runnable​

RunnableLambda​

import { RunnableLambda } from "@langchain/core/runnables";

const adder = (x: number) => {
return x + 5;
};

const runnable = RunnableLambda.from(adder);

await runnable.invoke(5);
10

Merge input and output dicts​

RunnablePassthrough.assign()​

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

const runnable = RunnableLambda.from((x: { foo: number }) => {
return x.foo + 7;
});

const chain = RunnablePassthrough.assign({
bar: runnable,
});

await chain.invoke({ foo: 10 });
{ foo: 10, bar: 17 }

Include input dict in output dict​

RunnablePassthrough​

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

const runnable = RunnableLambda.from((x: { foo: number }) => {
return x.foo + 7;
});

const chain = RunnableParallel.from({
bar: runnable,
baz: new RunnablePassthrough(),
});

await chain.invoke({ foo: 10 });
{ baz: { foo: 10 }, bar: 17 }

Add default invocation args​

runnable.bind()​

import { type RunnableConfig, RunnableLambda } from "@langchain/core/runnables";

const branchedFn = (mainArg: Record<string, any>, config?: RunnableConfig) => {
if (config?.configurable?.boundKey !== undefined) {
return { ...mainArg, boundKey: config?.configurable?.boundKey };
}
return mainArg;
};

const runnable = RunnableLambda.from(branchedFn);
const boundRunnable = runnable.bind({ configurable: { boundKey: "goodbye!" } });

await boundRunnable.invoke({ bar: "hello" });
{ bar: "hello", boundKey: "goodbye!" }

Add fallbacks​

runnable.withFallbacks()​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable = RunnableLambda.from((x: any) => {
throw new Error("Error case");
});

const fallback = RunnableLambda.from((x: any) => x + x);

const chain = runnable.withFallbacks([fallback]);

await chain.invoke("foo");
"foofoo"

Add retries​

runnable.withRetry()​

import { RunnableLambda } from "@langchain/core/runnables";

let counter = 0;

const retryFn = (_: any) => {
counter++;
console.log(`attempt with counter ${counter}`);
throw new Error("Expected error");
};

const chain = RunnableLambda.from(retryFn).withRetry({
stopAfterAttempt: 2,
});

await chain.invoke(2);
attempt with counter 1
attempt with counter 2
Error: Expected error

Configure runnable execution​

RunnableConfig​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable1 = RunnableLambda.from(async (x: any) => {
await new Promise((resolve) => setTimeout(resolve, 2000));
return { foo: x };
});

// Takes 4 seconds
await runnable1.batch([1, 2, 3], { maxConcurrency: 2 });
[ { foo: 1 }, { foo: 2 }, { foo: 3 } ]

Add default config to runnable​

runnable.withConfig()​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable1 = RunnableLambda.from(async (x: any) => {
await new Promise((resolve) => setTimeout(resolve, 2000));
return { foo: x };
}).withConfig({
maxConcurrency: 2,
});

// Takes 4 seconds
await runnable1.batch([1, 2, 3]);
[ { foo: 1 }, { foo: 2 }, { foo: 3 } ]

Build a chain dynamically based on input​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable1 = RunnableLambda.from((x: any) => {
return { foo: x };
});

const runnable2 = RunnableLambda.from((x: any) => [x].concat([x]));

const chain = RunnableLambda.from((x: number): any => {
if (x > 6) {
return runnable1;
}
return runnable2;
});

await chain.invoke(7);
{ foo: 7 }
await chain.invoke(5);
[ 5, 5 ]

Generate a stream of internal events​

runnable.streamEvents()​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable1 = RunnableLambda.from((x: number) => {
return {
foo: x,
};
}).withConfig({
runName: "first",
});

async function* generatorFn(x: { foo: number }) {
for (let i = 0; i < x.foo; i++) {
yield i.toString();
}
}

const runnable2 = RunnableLambda.from(generatorFn).withConfig({
runName: "second",
});

const chain = runnable1.pipe(runnable2);

for await (const event of chain.streamEvents(2, { version: "v1" })) {
console.log(
`event=${event.event} | name=${event.name} | data=${JSON.stringify(
event.data
)}`
);
}
event=on_chain_start | name=RunnableSequence | data={"input":2}
event=on_chain_start | name=first | data={}
event=on_chain_stream | name=first | data={"chunk":{"foo":2}}
event=on_chain_start | name=second | data={}
event=on_chain_end | name=first | data={"input":2,"output":{"foo":2}}
event=on_chain_stream | name=second | data={"chunk":"0"}
event=on_chain_stream | name=RunnableSequence | data={"chunk":"0"}
event=on_chain_stream | name=second | data={"chunk":"1"}
event=on_chain_stream | name=RunnableSequence | data={"chunk":"1"}
event=on_chain_end | name=second | data={"output":"01"}
event=on_chain_end | name=RunnableSequence | data={"output":"01"}

Return a subset of keys from output object​

runnable.pick()​

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

const runnable = RunnableLambda.from((x: { baz: number }) => {
return x.baz + 5;
});

const chain = RunnablePassthrough.assign({
foo: runnable,
}).pick(["foo", "bar"]);

await chain.invoke({ bar: "hi", baz: 2 });
{ foo: 7, bar: "hi" }

Declaratively make a batched version of a runnable​

runnable.map()​

import { RunnableLambda } from "@langchain/core/runnables";

const runnable1 = RunnableLambda.from((x: number) => [...Array(x).keys()]);
const runnable2 = RunnableLambda.from((x: number) => x + 5);

const chain = runnable1.pipe(runnable2.map());

await chain.invoke(3);
[ 5, 6, 7 ]

Get a graph representation of a runnable​

runnable.getGraph()​

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

const runnable1 = RunnableLambda.from((x: any) => {
return { foo: x };
});

const runnable2 = RunnableLambda.from((x: any) => [x].concat([x]));

const runnable3 = RunnableLambda.from((x: any) => x.toString());

const chain = RunnableSequence.from([
runnable1,
{
second: runnable2,
third: runnable3,
},
]);

await chain.getGraph();
Graph {
nodes: {
"935c67df-7ae3-4853-9d26-579003c08407": {
id: "935c67df-7ae3-4853-9d26-579003c08407",
data: {
name: "RunnableLambdaInput",
schema: ZodAny {
spa: [Function: bound safeParseAsync] AsyncFunction,
_def: [Object],
parse: [Function: bound parse],
safeParse: [Function: bound safeParse],
parseAsync: [Function: bound parseAsync] AsyncFunction,
safeParseAsync: [Function: bound safeParseAsync] AsyncFunction,
refine: [Function: bound refine],
refinement: [Function: bound refinement],
superRefine: [Function: bound superRefine],
optional: [Function: bound optional],
nullable: [Function: bound nullable],
nullish: [Function: bound nullish],
array: [Function: bound array],
promise: [Function: bound promise],
or: [Function: bound or],
and: [Function: bound and],
transform: [Function: bound transform],
brand: [Function: bound brand],
default: [Function: bound default],
catch: [Function: bound catch],
describe: [Function: bound describe],
pipe: [Function: bound pipe],
readonly: [Function: bound readonly],
isNullable: [Function: bound isNullable],
isOptional: [Function: bound isOptional],
_any: true
}
}
},
"a73d7b3e-0ed7-46cf-b141-de64ea1e12de": {
id: "a73d7b3e-0ed7-46cf-b141-de64ea1e12de",
data: RunnableLambda {
lc_serializable: false,
lc_kwargs: { func: [Function (anonymous)] },
lc_runnable: true,
name: undefined,
lc_namespace: [ "langchain_core", "runnables" ],
func: [Function (anonymous)]
}
},
"ff104b34-c13b-4677-8b82-af70d3548e12": {
id: "ff104b34-c13b-4677-8b82-af70d3548e12",
data: RunnableMap {
lc_serializable: true,
lc_kwargs: { steps: [Object] },
lc_runnable: true,
name: undefined,
lc_namespace: [ "langchain_core", "runnables" ],
steps: { second: [RunnableLambda], third: [RunnableLambda] }
}
},
"2dc627dc-1c06-45b1-b14f-bb1f6e689f83": {
id: "2dc627dc-1c06-45b1-b14f-bb1f6e689f83",
data: {
name: "RunnableMapOutput",
schema: ZodAny {
spa: [Function: bound safeParseAsync] AsyncFunction,
_def: [Object],
parse: [Function: bound parse],
safeParse: [Function: bound safeParse],
parseAsync: [Function: bound parseAsync] AsyncFunction,
safeParseAsync: [Function: bound safeParseAsync] AsyncFunction,
refine: [Function: bound refine],
refinement: [Function: bound refinement],
superRefine: [Function: bound superRefine],
optional: [Function: bound optional],
nullable: [Function: bound nullable],
nullish: [Function: bound nullish],
array: [Function: bound array],
promise: [Function: bound promise],
or: [Function: bound or],
and: [Function: bound and],
transform: [Function: bound transform],
brand: [Function: bound brand],
default: [Function: bound default],
catch: [Function: bound catch],
describe: [Function: bound describe],
pipe: [Function: bound pipe],
readonly: [Function: bound readonly],
isNullable: [Function: bound isNullable],
isOptional: [Function: bound isOptional],
_any: true
}
}
}
},
edges: [
{
source: "935c67df-7ae3-4853-9d26-579003c08407",
target: "a73d7b3e-0ed7-46cf-b141-de64ea1e12de",
data: undefined
},
{
source: "ff104b34-c13b-4677-8b82-af70d3548e12",
target: "2dc627dc-1c06-45b1-b14f-bb1f6e689f83",
data: undefined
},
{
source: "a73d7b3e-0ed7-46cf-b141-de64ea1e12de",
target: "ff104b34-c13b-4677-8b82-af70d3548e12",
data: undefined
}
]
}

Was this page helpful?


You can also leave detailed feedback on GitHub.