大模型agent开发之chains
新版langchain中已经弃用了LLMChain等内置链的组装和框架,取而代之的是使用 runables包中内置的类和方法 来构建更灵活的链,其中最主要的方法是RunablesSequence,RunnableLambda和
RunnableMap。
一:RunnablesSenquence
RunnablesSenquence可以直接实例化,更常用的方式是使用|运算符实例化,其中左操作数或右操作数(或两者)必须是 Runnable,任何 RunnableSequence 都会自动支持同步、异步、批处理。batch 和 abatch 的默认实现利用线程池和 asyncio 收集,并且比对 IO 绑定 Runnable 的invoke 或 ainvoke 的简单调用更快。通过按顺序调用 RunnableSequence 的每个组件上的 batch 方法来实现批处理。RunnableSequence 保留其组件的流式传输属性,因此如果序列的所有组件都实现了转换方法(即实现将流式传输输入映射到流式传输输出的逻辑的方法),那么序列将能够将输入流式传输到输出!如果序列的任何组件未实现转换,则只有在运行此组件后才会开始流式传输。如果有多个阻塞组件,则流式传输将在最后一个组件之后开始。
二:RunnableLambda
RunnableLambda将 Python 可调用函数转换为 Runnable。将可调用函数包装在 RunnableLambda 中可使可调用函数在同步或异步上下文中可用。RunnableLambda 可以像任何其他 Runnable 一样组合,并提供与 LangChain 跟踪的无缝集成。RunnableLambda不支持流式传输代码,如果要传输流式数据代码需要使用RunnableGenerator。
三: RunnableMap
RunnableMap是RunnableParallel 的别名,RunnableParallel 是 LCEL 的两个主要组合原语之一,与 RunnableSequence 并列。它同时调用 Runnable,为每个 Runnable 提供相同的输入。RunnableParallel 可以直接实例化,也可以通过使用序列中的字典文字来实例化。
通过对RunnableLambda和RunnableMap的组合使用可以实现大模型顺序链式模块的功能。
# 顺序链 def seq_chain(self): # 链一任务:翻译成中文 first_chain = RunnableLambda( lambda content: self.llm.invoke(str(self.prompt[0].invoke(content))), afunc=lambda content: self.llm.ainvoke(str(self.prompt[0].invoke(content))) # 如果需要异步支持 ) # 链二任务:对翻译的中文进行总结 second_chain = RunnableLambda( lambda chinese_review: self.llm.invoke(str(self.prompt[1].invoke(chinese_review))), afunc=lambda chinese_review: self.llm.ainvoke(str(self.prompt[1].invoke(chinese_review))) ) # 链三任务:智能识别语言 third_chain = RunnableLambda( lambda summary: self.llm.invoke(str(self.prompt[2].invoke(summary))), afunc=lambda summary: self.llm.ainvoke(str(self.prompt[2].invoke(summary))) ) # 链四任务:针对摘要使用语言进行评论 four_chain = RunnableLambda( lambda language: self.llm.invoke(str(self.prompt[3].invoke(language))), afunc=lambda language: self.llm.ainvoke(str(self.prompt[3].invoke(language))) ) # 使用 RunnableMap 来串联所有任务 overall_chain = RunnableMap( { "Chinese_Rview": first_chain, "Chinese_Summary": second_chain, "Language": third_chain, "Reply": four_chain } ) # 读取文件 content = self.question # 依次调用各个链 ans = overall_chain.invoke(content) print(f"chains answer: {ans}") return ans
每个链都使用 RunnableLambda
来定义其执行逻辑。输入被传递给下一个链的输入。所有的 RunnableLambda
被组合在 RunnableMap
中,这样可以按照顺序执行,并且方便管理每个链的输出。
通过对RunnableLambda的使用可以实现路由链,设置俩种完全不同的提示词模版,根据问题的不同,使其可以路由到对应的链中,从而返回准确的答案。
# 路由链 def route_chain(self): # 模版格式化 prompt_infos = [ { "name": "economy", "description": "Good at answering economic questions", "prompt_template": self.prompt[0], }, { "name": "zhouyi", "description": "Good at fortune telling", "prompt_template": self.prompt[1], }, ] # 创建提示链 description_chains = {} for p_info in prompt_infos: name = p_info["name"] prompt_template = p_info["prompt_template"] prompt = PromptTemplate(template=prompt_template, input_variables=["input"]) # 使用 RunnableLambda 创建每个提示链 chain = RunnableLambda(lambda input_value: self.llm.invoke(str(prompt.invoke(input_value)))) description_chains[name] = chain # 使用 Router 模板生成路由提示 destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos] destinations_str = "\n".join(destinations) router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str) router_prompt = PromptTemplate(template=router_template, input_variables=["input"]) # 创建路由链 router_chain = RunnableLambda(lambda input_value: self.llm.invoke(str(router_prompt.invoke(input_value)))) # 创建默认链 default_chain = RunnableLambda(lambda input_value: self.llm.invoke(str(input_value))) # 假设默认链是直接调用 LLM # 创建 MultiPromptChain chains = RunnableLambda( lambda input_value: ( description_chains.get(self.route(input_value), router_chain).invoke(input_value) ), afunc=lambda input_value: ( description_chains.get(self.route(input_value), default_chain).invoke(input_value) ) ) # 运行链 ans = chains.invoke(self.question) print(f"chains answer: {ans}") def route(self, input_value): # 示例路由逻辑 if "economics" in input_value: return "economy" elif "zhouyi" in input_value: return "zhouyi" else: return None # 或者返回默认链的名称
self.route(input_value)
来决定将输入内容发送到哪个链中,这里self.route(input_value)
返回的字符串将用于查找 description_chains
字典中的相应链。如果没有找到,就会使用 default_chain
作为备选处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2020-10-28 作业要求 20201022-1 每周例行报告