Pixelle-Video 源码解析 #10:多模型适配:GPT、通义千问、DeepSeek、Ollama 如何统一调用?

前面几篇,我们已经分析了 Pixelle-Video 的文案生成、固定文案、分镜规划和 Prompt 设计。

这一篇继续分析一个非常重要的工程设计问题:

Pixelle-Video 是如何把 GPT、通义千问、DeepSeek、Ollama 等不同大模型统一接入同一套生成流程的?

这个问题很关键。

因为 Pixelle-Video 的核心流程里,LLM 不只负责"写一段文案"。它会参与多个环节:

text 复制代码
主题 → 生成多段 narration
已有内容 → 提炼成 narration
脚本 → 生成标题
narration → 生成图片 prompt
narration → 生成视频 prompt
用户风格描述 → 转成英文视觉 prompt

如果每个模型都写一套调用逻辑,代码很快就会变得很乱:

text 复制代码
call_openai()
call_qwen()
call_deepseek()
call_ollama()
call_kimi()
call_custom_llm()

Pixelle-Video 的设计思路不是这样。

它选择了一条更简单、更工程化的路线:

只要模型服务兼容 OpenAI SDK 调用方式,就统一通过同一个 LLMService 调用。

一、多模型适配到底要解决什么问题?

在 AI 应用里,接入多个大模型,表面上看只是换一个 API Key。

但实际开发时,会遇到很多细节问题:

text 复制代码
不同模型的 API 地址不同
不同模型的 model 名称不同
有的服务需要真实 API Key
有的本地服务不需要真实 Key
有的模型 JSON 输出稳定
有的模型容易输出 markdown 代码块
有的模型中文更好
有的模型便宜
有的模型适合本地部署

如果每个地方都直接调用具体模型,后面维护会非常痛苦。

比如文案生成函数里直接写 OpenAI 调用,标题生成函数里又写通义千问调用,图片提示词生成函数里再写 DeepSeek 调用,那么以后想换模型,就要改很多地方。

Pixelle-Video 解决这个问题的方式是:

把模型调用统一封装到 LLMService,上层业务只关心"传入 prompt,拿回 response"。

这样,文案生成、标题生成、图片 prompt 生成都不需要知道底层到底是 GPT、Qwen、DeepSeek,还是本地 Ollama。

二、配置层:只用三个字段描述一个 LLM

先看配置文件。

Pixelle-Video 的 config.example.yaml 中,LLM 配置非常简单,只有三个字段:

yaml 复制代码
llm:
  api_key: ""
  base_url: ""
  model: ""

配置文件注释中明确写着:LLM 支持任何 OpenAI SDK compatible API,并且给出了几个常见预设,包括 Qwen Max、OpenAI GPT-4o、DeepSeek、Ollama Local。

这三个字段分别代表:

text 复制代码
api_key
    模型服务的密钥

base_url
    模型服务的 OpenAI-compatible 接口地址

model
    具体调用的模型名称

所以 Pixelle-Video 的多模型适配,本质上是把不同模型统一抽象成:

text 复制代码
同一个调用协议 + 不同的 base_url + 不同的 model

例如配置 GPT:

yaml 复制代码
llm:
  api_key: "你的 OpenAI API Key"
  base_url: "https://api.openai.com/v1"
  model: "gpt-4o"

配置通义千问:

yaml 复制代码
llm:
  api_key: "你的 DashScope API Key"
  base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1"
  model: "qwen-max"

配置 DeepSeek:

yaml 复制代码
llm:
  api_key: "你的 DeepSeek API Key"
  base_url: "https://api.deepseek.com"
  model: "deepseek-chat"

配置本地 Ollama:

yaml 复制代码
llm:
  api_key: "dummy-key"
  base_url: "http://localhost:11434/v1"
  model: "llama3.2"

这些示例的关键不是具体用哪个模型,而是格式完全一致。

这就是统一调用的基础。

三、Schema 层:LLMConfig 把配置结构固定下来

Pixelle-Video 没有直接把 YAML 当普通 dict 到处传,而是在 schema.py 里用 Pydantic 定义了 LLMConfig

