Skip to content

Commit

Permalink
Update expression language docs, add RunnableMap.from method (langcha…
Browse files Browse the repository at this point in the history
jacoblee93 authored Oct 6, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 9f2d296 commit b89ad8f
Showing 7 changed files with 116 additions and 11 deletions.
4 changes: 0 additions & 4 deletions docs/docs_skeleton/docs/expression_language/index.mdx
Original file line number Diff line number Diff line change
@@ -13,7 +13,3 @@ The base interface shared by all LCEL objects

#### [Cookbook](/docs/expression_language/cookbook)
Examples of common LCEL usage patterns

You can also peruse this high-level overview/cheatsheet made by [@zhanghaili0610](https://twitter.com/zhanghaili0610):

![](/img/langchain-js-runnable-cheatsheet.png)
14 changes: 7 additions & 7 deletions docs/docs_skeleton/sidebars.js
Original file line number Diff line number Diff line change
@@ -35,23 +35,23 @@
},
{
type: "category",
label: "Modules",
label: "LangChain Expression Language",
collapsed: false,
collapsible: false,
items: [{ type: "autogenerated", dirName: "modules" } ],
items: [{ type: "autogenerated", dirName: "expression_language" } ],
link: {
type: 'doc',
id: "modules/index"
id: "expression_language/index"
},
},
{
type: "category",
label: "LangChain Expression Language",
label: "Modules",
collapsed: false,
items: [{ type: "autogenerated", dirName: "expression_language" } ],
collapsible: false,
items: [{ type: "autogenerated", dirName: "modules" } ],
link: {
type: 'doc',
id: "expression_language/index"
id: "modules/index"
},
},
{
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# LangChain Expression Language Cheatsheet

For a quick reference for LangChain Expression Language overview/cheatsheet made by [@zhanghaili0610](https://twitter.com/zhanghaili0610):

![](/img/langchain-js-runnable-cheatsheet.png)
22 changes: 22 additions & 0 deletions docs/extras/expression_language/how_to/map.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Use RunnableMaps

RunnableMaps allow you to execute multiple Runnables in parallel, and to return the output of these Runnables as a map.

import CodeBlock from "@theme/CodeBlock";
import BasicExample from "@examples/guides/expression_language/runnable_maps_basic.ts";

<CodeBlock language="typescript">{BasicExample}</CodeBlock>

## Manipulating outputs/inputs

Maps can be useful for manipulating the output of one Runnable to match the input format of the next Runnable in a sequence.

Note below that the object within the `RunnableSequence.from()` call is automatically coerced into a runnable map. All keys of the object must
have values that are runnables or can be themselves coerced to runnables (functions to `RunnableLambda`s or objects to `RunnableMap`s).
This coercion will also occur when composing chains via the `.pipe()` method.

import SequenceExample from "@examples/guides/expression_language/runnable_maps_sequence.ts";

<CodeBlock language="typescript">{SequenceExample}</CodeBlock>

Here the input to prompt is expected to be a map with keys "context" and "question". The user input is just the question. So we need to get the context using our retriever and passthrough the user input under the "question" key.
37 changes: 37 additions & 0 deletions examples/src/guides/expression_language/runnable_maps_basic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ChatAnthropic } from "langchain/chat_models/anthropic";
import { PromptTemplate } from "langchain/prompts";
import { RunnableMap } from "langchain/schema/runnable";

const model = new ChatAnthropic({});
const jokeChain = PromptTemplate.fromTemplate(
"Tell me a joke about {topic}"
).pipe(model);
const poemChain = PromptTemplate.fromTemplate(
"write a 2-line poem about {topic}"
).pipe(model);

const mapChain = RunnableMap.from({
joke: jokeChain,
poem: poemChain,
});

const result = await mapChain.invoke({ topic: "bear" });
console.log(result);
/*
{
joke: AIMessage {
content: " Here's a silly joke about a bear:\n" +
'\n' +
'What do you call a bear with no teeth?\n' +
'A gummy bear!',
additional_kwargs: {}
},
poem: AIMessage {
content: ' Here is a 2-line poem about a bear:\n' +
'\n' +
'Furry and wild, the bear roams free \n' +
'Foraging the forest, strong as can be',
additional_kwargs: {}
}
}
*/
41 changes: 41 additions & 0 deletions examples/src/guides/expression_language/runnable_maps_sequence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ChatAnthropic } from "langchain/chat_models/anthropic";
import { CohereEmbeddings } from "langchain/embeddings/cohere";
import { PromptTemplate } from "langchain/prompts";
import { StringOutputParser } from "langchain/schema/output_parser";
import {
RunnablePassthrough,
RunnableSequence,
} from "langchain/schema/runnable";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import type { Document } from "langchain/document";

const model = new ChatAnthropic();
const vectorstore = await HNSWLib.fromDocuments(
[{ pageContent: "mitochondria is the powerhouse of the cell", metadata: {} }],
new CohereEmbeddings()
);
const retriever = vectorstore.asRetriever();
const template = `Answer the question based only on the following context:
{context}
Question: {question}`;

const prompt = PromptTemplate.fromTemplate(template);

const formatDocs = (docs: Document[]) => docs.map((doc) => doc.pageContent);

const retrievalChain = RunnableSequence.from([
{ context: retriever.pipe(formatDocs), question: new RunnablePassthrough() },
prompt,
model,
new StringOutputParser(),
]);

const result = await retrievalChain.invoke(
"what is the powerhouse of the cell?"
);
console.log(result);

/*
Based on the given context, the powerhouse of the cell is mitochondria.
*/
4 changes: 4 additions & 0 deletions langchain/src/schema/runnable/base.ts
Original file line number Diff line number Diff line change
@@ -1252,6 +1252,10 @@ export class RunnableMap<RunInput> extends Runnable<
}
}

static from<RunInput>(steps: Record<string, RunnableLike<RunInput>>) {
return new RunnableMap<RunInput>({ steps });
}

async invoke(
input: RunInput,
options?: Partial<BaseCallbackConfig>

0 comments on commit b89ad8f

Please sign in to comment.