当前位置:   article > 正文

LangChain实战技巧之一:传递参数_typeerror: expected a runnable, callable or dict.i

typeerror: expected a runnable, callable or dict.instead got an unsupported

在介绍如何使用LangChain构造Prompt

AI菜鸟向前飞 — LangChain系列之一

现在大家学会了用invoke  因为它也是Runnable对象所以可以用...

  1. prompt = PromptTemplate.from_template("{name}是谁呀")
  2. prompt.invoke({"name": "Song榆钱儿"})
  3. # Chain乱入了:)
  4. my_chain = prompt
  5. my_chain.invoke({"name": "Song榆钱儿"})

输出结果

  1. 'Song榆钱儿是谁呀'
  2. 'Song榆钱儿是谁呀'

大家有是否想过可以通过Chain把值传进去?当然也可以,不过...我们先看代码

  1. prompt = PromptTemplate.from_template("{name}是谁呀")
  2. my_chain = {"name": "Song榆钱儿"} | prompt
  3. print(my_chain.invoke())

输出结果

  1. raise TypeError(
  2. TypeError: Expected a Runnable, callable or dict.Instead got an unsupported type: <class 'str'>

如何解决? —— 使用itemgetter

https://docs.python.org/3/library/operator.html 

简单来说,itemgetter("xxxx")返回的并不是一个具体的值,而是一个函数(callable),所以可以用它 让我们再看看:

  1. prompt = PromptTemplate.from_template("{name}是谁呀")
  2. my_chain = {"name": itemgetter("name")} | prompt
  3. my_chain.invoke({"name": "Song榆钱儿"}

输出结果

'Song榆钱儿是谁呀'

当传入多个值时:

  1. prompt = PromptTemplate.from_template("{name1}是谁呀, {name2}是谁呀, {name3}是谁呀")
  2. my_chain = {"name1": itemgetter("name1"), "name2": itemgetter("name2"), "name3": itemgetter("name3")} | prompt
  3. my_chain.invoke({"name1": "Song榆钱儿", "name2": "他小弟们", "name3": "他小妹们"}

输出结果

'Song榆钱儿是谁呀, 他小弟们是谁呀, 他小妹们是谁呀'

但是,如果我们对于函数的传值,也可以这么用么?让我们来试试看 我们先来预习回顾我的这篇文章

AI菜鸟向前飞 — LangChain系列之七 - 深入浅出LCEL与Chain(中篇)

  1. def hello(name: str) -> str:
  2. return f"hello,{name}。"
  3. …………………………(看我上面的链接文章)……………………
  4. my_chain = {"name": itemgetter("name")} | hello | welcome | attach_date

输出结果

欢迎来到我的公众号, hello,{'name': 'Song榆钱儿'}。现在是2024-05-15

看来也行,不过把整个都传过来了,很怪,有木有 :(

如果函数有多个值呢?是不是也可以用itemgetter?让我们拭目以待吧

  1. def hello(name1: str, name2: str, name3: str) -> str:
  2. return f"hello,{name1}是谁呀, {name2}是谁呀, {name3}是谁呀。"
  3. …………………………(我上面的链接文章)……………………
  4. my_chain = {"name1": itemgetter("name1"), "name2": itemgetter("name2"), "name3": itemgetter("name3")} | hello | welcome | attach_date
  5. my_chain.invoke({"name1": "Song榆钱儿", "name2": "小弟们", "name3": "小妹们"})

输出结果

  1. in call_func_with_variable_args
  2. return func(input, **kwargs) # type: ignore[call-arg]
  3. ^^^^^^^^^^^^^^^^^^^^^
  4. TypeError: hello() missing 2 required positional arguments: 'name2' and 'name3'

那如果为"函数"(Runnable)传多个值,该怎么办?“聪明”的小伙伴可能会用这种方式来解决,但… 也行。。

  1. def hello(name_dict: str) -> str:
  2. return f"hello,{name_dict.get("name1", "")}是谁呀, {name_dict.get("name2", "")}是谁呀,{name_dict.get("name3", "")}是谁呀。"
  3. …………………………(我上面的链接文章)……………………
  4. my_chain.invoke({"name1": "Song榆钱儿", "name2": "小弟们", "name3": "小妹们"})

输出结果

欢迎来到我的公众号, hello,Song榆钱儿是谁呀, 小弟们是谁呀,小妹们是谁呀。现在是2024-05-15

PS:为啥说但是,因为把原函数都破坏掉了……而且用的是Python程序的方式,让我们看看如何用LangChain自己的办法去解决

解法:先bind再invoke

  1. # 先bind
  2. hello = hello.bind(name2="小弟们", name3="小妹们")
  3. my_chain = hello | welcome | attach_date
  4. # 再invoke
  5. my_chain.invoke({"name1": "Song榆钱儿", "name2": "小弟们", "name3": "小妹们"})

输出结果

欢迎来到我的公众号, hello,Song榆钱儿是谁呀, 小弟们是谁呀,小妹们是谁呀。现在是2024-05-15
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/904682
推荐阅读
相关标签
  

闽ICP备14008679号