源码中 LLMConfig 只有三个字段:api_keybase_urlmodel,并且主配置 PixelleVideoConfig 中包含 llm: LLMConfigPixelleVideoConfig 还提供了 is_llm_configured(),用于检查这三个字段是否都填写完整。

可以简化理解为:

python 复制代码
class LLMConfig(BaseModel):
    api_key: str = ""
    base_url: str = ""
    model: str = ""

这个设计的好处是:

text 复制代码
配置结构清晰
默认值明确
校验入口统一
WebUI 和核心服务读取的是同一套结构

也就是说,Pixelle-Video 并没有在代码里到处判断"这是 GPT 还是 Qwen",而是先把所有 LLM 配置统一成一个结构。

四、ConfigManager:统一读取和保存 LLM 配置

配置结构定义好以后,还需要一个统一管理入口。

Pixelle-Video 的 ConfigManager 使用单例模式管理配置,负责从 config.yaml 加载配置、更新配置、保存配置,并提供 get_llm_config()set_llm_config() 等方法。set_llm_config() 会接收 api_keybase_urlmodel,并更新到 llm 配置块中。

这意味着 WebUI 或其他代码不需要直接操作 YAML 文件。

它们只需要调用:

python 复制代码
config_manager.set_llm_config(
    api_key=api_key,
    base_url=base_url,
    model=model
)
config_manager.save()

从架构上看,这一层的作用是:

text 复制代码
config.yaml
    ↓
ConfigManager
    ↓
LLMConfig
    ↓
LLMService

这样配置来源就统一了。

以后如果你想在 WebUI 里切换模型,本质上就是更新这三个字段。

五、LLMService:所有模型的统一调用入口

真正负责调用大模型的是 pixelle_video/services/llm_service.py 里的 LLMService

源码注释中写得很直接:LLMService 使用 OpenAI SDK 直接实现,支持所有 OpenAI SDK compatible providers,包括 OpenAI、Alibaba Qwen、DeepSeek、Ollama,以及自定义 OpenAI-compatible API。

它的核心调用入口是 __call__()

python 复制代码
async def __call__(
    self,
    prompt: str,
    api_key: Optional[str] = None,
    base_url: Optional[str] = None,
    model: Optional[str] = None,
    temperature: float = 0.7,
    max_tokens: int = 2000,
    response_type: Optional[Type[T]] = None,
    **kwargs
) -> Union[str, T]:
    ...

这个接口设计得很实用。

上层业务只需要传:

python 复制代码
response = await llm_service(
    prompt=prompt,
    temperature=0.8,
    max_tokens=2000
)

如果不传 api_keybase_urlmodel,它就从配置系统读取。

如果临时传了参数,就用临时参数覆盖配置。

所以,LLMService 同时支持两种用法:

text 复制代码
默认模式:
使用 config.yaml 中配置的模型

覆盖模式:
当前调用临时指定 api_key / base_url / model

这对测试不同模型很方便。

六、_create_client:用 AsyncOpenAI 屏蔽模型差异

LLMService_create_client() 是多模型适配的关键。

源码中它会先确定最终的 api_keybase_url,优先级是"调用参数 > 配置文件"。如果没有 API Key,会使用 "dummy-key",注释里说明这是因为 Ollama 不需要真实 Key。然后它创建 AsyncOpenAI 客户端;如果有 base_url,就把 base_url 传进去。

简化后就是:

python 复制代码
def _create_client(api_key=None, base_url=None):
    final_api_key = api_key or config.llm.api_key or "dummy-key"
    final_base_url = base_url or config.llm.base_url

    client_kwargs = {"api_key": final_api_key}

    if final_base_url:
        client_kwargs["base_url"] = final_base_url

    return AsyncOpenAI(**client_kwargs)

这就是统一调用的核心。

不管你用 GPT、Qwen、DeepSeek,还是本地 Ollama,只要它们提供 OpenAI-compatible 接口,代码都可以走:

python 复制代码
client.chat.completions.create(...)

区别只在配置:

text 复制代码
OpenAI:
    base_url = https://api.openai.com/v1
    model = gpt-4o

