跳至主要內容
Open In ColabOpen on GitHub

如何將值新增至鏈的狀態

另一種傳遞資料通過鏈步驟的方式是保持鏈狀態的目前值不變,同時在給定的鍵下分配新值。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})
{'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)
{'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 的輸出會在可用時立即以區塊串流傳入。

後續步驟

現在您已了解如何傳遞資料通過您的鏈,以協助格式化流經鏈的資料。

若要了解更多資訊,請參閱本節中關於可執行物件的其他操作指南。


此頁面是否實用?