LangChain 46 深入理解LangChain 表达式语言十 Runnable 调用中间状态调试日志 LangChain Expression Language (LCEL)

LangChain系列文章

  1. LangChain 29 调试Debugging 详细信息verbose
  2. LangChain 30 ChatGPT LLM将字符串作为输入并返回字符串Chat Model将消息列表作为输入并返回消息
  3. LangChain 31 模块复用Prompt templates 提示词模板
  4. LangChain 32 输出解析器Output parsers
  5. LangChain 33: LangChain表达语言LangChain Expression Language (LCEL)
  6. LangChain 34: 一站式部署LLMs使用LangServe
  7. LangChain 35: 安全最佳实践深度防御Security
  8. LangChain 36 深入理解LangChain 表达式语言优势一 LangChain Expression Language (LCEL)
  9. LangChain 37 深入理解LangChain 表达式语言二 实现prompt+model+output parser LangChain Expression Language (LCEL)
  10. LangChain 38 深入理解LangChain 表达式语言三 实现RAG检索增强生成 LangChain Expression Language (LCEL)
  11. LangChain 39 深入理解LangChain 表达式语言四 为什么要用LCEL LangChain Expression Language (LCEL)
  12. LangChain 40 实战Langchain访问OpenAI ChatGPT API Account deactivated的另类方法,访问跳板机API
  13. LangChain 41 深入理解LangChain 表达式语言五 为什么要用LCEL调用大模型LLM LangChain Expression Language (LCEL)
  14. LangChain 42 深入理解LangChain 表达式语言六 Runtime调用不同大模型LLM LangChain Expression Language (LCEL)
  15. LangChain 43 深入理解LangChain 表达式语言七 日志和Fallbacks异常备选方案 LangChain Expression Language (LCEL)
  16. LangChain 44 深入理解LangChain 表达式语言八 Runnable接口输入输出模式 LangChain Expression Language (LCEL)
  17. 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值