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
}
]
}