Qwen:
    base_url = https://dashscope.aliyuncs.com/compatible-mode/v1
    model = qwen-max

DeepSeek:
    base_url = https://api.deepseek.com
    model = deepseek-chat

Ollama:
    base_url = http://localhost:11434/v1
    model = llama3.2

从业务代码角度看,它们都是同一种 LLM。

七、call:真正发起 Chat Completions 请求

__call__() 中,Pixelle-Video 会先创建 client,然后确定最终 model。model 的优先级同样是"调用参数 > 配置文件 > 默认 fallback"。源码里默认 fallback 是 gpt-3.5-turbo。随后,如果没有使用结构化输出模式,就调用 client.chat.completions.create(),传入 modelmessagestemperaturemax_tokens 等参数。

简化后是:

python 复制代码
response = await client.chat.completions.create(
    model=final_model,
    messages=[{"role": "user", "content": prompt}],
    temperature=temperature,
    max_tokens=max_tokens,
    **kwargs
)

return response.choices[0].message.content

这个设计非常直接。

Pixelle-Video 没有为不同模型写不同请求格式,而是让它们都适配 OpenAI 的 chat.completions 风格。

这就是"OpenAI-compatible"的价值。

八、为什么 Ollama 也能接入?

Ollama 是本地模型服务,和云端 API 不一样。

但如果 Ollama 暴露 OpenAI-compatible 接口,那么 Pixelle-Video 就可以像调用云端模型一样调用它。配置示例中也给出了 Ollama Local 的写法:base_url 使用 http://localhost:11434/v1,model 使用 llama3.2

本地 Ollama 的典型配置可以写成:

yaml 复制代码
llm:
  api_key: "dummy-key"
  base_url: "http://localhost:11434/v1"
  model: "llama3.2"

这里的 dummy-key 很重要。

因为 OpenAI SDK 创建 client 时需要 api_key 字段,但 Ollama 本地服务通常不需要真实密钥。Pixelle-Video 的 _create_client() 里也专门保留了 "dummy-key" 作为兜底。

这意味着本地模型和云端模型在 Pixelle-Video 里可以共用同一个调用入口。

区别只是:

text 复制代码
云端模型:
需要真实 API Key,需要网络,需要付费或额度

本地 Ollama:
需要本地启动模型服务,不一定需要真实 Key,成本主要是本机算力

九、LLMService 为什么要动态读取配置?

LLMService.__init__() 里有一个细节:它没有把配置永久缓存下来。源码注释中说明,为了支持 hot reload,它会在 _get_config_value() 中动态从 config_manager 读取配置。

也就是说,如果用户在 WebUI 里修改了 LLM 配置,后续调用 LLM 时可以读到新的配置。

这个设计对 Pixelle-Video 很重要。

因为它是一个 WebUI 工具,用户很可能在页面中切换:

text 复制代码
从 GPT 切到 DeepSeek
从 DeepSeek 切到 Qwen
从云端模型切到本地 Ollama
修改 base_url
修改 model 名称

如果 LLMService 初始化时就把配置固定死,那么用户改完配置后还要重启应用。

Pixelle-Video 通过动态读取配置,降低了调试成本。

十、LLMService 在 PixelleVideoCore 中如何被装配?

PixelleVideoCore 是 Pixelle-Video 的核心服务层。

源码中 PixelleVideoCore.initialize() 会初始化多个核心服务,包括 LLMServiceTTSServiceAPIProviderMediaServiceMediaServiceVideoServiceFrameProcessorPersistenceServiceHistoryManager,然后注册 standardcustomasset_based 三个 pipeline。

可以理解成:

text 复制代码
PixelleVideoCore
    ├── llm = LLMService(...)
    ├── tts = TTSService(...)
    ├── media = MediaService(...)
    ├── api_media = APIProviderMediaService(...)
    ├── video = VideoService(...)
    ├── frame_processor = FrameProcessor(...)
    └── pipelines

这说明 LLMService 不是一个孤立工具类,而是被注入到整个 Pixelle-Video 核心流程中。

后面的 StandardPipeline 会通过 self.core.llm 或类似方式调用 LLM,完成文案、标题和视觉 prompt 生成。

