如何將值新增至鏈的狀態
先決條件
本指南假設您熟悉以下概念
另一種傳遞資料通過鏈步驟的方式是保持鏈狀態的目前值不變,同時在給定的鍵下分配新值。RunnablePassthrough.assign()
靜態方法會取得輸入值,並新增傳遞至 assign 函數的額外引數。
這在常見的 LangChain 運算式語言 模式中很有用,該模式會累加建立字典以用作後續步驟的輸入。
以下範例
%pip install --upgrade --quiet langchain langchain-openai
import os
from getpass import getpass
if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass()
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
runnable = RunnableParallel(
extra=RunnablePassthrough.assign(mult=lambda x: x["num"] * 3),
modified=lambda x: x["num"] + 1,
)
runnable.invoke({"num": 1})
API 參考:RunnableParallel | RunnablePassthrough
{'extra': {'num': 1, 'mult': 3}, 'modified': 2}
讓我們分解一下這裡發生的事情。
- 鏈的輸入是
{"num": 1}
。這會傳遞到RunnableParallel
,後者會使用該輸入平行調用傳遞給它的可執行物件。 - 會調用
extra
鍵下的值。RunnablePassthrough.assign()
保留輸入字典 ({"num": 1}
) 中的原始鍵,並指派一個名為mult
的新鍵。值為lambda x: x["num"] * 3)
,即3
。因此,結果為{"num": 1, "mult": 3}
。 {"num": 1, "mult": 3}
會傳回至RunnableParallel
呼叫,並設定為鍵extra
的值。- 同時,會呼叫
modified
鍵。結果為2
,因為 lambda 從其輸入中擷取名為"num"
的鍵並加一。
因此,結果為 {'extra': {'num': 1, 'mult': 3}, 'modified': 2}
。
串流
此方法的一個便利功能是,它允許值在可用時立即傳遞。為了展示這一點,我們將使用 RunnablePassthrough.assign()
立即傳回檢索鏈中的來源文件
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
vectorstore = FAISS.from_texts(
["harrison worked at kensho"], embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever()
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()
generation_chain = prompt | model | StrOutputParser()
retrieval_chain = {
"context": retriever,
"question": RunnablePassthrough(),
} | RunnablePassthrough.assign(output=generation_chain)
stream = retrieval_chain.stream("where did harrison work?")
for chunk in stream:
print(chunk)
API 參考:FAISS | StrOutputParser | ChatPromptTemplate | RunnablePassthrough | ChatOpenAI | OpenAIEmbeddings
{'question': 'where did harrison work?'}
{'context': [Document(page_content='harrison worked at kensho')]}
{'output': ''}
{'output': 'H'}
{'output': 'arrison'}
{'output': ' worked'}
{'output': ' at'}
{'output': ' Kens'}
{'output': 'ho'}
{'output': '.'}
{'output': ''}
我們可以看見第一個區塊包含原始的 "question"
,因為它是立即可用的。第二個區塊包含 "context"
,因為檢索器第二個完成。最後,來自 generation_chain
的輸出會在可用時立即以區塊串流傳入。
後續步驟
現在您已了解如何傳遞資料通過您的鏈,以協助格式化流經鏈的資料。
若要了解更多資訊,請參閱本節中關於可執行物件的其他操作指南。