在现代 Python 开发中,异步编程变得越来越流行,而异步环境中的回调处理是实现高效非阻塞操作的关键技术。在本文中,我们将详细介绍如何在异步环境中使用自定义回调处理程序,并给出实际的代码示例。
技术背景介绍
回调函数是程序在特定事件发生时执行的一段代码,通过在特定操作的开始和结束时调用这些函数,我们可以对异步操作进行监控和控制。在异步环境中,使用异步回调处理程序可以避免阻塞事件循环,提高程序的响应性。
核心原理解析
在异步环境中使用回调处理程序需要注意线程安全性和事件循环的非阻塞性。通过扩展 AsyncCallbackHandler
,我们可以创建自定义的异步处理程序,以确保操作在异步上下文中正确执行。
代码实现演示
下面我们展示了一个使用异步回调处理程序的代码示例,该示例演示了如何使用 LangChain 库的异步 API 执行回调操作。
import asyncio
from typing import Any, Dict, List
from langchain_anthropic import ChatAnthropic
from langchain_core.callbacks import AsyncCallbackHandler, BaseCallbackHandler
from langchain_core.messages import HumanMessage
from langchain_core.outputs import LLMResult
# 自定义同步回调处理程序,注意线程池执行器中的调用
class MyCustomSyncHandler(BaseCallbackHandler):
def on_llm_new_token(self, token: str, **kwargs) -> None:
print(f"Sync handler being called in a `thread_pool_executor`: token: {token}")
# 自定义异步回调处理程序
class MyCustomAsyncHandler(AsyncCallbackHandler):
"""Async callback handler that can be used to handle callbacks from langchain."""
async def on_llm_start(
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
) -> None:
"""Run when chain starts running."""
print("zzzz....")
await asyncio.sleep(0.3)
class_name = serialized["name"]
print("Hi! I just woke up. Your llm is starting")
async def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:
"""Run when chain ends running."""
print("zzzz....")
await asyncio.sleep(0.3)
print("Hi! I just woke up. Your llm is ending")
# 创建聊天模型并添加回调处理程序
chat = ChatAnthropic(
model="claude-3-sonnet-20240229",
max_tokens=25,
streaming=True,
callbacks=[MyCustomSyncHandler(), MyCustomAsyncHandler()],
)
# 异步生成文本
await chat.agenerate([[HumanMessage(content="Tell me a joke")]])
应用场景分析
异步回调处理程序在需要处理大量异步事件、提高程序响应速度的场景中尤为有用。例如,在实时聊天应用、数据流处理系统和在线游戏中,异步回调可以有效改善用户体验和系统性能。
实践建议
- 确保回调处理程序是线程安全的,尤其是在涉及到共享数据的情况下。
- 在异步操作中使用
AsyncCallbackHandler
代替同步处理程序,以减少阻塞事件循环的风险。 - 在 Python 3.11+ 环境中使用异步编程,以利用其对异步操作的更好支持和优化。
如果遇到问题欢迎在评论区交流。
—END—