掌握异步环境中的回调技术:提高你的程序效率

55 阅读3分钟
# 掌握异步环境中的回调技术:提高你的程序效率

## 引言

在现代编程中,异步编程变得越来越重要,特别是在处理需要长时间运行的任务时,如网络请求或文件I/O操作。使用异步编程可以防止主线程被阻塞,从而提高应用程序的响应性。本篇文章将介绍如何在异步环境中使用和扩展自定义回调,帮助你在需要高效处理异步事件时充分利用回调技术。

## 主要内容

### 什么是回调

回调是一种编程模式,你可以在某一个事件发生时调用预先定义的函数。它在异步编程中尤其常见,因为它允许你处理事件完成后的结果。

### 自定义回调处理器

在Python中,通过继承一个基础回调处理器类,你可以创建自己的回调处理器。对于异步操作,我们建议扩展`AsyncCallbackHandler`以避免阻塞事件循环。

### 使用异步和同步回调处理器

在异步环境中,同时使用同步和异步回调处理器是可能的。但是,如果你在异步方法中使用同步回调处理器,则它将在`run_in_executor`中被调用。如果你的回调处理器不是线程安全的,这可能会导致问题。

### 插入和传递回调

在Python 3.10及以下版本中,当你在一个异步方法内调用其他可运行对象时,需要记住传递配置或回调,否则这些回调不会被传播到被调用的子可运行对象中。

## 代码示例

下面是一个完整的代码示例,展示了如何实现和使用自定义回调处理器:

```python
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)
        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()],
)

# 使用API代理服务提高访问稳定性
await chat.agenerate([[HumanMessage(content="Tell me a joke")]])

常见问题和解决方案

  • 线程安全问题: 在多线程环境中使用同步回调时,请确保你的回调处理器是线程安全的。可以使用线程锁或专用的线程安全数据结构。
  • 回调未传播: 如果在Python 3.10及以下版本中调用其他异步可运行对象时未传递回调,请确保正确传递配置或回调。

总结和进一步学习资源

异步回调可以大大提升你的应用程序的效率和响应性。通过实现和使用自定义回调处理器,你可以更好地管理异步事件。在探索和实践过程中,你可能会遇到各种挑战和细节,可以查阅以下资源以获取更深入的理解。

参考资料

  1. LangChain Anthropic API 文档
  2. Python 官方文档

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

---END---