如何以并行方式调用可运行程序
本指南假设您熟悉以下概念
The RunnableParallel
(也称为 RunnableMap
) 原语是一个对象,其值是可运行程序(或可以强制转换为可运行程序的事物,例如函数)。它会并行运行其所有值,并且每个值都会使用传递给 RunnableParallel
的初始输入进行调用。最终返回值是一个对象,其中包含每个值的结果,位于其相应的键下。
使用 RunnableParallels
进行格式化
RunnableParallels
可用于并行化操作,但也可用于操作一个可运行程序的输出,使其与序列中下一个可运行程序的输入格式匹配。您可以使用它们拆分或分支链,以便多个组件可以并行处理输入。稍后,其他组件可以加入或合并结果以合成最终响应。这种类型的链会创建一个计算图,如下所示
Input
/ \
/ \
Branch1 Branch2
\ /
\ /
Combine
在下文中,RunnableParallel
中每个链的输入都应为一个对象,其中包含一个名为 "topic"
的键。我们可以通过使用与该结构匹配的对象来调用我们的链来满足该要求。
请参阅有关安装集成包的通用说明的本节。
- npm
- Yarn
- pnpm
npm install @langchain/anthropic @langchain/cohere
yarn add @langchain/anthropic @langchain/cohere
pnpm add @langchain/anthropic @langchain/cohere
import { PromptTemplate } from "@langchain/core/prompts";
import { RunnableMap } from "@langchain/core/runnables";
import { ChatAnthropic } from "@langchain/anthropic";
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: {}
}
}
*/
API 参考
- PromptTemplate 来自
@langchain/core/prompts
- RunnableMap 来自
@langchain/core/runnables
- ChatAnthropic 来自
@langchain/anthropic
操作输出/输入
地图可用于操作一个可运行程序的输出,使其与序列中下一个可运行程序的输入格式匹配。
请注意,在下面的 RunnableSequence.from()
调用中的对象会自动强制转换为可运行地图。对象的所有键都必须具有可运行程序的值,或者可以自行强制转换为可运行程序(函数到 RunnableLambda
或对象到 RunnableMap
)。此强制转换也会在通过 .pipe()
方法组合链时发生。
import { CohereEmbeddings } from "@langchain/cohere";
import { PromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
import {
RunnablePassthrough,
RunnableSequence,
} from "@langchain/core/runnables";
import { Document } from "@langchain/core/documents";
import { ChatAnthropic } from "@langchain/anthropic";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
const model = new ChatAnthropic();
const vectorstore = await MemoryVectorStore.fromDocuments(
[{ pageContent: "mitochondria is the powerhouse of the cell", metadata: {} }],
new CohereEmbeddings({ model: "embed-english-v3.0" })
);
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.
*/
API 参考
- CohereEmbeddings 来自
@langchain/cohere
- PromptTemplate 来自
@langchain/core/prompts
- StringOutputParser 来自
@langchain/core/output_parsers
- RunnablePassthrough 来自
@langchain/core/runnables
- RunnableSequence 来自
@langchain/core/runnables
- Document 来自
@langchain/core/documents
- ChatAnthropic 来自
@langchain/anthropic
- MemoryVectorStore 来自
langchain/vectorstores/memory
这里,提示的输入应为一个包含键 "context" 和 "question" 的地图。用户输入只是问题。因此,我们需要使用我们的检索器获取上下文并将用户输入传递给 "question" 键。
下一步
您现在已经了解了如何使用 RunnableParallel
来格式化和并行化链步骤。
接下来,您可能希望了解有关在链中使用自定义逻辑的更多信息。