asyncio.run()不能在已运行事件循环中调用,因它强制要求顶层干净事件循环;在Jupyter、FastAPI等环境应改用await或create_task()。

asyncio.run() 不能在已运行的事件循环中调用
直接在 Jupyter、IPython 或某些 Web 框架(如 FastAPI 的依赖函数)里写 asyncio.run(main()),会报 RuntimeError: asyncio.run() cannot be called from a running event loop。这是因为这些环境本身已在运行一个事件循环。
实操建议:
- 在普通 Python 脚本(.py 文件)中,用
asyncio.run()是安全且推荐的入口方式 - 在 Jupyter 中,改用
await main()(确保单元格是 async 模式,或用nest_asyncio.apply()补丁) - 在 FastAPI 里,直接把协程函数作为
async def endpoint()的返回值,由框架调度,别手动run() - 若需复用已有事件循环(比如集成进旧系统),用
asyncio.create_task()或loop.create_task(),而非run()
requests 不支持 await,必须换 aiohttp 或 httpx
写 await requests.post(...) 会直接报 TypeError: object Response can't be used in 'await' expression —— 因为 requests 是同步阻塞库,压根不是协程。
实操建议:
- 首选
httpx.AsyncClient:API 与requests高度兼容,支持async with和await client.post(),对 JSON/headers 处理更自然 - 次选
aiohttp.ClientSession:性能略高,但 API 更底层,需手动await resp.json(),且 session 必须跨请求复用(不能每次 new 一个) - 绝对不要在协程里用
time.sleep(),改用await asyncio.sleep();同理,避免json.loads()大响应体时阻塞,可考虑流式解析
并发数过高触发 API 限流或连接错误
一次性发 100 个 httpx.AsyncClient 请求,很可能收到 503 Service Unavailable、429 Too Many Requests,甚至 OSError: [Errno 24] Too many open files(Linux 默认限制约 1024)。
实操建议:
- 用
asyncio.Semaphore(n)控制并发上限,例如限制同时最多 10 个请求:sem = asyncio.Semaphore(10) async def call_llm(prompt): async with sem: async with client.post(...) as resp: return await resp.json() - 给每个请求加随机 jitter 延迟(如
await asyncio.sleep(random.uniform(0.1, 0.5))),缓解服务端瞬时压力 - 检查目标 API 是否支持批量请求(如 OpenAI 的
/v1/chat/completions支持messages数组),比发多个单条请求更高效 - 注意
httpx.AsyncClient的limits参数(如max_connections=100),避免默认连接池过小成为瓶颈
异常未捕获导致整个并发任务静默失败
协程里抛出未处理异常(如网络超时、JSON 解析失败、API 返回非 2xx 状态码),不会中断其他任务,但会令 asyncio.gather() 抛出 ExceptionGroup(Python 3.11+)或第一个异常,后续结果全丢。
实操建议:
- 对每个请求做独立 try/except,返回结构化结果(含
success、error、response字段),而不是让异常冒泡 - 用
asyncio.gather(*tasks, return_exceptions=True),这样即使某个请求失败,也能拿到所有结果(失败项是 Exception 实例) - 特别注意超时:给
httpx.AsyncClient设置timeout=httpx.Timeout(30.0),否则 DNS 卡住或服务无响应可能挂起整个任务数分钟 - LLM API 响应体里常有
"error"字段(如{"error": {"message": "model not found"}}),这不算 HTTP 错误状态码,需手动检查响应内容
真正麻烦的不是并发本身,而是每个请求背后都藏着网络不确定性、服务端策略差异和模型响应格式漂移——得把错误当常态来设计,而不是等它崩了再看日志。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











