# 在异步环境中使用回调:实用指南
## 引言
在现代应用程序开发中,异步编程已经成为处理高并发任务的标准工具。在异步环境中,使用回调是一种常见的实践,可以帮助我们在异步操作完成后执行某些任务。本篇文章将深入探讨如何在异步环境中使用回调,包括实现自定义的回调处理程序,并解决常见的挑战。
## 主要内容
### 什么是回调?
回调是一种函数,通常在特定事件发生或操作完成时调用。它允许程序员在不阻塞程序主线程的情况下进行异步处理。
### 自定义回调处理程序
在某些情况下,您可能需要创建自己的回调处理程序,以处理异步API的不同事件。使用专门设计的`AsyncCallbackHandler`可以避免阻塞事件循环。
### 为什么选择异步回调处理程序?
虽然您可以在异步方法中使用同步回调处理程序,但这可能导致在后台线程中调用回调,这要求回调处理程序是线程安全的。因此,使用异步回调处理程序是更安全和高效的选择。
### Python版本注意事项
如果您使用的是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)
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")
# 使用API代理服务提高访问稳定性
chat = ChatAnthropic(
model="claude-3-sonnet-20240229",
max_tokens=25,
streaming=True,
callbacks=[MyCustomSyncHandler(), MyCustomAsyncHandler()],
)
await chat.agenerate([[HumanMessage(content="Tell me a joke")]])
常见问题和解决方案
- 线程安全问题:在使用同步回调处理程序时,确保它们是线程安全的,以避免在多线程环境中出现竞争状态。
- 未传播的回调:在Python 3.10及以下版本中,确保正确传播回调,以便它们能够在调用子可运行对象时生效。
总结和进一步学习资源
使用异步回调处理程序可以避免阻塞事件循环,并提高程序的并发性能。为了深入学习有关回调和异步编程的内容,推荐参考以下资源:
参考资料
- Langchain官方文档
- Python异步编程实践
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---