LangChain系列文章
- LangChain 29 调试Debugging 详细信息verbose
- LangChain 30 ChatGPT LLM将字符串作为输入并返回字符串Chat Model将消息列表作为输入并返回消息
- LangChain 31 模块复用Prompt templates 提示词模板
- LangChain 32 输出解析器Output parsers
- LangChain 33: LangChain表达语言LangChain Expression Language (LCEL)
- LangChain 34: 一站式部署LLMs使用LangServe
- LangChain 35: 安全最佳实践深度防御Security
- LangChain 36 深入理解LangChain 表达式语言优势一 LangChain Expression Language (LCEL)
- LangChain 37 深入理解LangChain 表达式语言二 实现prompt+model+output parser LangChain Expression Language (LCEL)
- LangChain 38 深入理解LangChain 表达式语言三 实现RAG检索增强生成 LangChain Expression Language (LCEL)
- LangChain 39 深入理解LangChain 表达式语言四 为什么要用LCEL LangChain Expression Language (LCEL)
- LangChain 40 实战Langchain访问OpenAI ChatGPT API Account deactivated的另类方法,访问跳板机API
- LangChain 41 深入理解LangChain 表达式语言五 为什么要用LCEL调用大模型LLM LangChain Expression Language (LCEL)
- LangChain 42 深入理解LangChain 表达式语言六 Runtime调用不同大模型LLM LangChain Expression Language (LCEL)
- LangChain 43 深入理解LangChain 表达式语言七 日志和Fallbacks异常备选方案 LangChain Expression Language (LCEL)
- LangChain 44 深入理解LangChain 表达式语言八 Runnable接口输入输出模式 LangChain Expression Language (LCEL)
- LangChain 45 深入理解LangChain 表达式语言九 Runnable 调用、流输出、批量调用、异步处理 LangChain Expression Language (LCEL)
1. 异步流中间步骤
所有可运行的对象也都有一个方法 .astream_log()
,用于流式传输(在发生时)链/序列的所有或部分中间步骤。
这对于向用户显示进度,使用中间结果或调试您的链条非常有用。
您可以流式传输所有步骤(默认)或按名称、标签或元数据包含/排除步骤。
该方法产生 JSONPatch 操作,当按接收顺序应用时,构建出 RunState。
class LogEntry(TypedDict):
id: str
"""ID of the sub-run."""
name: str
"""Name of the object being run."""
type: str
"""Type of the object being run, eg. prompt, chain, llm, etc."""
tags: List[str]
"""List of tags for the run."""
metadata: Dict[str, Any]
"""Key-value pairs of metadata for the run."""
start_time: str
"""ISO-8601 timestamp of when the run started."""
streamed_output_str: List[str]
"""List of LLM tokens streamed by this run, if applicable."""
final_output: Optional[Any]
"""Final output of this run.
Only available after the run has finished successfully."""
end_time: Optional[str]
"""ISO-8601 timestamp of when the run ended.
Only available after the run has finished."""
class RunState(TypedDict):
id: str
"""ID of the run."""
streamed_output: List[Any]
"""List of output chunks streamed by Runnable.stream()"""
final_output: Optional[Any]
"""Final output of the run, usually the result of aggregating (`+`) streamed_output.
Only available after the run has finished successfully."""
logs: Dict[str, LogEntry]
"""Map of run names to sub-runs. If filters were supplied, this list will
contain only the runs that matched the filters."""
2. 流式传输JSONPatch块
这对于在HTTP服务器中流式传输JSONPatch并在客户端上应用操作以重建运行状态非常有用。请参阅LangServe,了解如何更轻松地从任何可运行的代码构建Web服务器的工具。
from langchain.llms import OpenAI
from langchain_core.runnables import RunnablePassthrough
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from dotenv import load_dotenv
load_dotenv()
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
vectorstore = FAISS.from_texts(
["harrison worked at kensho"], embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever()
model = ChatOpenAI(model="gpt-3.5-turbo")
retrieval_chain = (
{
"context": retriever.with_config(run_name="Docs"),
"question": RunnablePassthrough(),
}
| prompt
| model
| StrOutputParser()
)
async def main():
async for chunk in retrieval_chain.astream_log(
"where did harrison work?", include_names=["Docs"]
):
print("-" * 40)
print(chunk)
import asyncio
asyncio.run(main())
----------------------------------------
RunLogPatch({'op': 'replace',
'path': '',
'value': {'final_output': None,
'id': 'e2f2cc72-eb63-4d20-8326-237367482efb',
'logs': {},
'streamed_output': []}})
----------------------------------------
RunLogPatch({'op': 'add',
'path': '/logs/Docs',
'value': {'end_time': None,
'final_output': None,
'id': '8da492cc-4492-4e74-b8b0-9e60e8693390',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:50:13.526',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}})
----------------------------------------
RunLogPatch({'op': 'add',
'path': '/logs/Docs/final_output',
'value': {'documents': [Document(page_content='harrison worked at kensho')]}},
{'op': 'add',
'path': '/logs/Docs/end_time',
'value': '2023-10-19T17:50:13.713'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': ''})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': 'H'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': 'arrison'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': ' worked'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': ' at'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': ' Kens'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': 'ho'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': '.'})
----------------------------------------
RunLogPatch({'op': 'add', 'path': '/streamed_output/-', 'value': ''})
----------------------------------------
RunLogPatch({'op': 'replace',
'path': '/final_output',
'value': {'output': 'Harrison worked at Kensho.'}})
3. 流式传输增量RunState
您可以简单地传递diff=False来获取RunState的增量值。您可以通过更多重复的部分获得更详细的输出。
async for chunk in retrieval_chain.astream_log(
"where did harrison work?", include_names=["Docs"], diff=False
):
print("-" * 70)
print(chunk)
输出
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {},
'streamed_output': []})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': None,
'final_output': None,
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': []})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': []})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['', 'H']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['', 'H', 'arrison']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['', 'H', 'arrison', ' worked']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['', 'H', 'arrison', ' worked', ' at']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['', 'H', 'arrison', ' worked', ' at', ' Kens']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['', 'H', 'arrison', ' worked', ' at', ' Kens', 'ho']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['', 'H', 'arrison', ' worked', ' at', ' Kens', 'ho', '.']})
----------------------------------------------------------------------
RunLog({'final_output': None,
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['',
'H',
'arrison',
' worked',
' at',
' Kens',
'ho',
'.',
'']})
----------------------------------------------------------------------
RunLog({'final_output': {'output': 'Harrison worked at Kensho.'},
'id': 'afe66178-d75f-4c2d-b348-b1d144239cd6',
'logs': {'Docs': {'end_time': '2023-10-19T17:52:15.738',
'final_output': {'documents': [Document(page_content='harrison worked at kensho')]},
'id': '88d51118-5756-4891-89c5-2f6a5e90cc26',
'metadata': {},
'name': 'Docs',
'start_time': '2023-10-19T17:52:15.438',
'streamed_output_str': [],
'tags': ['map:key:context', 'FAISS'],
'type': 'retriever'}},
'streamed_output': ['',
'H',
'arrison',
' worked',
' at',
' Kens',
'ho',
'.',
'']})
代码
https://github.com/zgpeace/pets-name-langchain/tree/develop
参考
https://python.langchain.com/docs/expression_language/why