🎬 个人主页:艾莉丝努力练剑
❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》
⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平
🎬 艾莉丝的简介:

文章目录
- 1 ~> 项目背景与设计目标
-
- 1.1 现有模型接入方案
- 1.2 现有方案存在的问题
- 1.3 LLMManager 设计目标
- 2 ~> 核心抽象与数据结构
-
- 2.1 LLMProvider 抽象基类
-
- 2.1.1 核心接口契约
- 2.1.2 子类实现示例(DeepSeekProvider)
- 2.2 ModelInfo 模型元数据结构体
- 2.3 LLMManager 核心管理类成员
-
- 2.3.1 头文件基础结构
- 2.3.2 成员变量设计说明
- 3 ~> LLMManager 公有接口定义
-
- 3.1 模型生命周期接口
-
- 3.1.1 registerProvider 注册接口
- 3.1.2 initModel 初始化接口
- 3.2 模型查询接口
-
- 3.2.1 getAvailableModels 获取可用列表
- 3.2.2 isModelAvailable 可用性检查
- 3.3 消息交互接口
-
- 3.3.1 sendMessage 同步调用
- 3.3.2 sendMessageStream 流式调用
- 4 ~> 核心方法实现细节
-
- 4.1 注册与初始化逻辑
-
- 4.1.1 registerProvider 实现
- 4.1.2 initModel 实现
- 4.2 查询逻辑实现
-
- 4.2.1 getAvailableModels 实现
- 4.2.2 isModelAvailable 实现
- 4.3 消息转发机制
- 5 ~> 扩展机制与架构价值
-
- 5.1 模型扩展流程
- 5.2 架构设计优势
- 5.3 当前已接入模型清单
- 结尾

