RunnablePassthrough 两种写法对比.assign()的参数到底要不要包RunnableLambda一、两种调用方式对比LangChain 提供了两种调用assign的方式功能等价但写法不同。1.1 写法一实例方法.assign()fromlangchain_core.runnablesimportRunnableParallel,RunnablePassthrough chainRunnableParallel(passedRunnablePassthrough().assign(modifiedlambdax:x[k1]!!!),)1.2 写法二类方法assign()fromlangchain_core.runnablesimportRunnablePassthroughdefget_user_age(data):return25chainRunnablePassthrough.assign(ageget_user_age)二、核心对比对比项写法一RunnablePassthrough().assign(...)写法二RunnablePassthrough.assign(...)调用方式实例方法先创建实例再调用类方法直接通过类调用返回值Runnable实例Runnable实例功能效果保留原字段 添加新字段保留原字段 添加新字段使用场景通常配合RunnableParallel使用通常作为独立步骤使用本质区别先实例化再配置类级别的工厂方法结论两种写法功能完全等价选择取决于代码上下文和个人习惯。三、参数要不要包RunnableLambda这是最容易混淆的地方。答案是在.assign()里不需要在管道运算符\|里需要。3.1 不需要包的场景以下方法内部会自动把函数或 Lambda 包装成RunnableLambdafromlangchain_core.runnablesimportRunnablePassthrough,RunnableParalleldefget_user_age(data):return25# ✅ RunnablePassthrough.assign() —— 自动转换chain1RunnablePassthrough.assign(ageget_user_age)# ✅ RunnableParallel() —— 自动转换chain2RunnableParallel({result:lambdax:x[name].upper()})# ✅ 直接传 lambda —— 自动转换chain3RunnablePassthrough().assign(modifiedlambdax:x[k1]!!!)3.2 需要包的场景管道运算符\|只接受Runnable对象不会自动转换fromlangchain_core.runnablesimportRunnableLambda# ❌ 错误普通函数不能直接接在管道里chain_badstep1|get_user_age|step2# ✅ 正确必须手动包一层 RunnableLambdachain_goodstep1|RunnableLambda(get_user_age)|step2四、四种等价写法实测fromlangchain_core.runnablesimportRunnablePassthrough,RunnableLambdadefget_user_age(data):return25# 写法1直接传函数最简洁推荐r1RunnablePassthrough.assign(ageget_user_age)# 写法2传 lambda也简洁r2RunnablePassthrough.assign(agelambdax:25)# 写法3手动包 RunnableLambda啰嗦但效果一样r3RunnablePassthrough.assign(ageRunnableLambda(get_user_age))# 写法4实例方式调用r4RunnablePassthrough().assign(ageget_user_age)# 测试forrin[r1,r2,r3,r4]:resultr.invoke({name:Alice})print(result)输出{name:Alice,age:25}{name:Alice,age:25}{name:Alice,age:25}{name:Alice,age:25}五、自动转换方法汇总方法/类自动转换函数为 RunnableLambdaRunnablePassthrough.assign()✅ 是RunnableParallel()✅ 是RunnableLambda()构造函数✅ 是当然管道运算符|❌ 否RunnableSequence()❌ 否六、最佳实践建议场景推荐写法原因.assign()里传函数ageget_user_age最简洁可读性最好.assign()里简单逻辑agelambda x: ...无需定义额外函数管道|里传函数RunnableLambda(func)必须手动包否则报错配合RunnableParallelRunnablePassthrough().assign(...)实例方式更自然七、一句话总结.assign()和RunnableParallel是友好的 API看到函数会自动帮你包成RunnableLambda但管道运算符\|是严格的只接受 Runnable 对象不会自动转换。在.assign()里直接写函数或 Lambda 就行别画蛇添足包RunnableLambda。
【LangChain 】RunnablePassthrough 两种写法对比:`.assign()` 的参数到底要不要包 `RunnableLambda`?
RunnablePassthrough 两种写法对比.assign()的参数到底要不要包RunnableLambda一、两种调用方式对比LangChain 提供了两种调用assign的方式功能等价但写法不同。1.1 写法一实例方法.assign()fromlangchain_core.runnablesimportRunnableParallel,RunnablePassthrough chainRunnableParallel(passedRunnablePassthrough().assign(modifiedlambdax:x[k1]!!!),)1.2 写法二类方法assign()fromlangchain_core.runnablesimportRunnablePassthroughdefget_user_age(data):return25chainRunnablePassthrough.assign(ageget_user_age)二、核心对比对比项写法一RunnablePassthrough().assign(...)写法二RunnablePassthrough.assign(...)调用方式实例方法先创建实例再调用类方法直接通过类调用返回值Runnable实例Runnable实例功能效果保留原字段 添加新字段保留原字段 添加新字段使用场景通常配合RunnableParallel使用通常作为独立步骤使用本质区别先实例化再配置类级别的工厂方法结论两种写法功能完全等价选择取决于代码上下文和个人习惯。三、参数要不要包RunnableLambda这是最容易混淆的地方。答案是在.assign()里不需要在管道运算符\|里需要。3.1 不需要包的场景以下方法内部会自动把函数或 Lambda 包装成RunnableLambdafromlangchain_core.runnablesimportRunnablePassthrough,RunnableParalleldefget_user_age(data):return25# ✅ RunnablePassthrough.assign() —— 自动转换chain1RunnablePassthrough.assign(ageget_user_age)# ✅ RunnableParallel() —— 自动转换chain2RunnableParallel({result:lambdax:x[name].upper()})# ✅ 直接传 lambda —— 自动转换chain3RunnablePassthrough().assign(modifiedlambdax:x[k1]!!!)3.2 需要包的场景管道运算符\|只接受Runnable对象不会自动转换fromlangchain_core.runnablesimportRunnableLambda# ❌ 错误普通函数不能直接接在管道里chain_badstep1|get_user_age|step2# ✅ 正确必须手动包一层 RunnableLambdachain_goodstep1|RunnableLambda(get_user_age)|step2四、四种等价写法实测fromlangchain_core.runnablesimportRunnablePassthrough,RunnableLambdadefget_user_age(data):return25# 写法1直接传函数最简洁推荐r1RunnablePassthrough.assign(ageget_user_age)# 写法2传 lambda也简洁r2RunnablePassthrough.assign(agelambdax:25)# 写法3手动包 RunnableLambda啰嗦但效果一样r3RunnablePassthrough.assign(ageRunnableLambda(get_user_age))# 写法4实例方式调用r4RunnablePassthrough().assign(ageget_user_age)# 测试forrin[r1,r2,r3,r4]:resultr.invoke({name:Alice})print(result)输出{name:Alice,age:25}{name:Alice,age:25}{name:Alice,age:25}{name:Alice,age:25}五、自动转换方法汇总方法/类自动转换函数为 RunnableLambdaRunnablePassthrough.assign()✅ 是RunnableParallel()✅ 是RunnableLambda()构造函数✅ 是当然管道运算符|❌ 否RunnableSequence()❌ 否六、最佳实践建议场景推荐写法原因.assign()里传函数ageget_user_age最简洁可读性最好.assign()里简单逻辑agelambda x: ...无需定义额外函数管道|里传函数RunnableLambda(func)必须手动包否则报错配合RunnableParallelRunnablePassthrough().assign(...)实例方式更自然七、一句话总结.assign()和RunnableParallel是友好的 API看到函数会自动帮你包成RunnableLambda但管道运算符\|是严格的只接受 Runnable 对象不会自动转换。在.assign()里直接写函数或 Lambda 就行别画蛇添足包RunnableLambda。