Purrcept LiteLLM
purrcept_litellm 是 purrcept_core 的 LiteLLM Provider 插件。它实现
ModelBackend 协议,把 Core 的统一模型请求映射到 LiteLLM Chat Completions,并将
Provider 响应、工具调用、流式增量和错误重新归一化为 Core 类型。
当前版本:0.1.3,对应 purrcept_core >=0.5.1,<0.6.0、litellm >=1.100.0,<2。
安装
pip install purrcept_litellm
在本仓库开发:
uv sync
最小用法
LiteLLM 使用带 Provider 前缀的模型名,例如 openai/gpt-4o-mini、
anthropic/claude-sonnet-4-5。推荐让 LiteLLM 从对应 Provider 的标准环境变量读取
凭据:
$env:OPENAI_API_KEY = "..."
$env:PURRCEPT_LITELLM_MODEL = "openai/gpt-4o-mini"
uv run python examples/01_chat.py
也可以显式传入凭据或接入 LiteLLM Proxy / OpenAI-compatible 服务:
import os
from purrcept_core import AgentDriver, AgentFlow, InlineExecutor
from purrcept_core.models import Conversation, Model
from purrcept_litellm import LiteLLMBackend
def chat(conversation: Conversation) -> AgentFlow[str]:
result = yield from conversation.ask("你好,请简短介绍自己。")
return result.text
async def main() -> None:
backend = LiteLLMBackend(
api_key=os.environ["LLM_API_KEY"],
api_base="https://llm.example.com/v1",
timeout=60,
)
conversation = Model(backend, "openai/my-model").conversation(
instructions="你是一名简洁、可靠的助手。",
)
answer = await AgentDriver(InlineExecutor()).run(
chat(conversation),
host=None,
)
print(answer)
请求默认走流式 Chat Completions,避免长生成在网关空闲超时。Generate 会依次产生
ModelStreamStarted、TextDelta / ToolCallDelta、UsageUpdate 和
ModelStreamCompleted。即使调用方不提供 emit,Adapter 仍会消费流并返回组装后的
ModelResponse。
完整的自动工具循环见 examples/02_tool_loop.py。
配置边界
运行时拥有后端和凭据:
backend = LiteLLMBackend(
api_key="...",
api_base="https://...",
api_version="...",
timeout=60,
default_options={
"drop_params": True,
"num_retries": 2,
},
)
一次请求的 LiteLLM 特有选项必须放在唯一命名空间中:
conversation = model.conversation(
provider_options={
"purrcept_litellm": {
"reasoning_effort": "medium",
"drop_params": True,
}
}
)
model、messages、stream、stream_options、tools、api_key、
api_base、api_version、callback(s)、success_callback 和
failure_callback 是保留字段,不能由请求级选项覆盖。凭据只应进入后端配置或 Provider
环境变量,不应写进对话状态。
OpenTelemetry 可观测性
OpenTelemetry 是可选依赖:
pip install "purrcept_litellm[otel]"
下面的 callback 使用 LiteLLM 自带的 OpenTelemetry 集成,但拥有私有
TracerProvider,并且只通过单次请求的 success/failure callback 参数执行。它不会写入
LiteLLM 或 OpenTelemetry 的进程全局 callback/provider:
from purrcept_litellm import (
LiteLLMBackend,
LiteLLMOpenTelemetryConfig,
create_opentelemetry_callback,
)
otel = create_opentelemetry_callback(
LiteLLMOpenTelemetryConfig(
exporter="otlp_http",
endpoint="http://127.0.0.1:4318/v1/traces",
service_name="purrcept-engine",
environment="development",
capture_message_content="SPAN_ONLY",
)
)
backend = LiteLLMBackend(callbacks=(otel,))
# Runtime 停止接收新请求并等待在途请求结束后:
otel.force_flush()
otel.shutdown()
NO_CONTENT 是默认值,只记录模型、耗时、token、状态和错误等运行信息。
SPAN_ONLY 会额外把真实请求提示词和模型返回写入 span 属性;它可能包含个人信息和密钥
片段,只应发送到可信的本地或受控 OTLP Collector。headers 使用 LiteLLM/OTLP 的字符串
格式,并会从配置对象的 repr 中隐藏。
每个主请求 span 同时带有 OpenInference 的 LLM 分类。支持 OpenInference 的界面(例如
Phoenix)可以按 System、User、Assistant 和 Tool 展开完整消息,并用最后一条输入和首个
模型结果填充紧凑的 Input/Output 摘要。工具声明以标准 llm.tools.*.tool.json_schema
记录,因此也可以进入 Phoenix Span Replay。完整消息仍只由 LiteLLM 的 gen_ai.* 属性
承载;Adapter 不会再镜像整段消息序列,但 Input 摘要会包含最后一条消息的完整 content。
NO_CONTENT 只保留 LLM 分类,不会通过这些补充字段泄露提示词、返回或工具 schema。
使用默认 completion 时,Backend 会在返回或抛错前等待本次 request-local callback
完成,因此 Terminal 这类短生命周期事件循环不会在关闭时取消尚未记录的 span。HTTP
exporter 仍由 BatchSpanProcessor 异步发送;Runtime 关闭阶段负责最终的
force_flush() 和 shutdown()。
映射范围
| Core | LiteLLM |
|---|---|
SystemInstruction |
前置 system message |
Message / TextBlock |
chat message / text content |
ImageUrl / ImageBytes |
image_url / data URI |
ToolSpec |
OpenAI-compatible function tool |
ToolCallBlock / ToolResultBlock |
assistant tool call / tool message |
ModelSettings |
temperature、max tokens、stop、tool choice、parallel calls |
TokenUsage |
prompt、completion、cache、reasoning tokens |
ModelStreamEvent |
LiteLLM chunk lifecycle |
| LiteLLM exceptions | Core 的认证、限流、上下文、临时、不可用、请求错误 |
未知但可 JSON 化的 Provider 字段会保留在 ModelResponse.provider_metadata,不会污染
Core 的稳定协议。
Prompt control、缓存与 continuation
- Core 已编译好的 reminder 一律作为
usermessage 发送,不进入system。插件不重新 解释 scope、priority 或 replacement;生命周期仍由Conversation/PromptCompiler管理。只有SystemInstruction使用system。 INSTRUCTIONSplacement 仍插在对话历史之前,但角色是user。TAIL/AUTO跟在 历史之后。相对顺序保持 Core 编译结果。cache="auto"(Adapter 默认,等同prefer)与cache="explicit"会在稳定 instruction、最后一个 tool、以及不断增长的对话历史上添加 LiteLLMcache_control提示。Provider 是否支持和如何计费由 Provider 决定。- reminder(含
INSTRUCTIONS前置与TAIL/AUTO尾部)从不打显式缓存标记。它们是 请求局部、常常易变的控制文本;标记它们只会制造几乎不会命中的 cache write。 cache="disabled"不添加任何cache_control。- strict cache 默认拒绝。只有确认目标 Provider 兼容后,才设置
allow_strict_prompt_cache=True。 - LiteLLM Chat Completions 没有统一、可靠的服务器 continuation 句柄,因此
ModelContinuation不会默认发给 Provider。推荐使用 Core 默认的continuation_policy="client_managed",由本地规范历史重建下一次请求。这也确保已过期 reminder 不会因 Provider 保存了旧状态而泄漏到后续轮次。 - 自定义 LiteLLM Provider 若在
provider_specific_fields.purrcept_continuation返回{provider, data},插件会将其恢复为 Core 的不透明 continuation,供显式策略使用。
真实 Provider 验证
默认测试完全离线。启用真实流式调用:
$env:PURRCEPT_LITELLM_RUN_INTEGRATION = "1"
$env:PURRCEPT_LITELLM_MODEL = "openai/gpt-4o-mini"
$env:OPENAI_API_KEY = "..."
uv run pytest tests/test_real_integration.py -m integration -q
若使用统一代理,可改用 PURRCEPT_LITELLM_API_KEY 和
PURRCEPT_LITELLM_API_BASE。
完整质量门:
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv run pytest --cov=purrcept_litellm --cov-branch
uv run python -m build
设计原则
purrcept_core 只定义 Provider 无关协议和 Agent 语义;本包只承担 LiteLLM
传输适配。具体模型凭据、网络客户端生命周期和部署策略归 Runtime 所有。这样 Core
不会依赖任何厂商 SDK,其他 Provider 也可以继续以独立 Python 插件实现。
工具结果中的图片
从 0.1.2 起,Core ToolResultBlock 中的图片在 Chat Completions 传输时映射到带
工具调用 ID 说明的 user 视觉消息。原始工具消息只保留文本;同一批工具回执全部发出后
才插入图片,随后再发送后续历史与尾部 Reminder。这样兼容只允许文本 tool 内容的接口,
同时保留 Core 历史中的真实图像块、错误标记和调用身份。
0.1.3 将 LiteLLM 最低版本提高到 1.100.0,采用其 DeepSeek 视觉修复
(上游 #38397)。旧版 DeepSeek 适配器会将
多模态 user 消息折叠为字符串,静默丢弃图片。现在保留原生 deepseek/ 路由;回归测试
通过真实 LiteLLM SDK 向本地 HTTP 接收端发送请求,并核对最终 base64 图像字节。
发布
GitHub Release 自动触发 PyPI 发布,认证配置和版本顺序见 发布说明。
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file purrcept_litellm-0.1.3.tar.gz.
File metadata
- Download URL: purrcept_litellm-0.1.3.tar.gz
- Upload date:
- Size: 201.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a32cc506a8143a3d452099e09bdd82ee4cead0e9c73a46492686dd70e7be942b
|
|
| MD5 |
caf00455c5f944945882d727ef989854
|
|
| BLAKE2b-256 |
002c22c9685aba98e83ef49e0a89e8d66d57610469d806cad7b45f01b7b61a4e
|
Provenance
The following attestation bundles were made for purrcept_litellm-0.1.3.tar.gz:
Publisher:
publish.yml on Windpicker-owo/Purrcept-LiteLLM
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
purrcept_litellm-0.1.3.tar.gz -
Subject digest:
a32cc506a8143a3d452099e09bdd82ee4cead0e9c73a46492686dd70e7be942b - Sigstore transparency entry: 2752526552
- Sigstore integration time:
-
Permalink:
Windpicker-owo/Purrcept-LiteLLM@2d477baef852a75d526ee41af8a6b83f79cca7cd -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/Windpicker-owo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2d477baef852a75d526ee41af8a6b83f79cca7cd -
Trigger Event:
release
-
Statement type:
File details
Details for the file purrcept_litellm-0.1.3-py3-none-any.whl.
File metadata
- Download URL: purrcept_litellm-0.1.3-py3-none-any.whl
- Upload date:
- Size: 30.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e20c80fcfc65a0c2d089b757404f3ddb1c2921dae6a8ff18faa65c243d68053
|
|
| MD5 |
c073d500e85f0b087b236078c1426f43
|
|
| BLAKE2b-256 |
5e36acab4ca7a3ebb0ee7acaec401c65e33d87fe297c39c52e5780db3a131299
|
Provenance
The following attestation bundles were made for purrcept_litellm-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on Windpicker-owo/Purrcept-LiteLLM
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
purrcept_litellm-0.1.3-py3-none-any.whl -
Subject digest:
1e20c80fcfc65a0c2d089b757404f3ddb1c2921dae6a8ff18faa65c243d68053 - Sigstore transparency entry: 2752526554
- Sigstore integration time:
-
Permalink:
Windpicker-owo/Purrcept-LiteLLM@2d477baef852a75d526ee41af8a6b83f79cca7cd -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/Windpicker-owo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2d477baef852a75d526ee41af8a6b83f79cca7cd -
Trigger Event:
release
-
Statement type: