langchain框架-对比分析chain的三种实现方式
对比分析chain的三种实现方式
方式一
setup_and_retrieval = RunnableParallel({"context": retriever,"question": RunnablePassthrough()}
)
chain = setup_and_retrieval | prompt | model | outputParser
效果分析:
- 并行处理:
RunnableParallel
并行执行两个任务,一个是通过retriever
获取上下文,另一个是通过RunnablePassthrough
传递问题。 - 输入输出:
setup_and_retrieval
的输出是一个包含context
和question
的字典,这个字典被传递给prompt
组件。 - 适用场景:适用于简单的 RAG(Retrieval-Augmented Generation)链路,用户输入一个字符串形式的问题。
方式二
chain = ({"context": retriever, "question": RunnablePassthrough()}| prompt| model| StrOutputParser()
)
chain.invoke("小明在哪里工作?")
效果分析:
- 简洁性:这种方式直接将
RunnableParallel
的定义嵌入到链路中,减少了中间变量的定义,使代码更加简洁。 - 功能等价:与方式一功能等价,都是通过
RunnableParallel
并行获取上下文和问题,然后传递给后续组件。 - 适用场景:适用于需要快速构建简单链路的场景。
方式三
chain = ({"context": itemgetter("question") | retriever,"question": itemgetter("question"),"name": itemgetter("name"),}| prompt| model| StrOutputParser()
)
chain.invoke({"question": "小明在哪里工作?", "name": "主人"})
效果分析:
- 扩展性:这种方式通过
itemgetter
从输入字典中提取question
和name
,并分别传递给retriever
和其他组件。这种方式更加灵活,可以处理更复杂的输入结构。 - 多输入支持:除了
question
,还可以传递其他信息(如name
),这使得链路可以处理更复杂的需求。 - 适用场景:适用于需要处理复杂输入结构或需要从多个字段中提取信息的场景。
总结
- 方式一 和 方式二 主要适用于简单的 RAG 链路,用户输入一个字符串形式的问题。方式二更加简洁。
- 方式三 提供了更高的灵活性和扩展性,可以处理更复杂的输入结构,适用于需要从多个字段中提取信息的场景。
通过对比可以看出,三种方式各有优劣,选择哪种方式取决于具体的应用需求和输入数据的复杂性。