1 ~> 项目背景与设计目标
1.1 现有模型接入方案
- 云端模型接入:通过 HTTP API 调用方式接入三类主流云端大语言模型,包括 ChatGPT 系列、Gemini 系列、DeepSeek 系列
- 本地模型接入:基于 Ollama 第三方推理工具,实现本地大模型的部署、加载与调用管理
- 基础扩展逻辑:新增模型接入仅需新建对应实现类,重写抽象基类的纯虚方法即可完成适配,无需修改核心框架
1.2 现有方案存在的问题
- 代码冗余度高:不同云端模型除 API 密钥、服务端点不同外,请求封装、响应解析、流式处理等核心逻辑高度重合;每接入新模型都需重复实现完整逻辑,代码复用率低、可读性差
- 业务耦合度高:模型数量增多后,上层业务需直接感知具体模型实现类,调用时需实例化对应 Provider,维护与切换成本高
- 缺乏统一管控:模型状态、配置、生命周期分散在各个实现类中,无法进行统一的状态监控与调度管理
1.3 LLMManager 设计目标
基于面向对象多态机制构建统一模型管理层,实现三大核心目标:
- 屏蔽底层不同模型的实现差异,对外提供一致的调用接口
- 集中管理所有模型的注册、初始化、状态校验与消息转发
- 上层业务无需依赖具体模型实现类,仅通过 LLMManager 即可完成全部模型交互,符合开闭原则
2 ~> 核心抽象与数据结构
2.1 LLMProvider 抽象基类
LLMProvider 是所有模型提供者的抽象基类,定义了统一的接口契约,是多态机制的核心基础。所有具体模型必须继承该类并实现全部纯虚函数。
2.1.1 核心接口契约
class LLMProvider {
public:
virtual ~LLMProvider() = default;
// 模型初始化:加载配置、校验密钥、建立连接
virtual bool initModel(const std::map<std::string, std::string>& modelConfig) = 0;
// 检查模型当前是否可用
virtual bool isAvailable() const = 0;
// 获取模型元数据信息
virtual ModelInfo getModelInfo() const = 0;
// 同步发送消息,返回完整回复
virtual std::string sendMessage(
const std::vector<Message>& messages,
const std::map<std::string, std::string>& requestParam
) = 0;
// 流式发送消息,通过回调逐块返回数据
virtual std::string sendMessageStream(
const std::vector<Message>& messages,
const std::map<std::string, std::string>& requestParam,
std::function<void(const std::string& chunk, bool last)> chunkCallback
) = 0;
};
2.1.2 子类实现示例(DeepSeekProvider)
bool DeepSeekProvider::initModel(const std::map<std::string, std::string>& modelConfig) {
// 读取并校验API密钥
auto it = modelConfig.find("api_key");
if (it == modelConfig.end()) {
ERR("DeepSeekProvider initModel api_key not found");
return false;
}
_apiKey = it->second;
// 读取并校验服务端点
it = modelConfig.find("endpoint");
if (it == modelConfig.end()) {
ERR("DeepSeekProvider initModel endpoint not found");
return false;
}
_endpoint = it->second;
_isAvailable = true;
INFO("DeepSeekProvider initModel success, endpoint: {}", _endpoint);
return true;
}
bool DeepSeekProvider::isAvailable() const {
return _isAvailable;
}
std::string DeepSeekProvider::getModelName() const {
return "deepseek-chat";
}
2.2 ModelInfo 模型元数据结构体
定义于common.h头文件,用于存储模型的静态描述信息,实现模型元数据与业务实现的分离,支撑对外信息展示。
struct ModelInfo {
std::string modelName; // 模型唯一标识名称
std::string modelDesc; // 模型功能与定位描述
std::string provider; // 模型提供厂商
std::string endpoint; // 模型API服务根地址
bool isAvailable = false; // 模型实时可用性状态
// 带默认参数的构造函数
ModelInfo(
const std::string& modelName = "",
const std::string& modelDesc = "",
const std::string& provider = "",
const std::string& endpoint = ""
) : modelName(modelName), modelDesc(modelDesc), provider(provider), endpoint(endpoint) {}
};
2.3 LLMManager 核心管理类成员
LLMManager 通过双映射容器实现模型实例与元数据的统一管理,是整个 SDK 的核心调度中枢。
2.3.1 头文件基础结构
#pragma once
#include <map>
#include <memory>
#include <vector>
#include <string>
#include <stdexcept>
#include <functional>
#include "LLMProvider.h"
#include "common.h"
namespace ai_chat_sdk {
class LLMManager {
public:
// 公有业务接口(后续章节详细定义)
private:
// 模型提供者映射表:key=模型名称, value=模型提供者基类智能指针
std::map<std::string, std::shared_ptr<LLMProvider>> providers;
// 模型信息映射表:key=模型名称, value=模型元数据对象
std::map<std::string, ModelInfo> modelInfos;
};
} // namespace ai_chat_sdk
2.3.2 成员变量设计说明
- providers:存储所有已注册的模型提供者实例,通过基类指针指向子类对象,利用 C++ 多态特性实现统一调用
- modelInfos:存储所有模型的元数据信息,与providers通过模型名称一一对应;对外仅暴露该层数据,避免泄露内部实现对象
3 ~> LLMManager 公有接口定义
3.1 模型生命周期接口
3.1.1 registerProvider 注册接口
void registerProvider(const std::string& modelName, std::shared_ptr<LLMProvider> provider);
- 功能:将具体模型的实现类实例注册到管理容器,是模型纳入统一管理的入口
- 参数:
- modelName:模型唯一标识名称,作为后续调用的索引键
- provider:模型提供者实例的智能指针,必须是 LLMProvider 子类的实例
- 约束:重复注册同一名称的模型会覆盖原有实例
3.1.2 initModel 初始化接口
bool initModel(const std::string& modelName, const std::map<std::string, std::string>& modelParam);
- 功能:根据模型名称查找对应实例,完成配置加载与可用性校验
- 参数:
- modelName:目标模型的注册名称
- modelParam:模型初始化参数字典,通常包含api_key、endpoint等配置项
- 返回值:初始化成功返回 true,失败返回 false
- 异常:模型未注册时抛出std::runtime_error异常
3.2 模型查询接口
3.2.1 getAvailableModels 获取可用列表
std::vector<ModelInfo> getAvailableModels() const;
- 功能:返回所有已注册且状态为可用的模型元数据集合
- 应用场景:客户端新建会话时的模型选择界面展示
- 返回值:仅包含isAvailable = true的模型信息
3.2.2 isModelAvailable 可用性检查
bool isModelAvailable(const std::string& modelName) const;
- 功能:校验指定名称的模型是否存在且处于可用状态
- 返回值:模型不存在或不可用均返回 false,可用返回 true
- 作用:消息发送前的前置校验,避免无效调用
3.3 消息交互接口
3.3.1 sendMessage 同步调用
std::string sendMessage(
const std::string& modelName,
const std::vector<Message>& messages,
const std::map<std::string, std::string>& requestParam
);
- 功能:向指定模型同步发送对话消息,等待并返回完整回复文本
- 参数:
- modelName:目标模型名称
- messages:对话历史消息列表,包含角色与内容
- requestParam:请求超参数,如temperature、max_tokens等
3.3.2 sendMessageStream 流式调用
std::string sendMessageStream(
const std::string& modelName,
const std::vector<Message>& messages,
const std::map<std::string, std::string>& requestParam,
std::function<void(const std::string& chunk, bool last)> chunkCallback
);
- 功能:向指定模型发送流式请求,通过回调函数逐块返回生成的文本
- 回调参数:
- chunk:当前返回的文本片段
- last:是否为最后一块数据,为 true 时表示响应结束
- 返回值:最终拼接完成的完整回复文本
- 流式回调使用示例:
- auto writeChunk = [](const std::string& chunk, bool last) { INFO("chunk: {}", chunk); if (last) { INFO("[DONE]"); } }; std::string fullData = manager.sendMessageStream("deepseek-chat", messages, requestParam, writeChunk);
4 ~> 核心方法实现细节
4.1 注册与初始化逻辑
4.1.1 registerProvider 实现
void LLMManager::registerProvider(const std::string& modelName, std::shared_ptr<LLMProvider> provider) {
providers[modelName] = provider;
// 同步写入模型基础信息,保证双映射表数据一致
modelInfos[modelName] = provider->getModelInfo();
}
- 实现要点:注册阶段同时维护providers与modelInfos两个容器,保证数据一致性;注册仅存储实例,不执行初始化
4.1.2 initModel 实现
bool LLMManager::initModel(const std::string& modelName, const std::map<std::string, std::string>& modelParam) {
auto it = providers.find(modelName);
if (it == providers.end()) {
throw std::runtime_error("Model provider not found: " + modelName);
}
// 多态调用:基类指针调用子类重写的初始化方法
bool success = it->second->initModel(modelParam);
// 更新元数据中的可用性状态
modelInfos[modelName].isAvailable = success;
return success;
}
- 多态原理:基类指针根据指向对象的实际类型,调用对应子类重写的虚函数,实现 “一个接口,多种实现”
- 状态同步:初始化结果同步更新到modelInfos,确保查询接口返回最新状态
4.2 查询逻辑实现
4.2.1 getAvailableModels 实现
std::vector<ModelInfo> LLMManager::getAvailableModels() const {
std::vector<ModelInfo> models;
for (const auto& pair : modelInfos) {
if (pair.second.isAvailable) {
models.push_back(pair.second);
}
}
return models;
}
- 实现逻辑:遍历元数据映射表,过滤出可用状态的模型并返回;不直接操作providers容器,符合信息隐藏原则
4.2.2 isModelAvailable 实现
bool LLMManager::isModelAvailable(const std::string& modelName) const {
auto it = modelInfos.find(modelName);
if (it == modelInfos.end()) {
return false;
}
return it->second.isAvailable;
}
- 容错处理:模型不存在时直接返回 false,不抛出异常,保证接口调用的安全性
4.3 消息转发机制
LLMManager 本身不处理具体的 HTTP 请求、协议封装与响应解析,所有消息交互均采用路由转发模式:
std::string LLMManager::sendMessage(
const std::string& modelName,
const std::vector<Message>& messages,
const std::map<std::string, std::string>& requestParam
) {
auto it = providers.find(modelName);
if (it == providers.end()) {
throw std::runtime_error("Model provider not found: " + modelName);
}
if (!it->second->isAvailable()) {
throw std::runtime_error("Model is not available: " + modelName);
}
// 转发给具体模型提供者执行
return it->second->sendMessage(messages, requestParam);
}
- 职责边界:LLMManager 仅负责路由寻址、前置校验与结果转发,业务逻辑完全下沉到各 Provider 子类
- 流式接口实现逻辑与同步接口一致,仅增加回调函数透传
5 ~> 扩展机制与架构价值
5.1 模型扩展流程
新增模型接入严格遵循开闭原则,无需修改 LLMManager 核心代码,标准流程如下:
5.2 架构设计优势
- 业务解耦:上层业务仅依赖 LLMManager 与通用数据结构,与具体模型实现完全隔离,模型切换无需修改业务代码
- 统一规范:所有模型遵循相同的接口契约,保证调用方式、参数结构、错误处理的一致性
- 可维护性:各模型实现逻辑内聚于独立的 Provider 类,故障定位、功能迭代、性能优化互不影响
- 可测试性:可基于 LLMProvider 接口注入 Mock 实现,在无真实 API 的环境下完成单元测试
5.3 当前已接入模型清单
| deepseek-r1:70b | 本地 Ollama | DeepSeek 旗舰级开源大模型,128K 上下文,主打深度理解与推理 |
| gemini-2.0-flash | 云端 API | Google 极速响应模型,面向大规模部署与快速交互场景 |
| gpt-4o-mini | 云端 API | OpenAI 轻量级高性价比模型,核心能力接近 GPT-4 Turbo |
| deepseek-chat | 云端 API | 中文优化通用对话模型,适用于日常问答与创意创作场景 |
结尾
uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!
|
艾莉丝努力练剑
C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 👀 ❤️ ⭐ 💬 不要忘记给博主“一键四连”哦! “今日练剑达成!” “技术之路难免有困惑,但同行的人会让前进更有方向。” |
结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!
往期回顾:
【AI大模型接入SDK】Ollama API 流式增量响应
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡
૮₍ ˶ ˊ ᴥ ˋ˶₎ა



