数据截至 (上游 commit 92c146faa529)
LLM 层:双路径、多provider与容错
30 秒导读: 这一层只干一件事——把一次「调用大模型」的请求,可 靠地打到某个模型上,再把文本、token、成本收回来。它的核心取舍是「快 vs 通用」:默认用原生 OpenAI 客户端(导入快、延迟低),一旦你要用别的 provider(模型名带
/、传 dict 配置、或设了base_url)就切到 LiteLLM(一个库统一 100+ provider)。两条路径外面,再裹上 provider 侦测、错误分类、限速与重试、跨账号失败切换、token 与成本核算这几圈「保命」逻辑。
本章讲这一层内部怎么把请求打稳。至于 Agent 在什么时机、用什么消息来调这一层,属于 01-agent-chat-loop;工具怎么定义和执行属于 02-tools-and-mcp。
1. 这是什么(零基础也能懂)
一句话定义: LLM 层是 PraisonAI 里「模型调用的统一网关」——上层只说「拿这段 prompt 去问模型」,这层负责选哪条路径、怎么重试、怎么算钱。
它解决什么问题。 假设你写了个 agent,今天用 gpt-4o-mini,明天老板说换成 claude,后天要接自建的 Ollama 本地模型,大后天 OpenAI 限流了想自动切到备用 key。如果每处都手写 if provider == ...,代码会烂成一团。这层把这些差异全收进去,让上层永远只写一句「问模型」。
它能做什么(功能清单):
- 两套后端并存:原生 OpenAI SDK(快)+ LiteLLM(通用)。
- 从模型名 自动认出 provider(openai / anthropic / gemini / ollama…),并套上 provider 专属默认值。
- 把 API 报错分类(限流 / 上下文超长 / 认证失败 / 服务过载…),据此决定「重试还是直接抛」。
- 令牌桶限速 + 带抖动的指数退避,避免多 agent 同时把 provider 打爆。
- 一个 provider 挂了,自动换到下一个 auth profile(跨 key / 跨 provider 切换)。
- 数每次调用的 token 用量与美元成本。
用起来什么样。 上层几乎感觉不到这一层的存在——你只是在建 Agent 时给个 llm 参数:
# 示意,非源码
from praisonaiagents import Agent
# 默认路径:走原生 OpenAI 客户端,导入快、延迟低
a1 = Agent(instructions="你是助手", llm="gpt-4o-mini")
# 带 "/" → 切到 LiteLLM,支持任意 provider
a2 = Agent(instructions="你是助手", llm="anthropic/claude-3-5-sonnet")
# 传 dict / 设 base_url → 也走 LiteLLM
a3 = Agent(instructions="你是助手", llm={"model": "gpt-4o-mini", "temperature": 0.2})
一句话直觉。 把这层想成机场的双跑道 + 塔台:绝大多数航班(OpenAI)走主跑道,起降最快;国际航班(其它 provider)走副跑道,程序多但哪都能飞。塔台(侦测 / 限速 / 重试 / 切换)保证不管哪条跑道,飞机都能安全落地。