
🎬 个人主页:艾莉丝努力练剑
❄专栏传送门:《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.1.1 核心接口契约
- 2.2 ModelInfo 模型元数据结构体
- 2.3 LLMManager 核心管理类成员
-
- 2.3.1 头文件基础结构
- 2.3.2 成员变量设计说明
- 2.3.1 头文件基础结构
- 3 ~> LLMManager 公有接口定义
-
- 3.1 模型生命周期接口
-
- 3.1.1 registerProvider 注册接口
- 3.1.2 initModel 初始化接口
- 3.1.1 registerProvider 注册接口
- 3.2 模型查询接口
-
- 3.2.1 getAvailableModels 获取可用列表
- 3.2.2 isModelAvailable 可用性检查
- 3.2.1 getAvailableModels 获取可用列表
- 3.3 消息交互接口
-
- 3.3.1 sendMessage 同步调用
- 3.3.2 sendMessageStream 流式调用
- 3.3.1 sendMessage 同步调用
- 4 ~> 核心方法实现细节
-
- 4.1 注册与初始化逻辑
-
- 4.1.1 registerProvider 实现
- 4.1.2 initModel 实现
- 4.1.1 registerProvider 实现
- 4.2 查询逻辑实现
-
- 4.2.1 getAvailableModels 实现
- 4.2.2 isModelAvailable 实现
- 4.2.1 getAvailableModels 实现
- 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 核心接口契约
1class LLMProvider { 2public: 3 virtual ~LLMProvider() = default; 4 5 // 模型初始化:加载配置、校验密钥、建立连接 6 virtual bool initModel(const std::map<std::string, std::string>& modelConfig) = 0; 7 8 // 检查模型当前是否可用 9 virtual bool isAvailable() const = 0; 10 11 // 获取模型元数据信息 12 virtual ModelInfo getModelInfo() const = 0; 13 14 // 同步发送消息,返回完整回复 15 virtual std::string sendMessage( 16 const std::vector<Message>& messages, 17 const std::map<std::string, std::string>& requestParam 18 ) = 0; 19 20 // 流式发送消息,通过回调逐块返回数据 21 virtual std::string sendMessageStream( 22 const std::vector<Message>& messages, 23 const std::map<std::string, std::string>& requestParam, 24 std::function<void(const std::string& chunk, bool last)> chunkCallback 25 ) = 0; 26}; 27
2.1.2 子类实现示例(DeepSeekProvider)
1bool DeepSeekProvider::initModel(const std::map<std::string, std::string>& modelConfig) { 2 // 读取并校验API密钥 3 auto it = modelConfig.find("api_key"); 4 if (it == modelConfig.end()) { 5 ERR("DeepSeekProvider initModel api_key not found"); 6 return false; 7 } 8 _apiKey = it->second; 9 10 // 读取并校验服务端点 11 it = modelConfig.find("endpoint"); 12 if (it == modelConfig.end()) { 13 ERR("DeepSeekProvider initModel endpoint not found"); 14 return false; 15 } 16 _endpoint = it->second; 17 18 _isAvailable = true; 19 INFO("DeepSeekProvider initModel success, endpoint: {}", _endpoint); 20 return true; 21} 22 23bool DeepSeekProvider::isAvailable() const { 24 return _isAvailable; 25} 26 27std::string DeepSeekProvider::getModelName() const { 28 return "deepseek-chat"; 29} 30
2.2 ModelInfo 模型元数据结构体
定义于common.h头文件,用于存储模型的静态描述信息,实现模型元数据与业务实现的分离,支撑对外信息展示。
1struct ModelInfo { 2 std::string modelName; // 模型唯一标识名称 3 std::string modelDesc; // 模型功能与定位描述 4 std::string provider; // 模型提供厂商 5 std::string endpoint; // 模型API服务根地址 6 bool isAvailable = false; // 模型实时可用性状态 7 8 // 带默认参数的构造函数 9 ModelInfo( 10 const std::string& modelName = "", 11 const std::string& modelDesc = "", 12 const std::string& provider = "", 13 const std::string& endpoint = "" 14 ) : modelName(modelName), modelDesc(modelDesc), provider(provider), endpoint(endpoint) {} 15}; 16
2.3 LLMManager 核心管理类成员
LLMManager 通过双映射容器实现模型实例与元数据的统一管理,是整个 SDK 的核心调度中枢。
2.3.1 头文件基础结构
1#pragma once 2#include <map> 3#include <memory> 4#include <vector> 5#include <string> 6#include <stdexcept> 7#include <functional> 8#include "LLMProvider.h" 9#include "common.h" 10 11namespace ai_chat_sdk { 12 13class LLMManager { 14public: 15 // 公有业务接口(后续章节详细定义) 16 17private: 18 // 模型提供者映射表:key=模型名称, value=模型提供者基类智能指针 19 std::map<std::string, std::shared_ptr<LLMProvider>> providers; 20 21 // 模型信息映射表:key=模型名称, value=模型元数据对象 22 std::map<std::string, ModelInfo> modelInfos; 23}; 24 25} // namespace ai_chat_sdk 26
2.3.2 成员变量设计说明
providers:存储所有已注册的模型提供者实例,通过基类指针指向子类对象,利用 C++ 多态特性实现统一调用modelInfos:存储所有模型的元数据信息,与providers通过模型名称一一对应;对外仅暴露该层数据,避免泄露内部实现对象
3 ~> LLMManager 公有接口定义
3.1 模型生命周期接口
3.1.1 registerProvider 注册接口
1void registerProvider(const std::string& modelName, std::shared_ptr<LLMProvider> provider); 2
- 功能:将具体模型的实现类实例注册到管理容器,是模型纳入统一管理的入口
- 参数:
modelName:模型唯一标识名称,作为后续调用的索引键provider:模型提供者实例的智能指针,必须是 LLMProvider 子类的实例
- 约束:重复注册同一名称的模型会覆盖原有实例
3.1.2 initModel 初始化接口
1bool initModel(const std::string& modelName, const std::map<std::string, std::string>& modelParam); 2
- 功能:根据模型名称查找对应实例,完成配置加载与可用性校验
- 参数:
modelName:目标模型的注册名称modelParam:模型初始化参数字典,通常包含api_key、endpoint等配置项
- 返回值:初始化成功返回 true,失败返回 false
- 异常:模型未注册时抛出
std::runtime_error异常
3.2 模型查询接口
3.2.1 getAvailableModels 获取可用列表
1std::vector<ModelInfo> getAvailableModels() const; 2
- 功能:返回所有已注册且状态为可用的模型元数据集合
- 应用场景:客户端新建会话时的模型选择界面展示
- 返回值:仅包含
isAvailable = true的模型信息
3.2.2 isModelAvailable 可用性检查
1bool isModelAvailable(const std::string& modelName) const; 2
- 功能:校验指定名称的模型是否存在且处于可用状态
- 返回值:模型不存在或不可用均返回 false,可用返回 true
- 作用:消息发送前的前置校验,避免无效调用
3.3 消息交互接口
3.3.1 sendMessage 同步调用
1std::string sendMessage( 2 const std::string& modelName, 3 const std::vector<Message>& messages, 4 const std::map<std::string, std::string>& requestParam 5); 6
- 功能:向指定模型同步发送对话消息,等待并返回完整回复文本
- 参数:
modelName:目标模型名称messages:对话历史消息列表,包含角色与内容requestParam:请求超参数,如temperature、max_tokens等
3.3.2 sendMessageStream 流式调用
1std::string sendMessageStream( 2 const std::string& modelName, 3 const std::vector<Message>& messages, 4 const std::map<std::string, std::string>& requestParam, 5 std::function<void(const std::string& chunk, bool last)> chunkCallback 6); 7
- 功能:向指定模型发送流式请求,通过回调函数逐块返回生成的文本
- 回调参数:
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 实现
1void LLMManager::registerProvider(const std::string& modelName, std::shared_ptr<LLMProvider> provider) { 2 providers[modelName] = provider; 3 // 同步写入模型基础信息,保证双映射表数据一致 4 modelInfos[modelName] = provider->getModelInfo(); 5} 6
- 实现要点:注册阶段同时维护
providers与modelInfos两个容器,保证数据一致性;注册仅存储实例,不执行初始化
4.1.2 initModel 实现
1bool LLMManager::initModel(const std::string& modelName, const std::map<std::string, std::string>& modelParam) { 2 auto it = providers.find(modelName); 3 if (it == providers.end()) { 4 throw std::runtime_error("Model provider not found: " + modelName); 5 } 6 7 // 多态调用:基类指针调用子类重写的初始化方法 8 bool success = it->second->initModel(modelParam); 9 // 更新元数据中的可用性状态 10 modelInfos[modelName].isAvailable = success; 11 return success; 12} 13
- 多态原理:基类指针根据指向对象的实际类型,调用对应子类重写的虚函数,实现 “一个接口,多种实现”
- 状态同步:初始化结果同步更新到
modelInfos,确保查询接口返回最新状态
4.2 查询逻辑实现
4.2.1 getAvailableModels 实现
1std::vector<ModelInfo> LLMManager::getAvailableModels() const { 2 std::vector<ModelInfo> models; 3 for (const auto& pair : modelInfos) { 4 if (pair.second.isAvailable) { 5 models.push_back(pair.second); 6 } 7 } 8 return models; 9} 10
- 实现逻辑:遍历元数据映射表,过滤出可用状态的模型并返回;不直接操作
providers容器,符合信息隐藏原则
4.2.2 isModelAvailable 实现
1bool LLMManager::isModelAvailable(const std::string& modelName) const { 2 auto it = modelInfos.find(modelName); 3 if (it == modelInfos.end()) { 4 return false; 5 } 6 return it->second.isAvailable; 7} 8
- 容错处理:模型不存在时直接返回 false,不抛出异常,保证接口调用的安全性
4.3 消息转发机制
LLMManager 本身不处理具体的 HTTP 请求、协议封装与响应解析,所有消息交互均采用路由转发模式:
1std::string LLMManager::sendMessage( 2 const std::string& modelName, 3 const std::vector<Message>& messages, 4 const std::map<std::string, std::string>& requestParam 5) { 6 auto it = providers.find(modelName); 7 if (it == providers.end()) { 8 throw std::runtime_error("Model provider not found: " + modelName); 9 } 10 if (!it->second->isAvailable()) { 11 throw std::runtime_error("Model is not available: " + modelName); 12 } 13 // 转发给具体模型提供者执行 14 return it->second->sendMessage(messages, requestParam); 15} 16
- 职责边界:LLMManager 仅负责路由寻址、前置校验与结果转发,业务逻辑完全下沉到各 Provider 子类
- 流式接口实现逻辑与同步接口一致,仅增加回调函数透传
5 ~> 扩展机制与架构价值
5.1 模型扩展流程
新增模型接入严格遵循开闭原则,无需修改 LLMManager 核心代码,标准流程如下:
- 新建模型 Provider 类,公开继承 LLMProvider 抽象基类
- 重写所有纯虚函数:
initModel、isAvailable、getModelInfo、sendMessage、sendMessageStream - 上层业务实例化新模型 Provider,调用
registerProvider注册到 LLMManager - 传入配置参数调用
initModel,完成初始化后即可通过统一接口调用
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】LLMManager架构设计与实现》 是转载文章,点击查看原文。
“技术之路难免有困惑,但同行的人会让前进更有方向。”