十一、业务层不关心模型是谁,只关心 llm_service

这一点在 content_generators.py 中体现得非常明显。

例如 generate_narrations_from_topic() 接收的参数不是 OpenAI client,也不是 Qwen client,而是一个通用的 llm_service。它只负责构造 prompt,然后调用 llm_service(prompt=..., temperature=0.8, max_tokens=2000),拿到 response 后解析 JSON,并校验 narrations 数量。

也就是说,文案生成函数完全不知道底层模型是谁。

它只依赖一个抽象能力:

text 复制代码
给我一个 prompt
返回一段文本

同样,标题生成函数也是调用 llm_service;图片 prompt 生成函数也是调用 llm_service,并且对返回的 image_prompts 做 JSON 解析、数量校验和重试。

这就是解耦。

如果底层模型从 GPT 换成 DeepSeek,业务代码不用动。

如果底层模型从云端 DeepSeek 换成本地 Ollama,业务代码仍然不用动。

只要配置改对,LLMService 继续返回文本即可。

十二、结构化输出:不同模型也能尽量统一 JSON 结果

Pixelle-Video 的 LLMService 还支持 response_type 参数。

当传入 Pydantic model 类型时,它会进入结构化输出模式。源码中 _call_with_structured_output() 会把 Pydantic model 的 JSON schema 追加到 prompt 中,要求模型只输出符合 schema 的 JSON。注释也说明,这种方式是为了兼容 Qwen、DeepSeek 等 OpenAI-compatible provider。

这个设计很实用。

因为并不是每个 OpenAI-compatible 服务都完整支持 OpenAI 最新的结构化输出接口。

所以 Pixelle-Video 采用了更通用的做法:

text 复制代码
不依赖某个厂商专有 structured output 能力
而是把 JSON schema 写进 prompt
让模型按 schema 输出
再由代码解析和校验

_parse_response_as_model() 也做了多层兜底:先尝试直接解析 JSON;失败后尝试从 markdown code block 中提取 JSON;再失败就尝试从文本中找到第一个 { 到最后一个 } 的 JSON 对象。

这种处理方式对多模型兼容很重要。

因为不同模型的"听话程度"不一样:

