
本教程旨在解决Chainlit应用中与LangChain集成时常见的`UserSession.set() missing 1 required positional argument: 'value'`错误。文章将深入解释`cl.user_session.set()`用于存储数据与`cl.user_session.get()`用于检索数据之间的关键区别,并提供一个直接的解决方案,确保您的LangChain链在整个聊天会话中被正确访问和复用。
在构建基于Chainlit和LangChain的交互式AI应用时,通常需要在用户会话开始时(即@cl.on_chat_start装饰器下的函数)初始化一些计算成本较高的对象,例如大型语言模型(LLM)、嵌入模型、向量存储或复杂的LangChain链。这些对象被初始化后,需要被存储起来,以便在用户后续的每次消息交互中(即@cl.on_message装饰器下的函数)复用,从而避免重复加载和初始化,提高效率。
Chainlit提供了cl.user_session这一机制来实现会话级别的状态管理。然而,一个常见的错误是混淆了cl.user_session的存储(set)和检索(get)操作,导致在尝试获取已存储对象时,错误地调用了set()方法而未提供完整的参数,进而引发UserSession.set() missing 1 required positional argument: 'value'这样的错误信息。
在原始代码中,用户还曾遇到与context变量相关的ValidationError。虽然LangChain的RetrievalQA链(特别是chain_type="stuff")确实需要context和question作为其内部提示的输入变量,但上述UserSession.set()错误则指向了Chainlit会话管理中更根本的操作问题,即如何正确地在不同回调函数之间传递和访问已初始化的chain对象。
cl.user_session是Chainlit为每个用户会话提供的专属键值存储空间。理解set()和get()的明确用途是解决此类问题的关键:
让我们分析一下提供的代码片段中@cl.on_chat_start和@cl.on_message函数的相关部分:
# ... (qa_bot 函数及其他辅助函数) ...
@cl.on_chat_start
async def start():
chain = qa_bot() # 在会话开始时初始化 LangChain 链
msg = cl.Message(content="Starting the bot......")
await msg.send()
msg.content = "Hi, Welcome to the Medical Bot. What is your query?"
await msg.update()
cl.user_session.set('chain', chain) # 正确地将初始化的 chain 对象存储到会话中
@cl.on_message
async def main(message):
# 错误之处:试图通过调用 set() 方法来检索 chain 对象,但未提供 value 参数
chain = cl.user_session.set("chain")
cb = cl.AsyncLangchainCallbackHandler(
stream_final_answer = True, answer_prefix_tokens = ["FINAL", "ANSWER"]
)
cb.answer_reached = True
# 原始代码中使用 message 对象,但 LangChain 链通常期望字符串输入
res = await chain.acall(message, callbacks = [cb])
answer = res["result"]
sources = res["source_documents"]
if sources:
answer += f"\nSources:" + str(sources)
else:
answer += f"\nNo Sources Found"
await cl.Message(content = answer).send()在@cl.on_chat_start函数中,cl.user_session.set('chain', chain)是正确的用法,它将qa_bot()返回的chain对象以键'chain'存储起来。
然而,在@cl.on_message函数中,chain = cl.user_session.set("chain")这行代码是错误的。这里的意图显然是想检索之前存储的chain对象,但却错误地调用了set()方法,并且只提供了一个key参数,而缺少了必需的value参数。这就是导致UserSession.set() missing 1 required positional argument: 'value'错误的原因。
此外,在chain.acall(message, callbacks = [cb])这一行,LangChain链的acall方法通常期望接收一个字符串作为查询输入,而不是整个message对象。正确的做法是访问message.content来获取用户输入的文本。
要正确地从用户会话中检索在@cl.on_chat_start中存储的chain对象,只需将set()方法替换为get()方法即可。同时,修正acall方法的输入参数。
修正后的代码片段:
# ... (qa_bot 函数及其他辅助函数保持不变) ...
@cl.on_chat_start
async def start():
chain = qa_bot() # 在会话开始时初始化 LangChain 链
msg = cl.Message(content="Starting the bot......")
await msg.send()
msg.content = "Hi, Welcome to the Medical Bot. What is your query?"
await msg.update()
cl.user_session.set('chain', chain) # 正确地将初始化的 chain 对象存储到会话中
@cl.on_message
async def main(message: cl.Message): # 明确message的类型提示
# 正确之处:使用 get() 方法检索已存储的 chain 对象
chain = cl.user_session.get("chain")
# 确保 chain 对象已成功检索
if chain is None:
await cl.Message(content="Bot not initialized. Please restart the chat.").send()
return
cb = cl.AsyncLangchainCallbackHandler(
stream_final_answer = True, answer_prefix_tokens = ["FINAL", "ANSWER"]
)
cb.answer_reached = True
# 修正:将 message.content 作为查询输入传递给 chain.acall
res = await chain.acall(message.content, callbacks = [cb])
answer = res["result"]
sources = res["source_documents"]
if sources:
answer += f"\nSources:" + str(sources)
else:
answer += f"\nNo Sources Found"
await cl.Message(content = answer).send()通过将chain = cl.user_session.set("chain")修改为chain = cl.user_session.get("chain"),我们确保了在@cl.on_message函数中能够正确地获取到在会话开始时创建的LangChain链实例,从而避免了UserSession.set()的错误。同时,将message替换为message.content,确保了向LangChain链传递的是正确的字符串查询内容。
为了构建健壮且高效的Chainlit应用,请遵循以下会话管理最佳实践:
正确管理cl.user_session对于构建状态化且高效的Chainlit应用至关重要。通过理解cl.user_session.set()用于存储和cl.user_session.get()用于检索的明确职责,开发者可以避免常见的错误,并确保其LangChain组件能够无缝集成并在用户交互中被有效复用。这个简单的修正不仅解决了特定的UserSession.set()错误,也显著提升了Chainlit机器人的健壮性和功能性。
以上就是正确管理Chainlit用户会话:解决UserSession.set()错误的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号