设置如下:
我的矢量存储(chromadb)有两个集合,一个包含关键字,另一个包含用于检索的实际文档。两个集合都将页码作为元数据,这就是它们相互关联的方式。例如,在关键字集合中我会有一个像这样的文档:
Document(page_content="SomeKeyword", metadata={'pages': '23, 29'})
在文件收集中我会:
Document(page_content="Lorem ipsum etc etc etc...", metadata={'page': 23})
然后我的链基本上是这样的:首先我们搜索关键字存储并返回匹配项。然后我们将此文档输入一个函数,该函数返回相关页码列表(a
list[int]
)。然后我们希望通过相关页码列表过滤文档存储上的搜索,以便提高准确性和速度。
如果我手动构建这个链(即没有 LCEL),我可以很好地做到这一点,但是如果我想利用 LCEL,我找不到在链上动态设置此过滤器的方法。例如:
user_input = {"question": "What is SomeKeyword?"}
keyword_retrieval = RunnableParallel(
keywords=itemgetter("question") | keywords.as_retriever(
search_type="similarity_score_threshold",
search_kwargs={"score_threshold": 0.4}),
question=itemgetter("question"))
page_nums = RunnableParallel(
page_nums=itemgetter("keywords") | RunnableLambda(get_page_nums),
question=itemgetter("question"))
docs_retrieval = RunnableParallel(
context=itemgetter("question") | docs.as_retriever(
search_kwargs={"filter": {"page": {"$in": itemgetter("page_nums")}}}),
question=itemgetter("question"))
chain = keyword_retrieval | page_nums | docs_retrieval | prompt | llm
以上失败
.venv\Lib\site-packages\chromadb\api\types.py", line 364, in validate_where
raise ValueError(
ValueError: Expected operand value to be an list for operator $in, got operator.itemgetter('page_nums')
我有点明白为什么会失败,但我不知道如何解决它。有没有办法根据LCEL中链上一步的输出动态设置search_kwargs?
对于将来遇到类似问题的任何人,我已设法使其能够解决此问题(但不清楚这是否是最佳解决方案):
docs_retrieval = RunnableParallel( context=lambda inp: itemgetter("问题") | docs.as_retriever(search_kwargs={"filter": {"page": {"$in": inp["page_nums"]}}}), 问题=itemgetter(“问题”), )