text 复制代码
有的模型严格只输出 JSON
有的模型会包一层 ```json
有的模型会加一句"下面是结果"
有的模型会把 JSON 前后加解释

如果只支持一种格式,多模型适配就会很脆弱。

十三、GPT、Qwen、DeepSeek、Ollama 在 Pixelle-Video 里的区别

从 Pixelle-Video 的源码结构看,这些模型在业务层没有本质区别。

它们的区别主要体现在配置和运行环境上。

1. GPT

GPT 适合追求综合质量和稳定输出的场景。

配置上,一般只需要填:

yaml 复制代码
llm:
  api_key: "你的 OpenAI API Key"
  base_url: "https://api.openai.com/v1"
  model: "gpt-4o"

Pixelle-Video 的配置示例中也把 OpenAI GPT-4o 作为常见预设之一。

2. 通义千问 Qwen

Qwen 对中文内容比较友好,适合中文短视频文案、中文标题、中文旁白生成。

配置示例中给出了 Qwen Max 的 OpenAI-compatible 地址和模型名:

yaml 复制代码
llm:
  api_key: "你的 DashScope API Key"
  base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1"
  model: "qwen-max"

Pixelle-Video 的配置文件注释里也列出了 Qwen Max 的 popular preset。

3. DeepSeek

DeepSeek 适合成本敏感、批量生成文案的场景。

配置示例中给出的方式是:

yaml 复制代码
llm:
  api_key: "你的 DeepSeek API Key"
  base_url: "https://api.deepseek.com"
  model: "deepseek-chat"

DeepSeek 同样通过 OpenAI-compatible 接口接入。

4. Ollama

Ollama 适合本地部署和免费试验。

配置示例中给出的方式是:

yaml 复制代码
llm:
  api_key: "dummy-key"
  base_url: "http://localhost:11434/v1"
  model: "llama3.2"

LLMService 中也专门说明 Ollama 不需要真实 key,所以 _create_client() 中会使用 "dummy-key" 作为兜底。

十四、统一调用带来的最大好处:pipeline 不用改

Pixelle-Video 的 standard pipeline 需要调用 LLM 做很多事:

text 复制代码
生成 narrations
生成 title
生成 image prompts
生成 video prompts
风格转换

如果没有统一的 LLMService,每个环节都要判断模型类型。

但现在,pipeline 只需要拿到:

python 复制代码
self.core.llm

然后传 prompt。

模型切换完全在配置层完成。

这就是典型的分层设计:

text 复制代码
配置层:
决定使用哪个模型

服务层:
负责统一调用模型

业务层:
负责文案、标题、prompt 生成逻辑

pipeline 层:
负责组织完整视频生成流程

这种架构的好处是:

text 复制代码
换模型不用改 pipeline
换模型不用改 prompt 生成函数
新增 OpenAI-compatible 服务成本很低
用户可以通过 WebUI 或 config.yaml 切换模型

十五、统一调用并不等于效果完全一致

不过要注意,统一调用只是解决"能不能接入"的问题,不代表不同模型生成效果完全一样。

同一个 prompt,GPT、Qwen、DeepSeek、Ollama 可能输出不同结果:

text 复制代码
文案风格不同
标题吸引力不同
JSON 格式稳定性不同
中文表达自然度不同
图片 prompt 细节程度不同
遵守字数限制的能力不同

所以 Pixelle-Video 虽然在工程上统一了调用入口,但模型选择仍然会影响最终视频效果。

实际使用时可以这样选择:

text 复制代码
追求稳定和综合质量:
优先 GPT 或能力较强的商业模型

中文内容为主:
可以测试 Qwen 或 DeepSeek

批量低成本生成:
可以测试 DeepSeek

本地离线、低成本实验:
可以测试 Ollama

对 JSON 格式要求高:
优先选择遵循指令能力更强的模型

尤其是 Pixelle-Video 很依赖 JSON 输出。

如果某个模型经常输出不合法 JSON,就会影响 narration、image_prompt 等结构化步骤。

十六、为什么还需要解析和兜底?

即使 Prompt 已经要求严格 JSON,模型也可能不完全遵守。

所以 Pixelle-Video 在多个地方做了兜底。

例如 generate_narrations_from_topic() 会在拿到 LLM response 后解析 JSON,然后检查是否存在 narrations 字段,并校验数量是否符合 n_scenes。如果返回数量多了,就截取前 n_scenes 个;如果少了,就抛出错误。

generate_image_prompts() 更进一步:它会把 narrations 分批处理,解析每批返回的 JSON,检查 image_prompts 字段,并确保 prompt 数量和 narration 数量完全一致。如果不一致,会按最大重试次数重试,最终仍然失败才抛错。

这说明 Pixelle-Video 的多模型适配不是简单"能调用就行"。

它还考虑了模型输出不稳定的问题:

text 复制代码
Prompt 约束输出格式
Parser 解析模型响应
Validator 校验字段和数量
Retry 处理偶发失败
Error 处理最终失败

这是实际 AI 工程里很重要的一层。

十七、和 API Providers 不要混淆

这里还要区分两个概念:

text 复制代码
llm
    用于文本生成:文案、标题、图片 prompt、视频 prompt

api_providers
    用于直连图像、视频、VLM 等媒体模型

config.example.yaml 中除了 llm 配置,还有 api_providers 配置,后者包含 OpenAI、DashScope、ARK、Kling 等 provider,主要用于不通过 ComfyUI workflow,直接调用图像、视频或视觉理解模型。

不要把这两层混在一起。

LLMService 解决的是:

text 复制代码
我怎么统一调用 GPT、Qwen、DeepSeek、Ollama 来生成文本?

APIProviderMediaService 解决的是:

text 复制代码
我怎么直接调用云厂商的图片、视频、VLM API?

它们都可能和 OpenAI、DashScope 这些名字有关,但用途不同。

在 Pixelle-Video 中:

text 复制代码
llm 配置影响文案和 prompt
api_providers 配置影响媒体生成
comfyui 配置影响工作流执行

理解这三者边界,读源码就不会乱。

十八、二次开发:如何新增一个 OpenAI-compatible 模型?

如果你要接入一个新的大模型服务,只要它兼容 OpenAI Chat Completions 风格,通常不需要改 LLMService

你只需要配置:

yaml 复制代码
llm:
  api_key: "你的 API Key"
  base_url: "模型服务商提供的 OpenAI-compatible base_url"
  model: "模型名称"

然后 Pixelle-Video 的调用链路就是:

text 复制代码
config.yaml
    ↓
ConfigManager
    ↓
LLMConfig
    ↓
LLMService._create_client()
    ↓
AsyncOpenAI(base_url=..., api_key=...)
    ↓
client.chat.completions.create()
    ↓
返回 response

如果你希望 WebUI 里有下拉预设,可以再做一层增强:

text 复制代码
1. 增加模型供应商名称
2. 增加默认 base_url
3. 增加推荐 model
4. 增加 API Key 获取提示
5. 在设置面板中加入快速选择

但底层调用逻辑不一定需要改。

十九、二次开发:如何让多模型切换更好用?

Pixelle-Video 当前已经有统一调用基础。如果要继续产品化,可以做几个增强。

1. 增加模型预设列表

在 WebUI 中提供:

text 复制代码
OpenAI GPT-4o
Qwen Max
DeepSeek Chat
Ollama Llama3.2
自定义 OpenAI-compatible

用户选中后,自动填充 base_url 和推荐 model,只需要填 API Key。

2. 增加连通性测试

保存配置前,可以加一个"测试 LLM"按钮。

测试内容很简单:

text 复制代码
请返回 JSON:{"ok": true}

然后检查返回能不能解析。

这样可以提前发现:

text 复制代码
API Key 错误
base_url 错误
model 名称错误
本地 Ollama 没启动
网络无法访问

3. 增加 JSON 稳定性评分

Pixelle-Video 很依赖 JSON 输出。

可以对不同模型做一个简单评分:

text 复制代码
连续请求 5 次
要求返回固定 JSON
统计成功率
提示用户该模型是否适合结构化生成

4. 增加不同任务使用不同模型

现在 LLM 配置偏全局。

未来可以拆成:

yaml 复制代码
llm:
  narration_model:
  title_model:
  image_prompt_model:
  video_prompt_model:

这样可以做成本优化:

text 复制代码
文案用强模型
标题用便宜模型
图片 prompt 用英文能力强的模型
批量任务用低成本模型

5. 增加 fallback 模型

如果主模型失败,可以自动切换备用模型:

text 复制代码
DeepSeek 失败 → Qwen
Qwen 失败 → GPT
云端失败 → 本地 Ollama

这个对批量视频生成很有用。

二十、常见问题排查

1. 页面能打开,但生成文案失败

优先检查:

text 复制代码
llm.api_key 是否填写
llm.base_url 是否正确
llm.model 是否正确
网络是否能访问 base_url
模型服务是否支持 chat.completions

PixelleVideoConfig.is_llm_configured() 本身也会检查 api_keybase_urlmodel 是否都有内容。

2. Ollama 配了但连不上

检查:

text 复制代码
Ollama 是否已启动
模型是否已 pull
base_url 是否是 http://localhost:11434/v1
model 名称是否和本地模型一致
如果在 Docker 中运行,localhost 是否指向容器自己

配置示例里也提醒 Docker 用户访问宿主机服务时,需要根据环境使用合适的宿主机地址;这一点虽然写在 ComfyUI 配置注释中,但同样提醒我们,容器里的 localhost 和宿主机的 localhost 不是一回事。

3. 模型返回内容,但程序报 JSON 错误

这说明模型没有严格遵守 Prompt 输出格式。

可以尝试:

text 复制代码
换更强的模型
降低 temperature
强化 Prompt 的 JSON 要求
检查返回内容是否包了 markdown
增加解析兜底
使用 response_type 结构化输出模式

LLMService 的结构化输出模式会把 Pydantic JSON schema 追加到 prompt,并在返回后进行 JSON 解析和 Pydantic 校验。

4. 换模型后风格变差

这是正常的。

统一调用解决的是接口问题,不保证内容质量完全一致。

可以针对不同模型调整:

text 复制代码
temperature
max_tokens
prompt wording
narration 字数范围
image prompt 字数范围

二十一、源码阅读建议

如果你想读 Pixelle-Video 的多模型适配源码,建议按这个顺序:

text 复制代码
1. config.example.yaml
   看 llm 配置如何用 api_key / base_url / model 描述模型

2. pixelle_video/config/schema.py
   看 LLMConfig 和 is_llm_configured()

3. pixelle_video/config/manager.py
   看 get_llm_config() 和 set_llm_config()

4. pixelle_video/services/llm_service.py
   看 AsyncOpenAI、_create_client()、__call__()、structured output

5. pixelle_video/service.py
   看 PixelleVideoCore 如何初始化 LLMService

6. pixelle_video/utils/content_generators.py
   看文案、标题、图片 prompt 如何统一调用 llm_service

按照这个顺序读,可以清楚看到:

text 复制代码
配置如何进入服务
服务如何调用模型
业务函数如何复用服务
pipeline 如何不关心底层模型

二十二、总结

这一篇我们分析了 Pixelle-Video 的多模型适配设计。

它的核心思路很清楚:

不要为 GPT、Qwen、DeepSeek、Ollama 分别写业务逻辑,而是把它们统一抽象成 OpenAI-compatible LLM。

整个调用链路可以总结为:

text 复制代码
config.yaml
    ↓
llm.api_key / llm.base_url / llm.model
    ↓
ConfigManager
    ↓
LLMConfig
    ↓
LLMService
    ↓
AsyncOpenAI
    ↓
client.chat.completions.create()
    ↓
返回文本或结构化 JSON
    ↓
文案生成 / 标题生成 / 图片 prompt 生成 / 视频 prompt 生成

这种设计带来几个好处:

text 复制代码
模型切换简单
业务代码稳定
支持云端模型
支持本地 Ollama
支持自定义 OpenAI-compatible 服务
支持参数覆盖和配置热更新
支持结构化输出兜底

当然,它也有边界:

text 复制代码
统一接口不等于统一质量
不同模型 JSON 稳定性不同
不同模型中文表达不同
不同模型成本和速度不同
本地模型受机器性能影响

一句话总结:

Pixelle-Video 的多模型适配,本质是用 OpenAI-compatible 接口把不同 LLM 统一封装到 LLMService 中,让上层文案、标题和 prompt 生成流程完全不关心底层模型是谁。

相关推荐
@atweiwei1 小时前
用 Rust 构建 Agent 应用的高性能框架:langchainrust 架构全景
人工智能·架构·rust·langchain·llm·agent·ai编程
欧特克_Glodon1 小时前
OpenCV计算机视觉开发入门与实践<二十二>:图像平滑之线性滤波
c++·人工智能·opencv·计算机视觉
ShiXZ2131 小时前
ChatGPT Plus用户注意:5小时限制今日恢复,额度每5小时自动刷新(且额度又又又重置了)
人工智能·chatgpt
阿童木写作1 小时前
跨马翻译:AI批量图片翻译工具,视频字幕翻译与智能抠图一站式解决
大数据·人工智能·python·音视频
chongzhe1 小时前
AgentConnect:多 Agent 协作的开源版 Claude Tag
人工智能·github·源码
武子康1 小时前
看不见的 Reasoning State,为什么不能拥有看得见的工具权限
人工智能·llm·agent
十三画者1 小时前
【文献分享】abCRISPR:基于深度学习的脱碱基gRNA理性设计框架
人工智能·深度学习·数据挖掘·数据分析·数据可视化
腾视科技-AIoT1 小时前
腾视科技重磅推出TensorAI智能体平台,开启智能助手新体验
大数据·人工智能·科技·ai·ai大模型·ainas·腾视科技
天天代码码天天1 小时前
一个 HTML 文件就能跑 OCR:我把 PP-OCR 装进了浏览器
人工智能