【AI大模型接入SDK】项目的数据结构设计

📅 2026/8/24 23:46:37
【AI大模型接入SDK】项目的数据结构设计
个人主页艾莉丝努力练剑❄专栏传送门《C语言》《数据结构与算法》《C/C干货分享学习过程记录》《Linux操作系统编程详解》《笔试/面试常见算法从基础到进阶》《Python干货分享》⭐️为天地立心为生民立命为往圣继绝学为万世开太平 艾莉丝的简介文章目录1 ~ AI‑Model‑Access‑Tech 大模型接入 SDK1.1 项目前期准备工作1.1.1 API‑Key 资源准备1.1.2 Git 仓库与本地项目创建完整操作流程1.1.3 SDK 目录创建与工程结构1.1.4 头文件源文件分离的设计目的1.1.5 common.h 基础文件配置1.2 需求分析需要定义哪些数据结构1.2.1 Message 消息结构体1.2.2 Config 模型调用基础配置结构体1.2.3 ModelInfo 模型元信息结构体1.2.4 Session 会话结构体1.3 Token 概念、换算、计费规则1.3.1 Token 基础概念1.3.2 DeepSeek 模型计费规则1.3.3 temperature 参数官方使用场景表1.4 工程与数据结构设计思想完整复盘1.4.1 继承设计1.4.2 对象分层1.4.3 C 工程 SDK 设计要点1.4.4 业务后续开发方向附录完整 common.h 全部整合代码结尾1 ~ AI‑Model‑Access‑Tech 大模型接入 SDK1.1 项目前期准备工作1.1.1 API‑Key 资源准备原始计划可用模型DeepSeek、ChatGPT、Gemini实际替换情况Gemini 存在反中访问限制替换为通义千问ChatGPT 无法完成充值替换为 mino 模型API‑Key 定位连接大模型服务的身份凭证是调用 API 的第一步拿到密钥后阅读官方 API 文档确认请求地址、请求体格式即可发起模型调用。1.1.2 Git 仓库与本地项目创建完整操作流程操作终端bitbit08# 1.进入will工作目录cdwill# 2.创建项目根目录mkdirai-model-acess-techcdai-model-acess-tech# 3.拉取老师提供的远程码云仓库gitclone https://gitee.com/zhibite-edu/ai-model-acess-tech.gitgit clone 执行输出日志remote:Enumerating objects:4,done. remote:Counting objects:100%(4/4),done. remote:Compressing objects:100%(4/4),done. Cloning intoai-model-acess-tech... Receiving objects:100%(4/4),4.91 KiB|4.91 MiB/s,done.克隆完成后目录内包含 git 版本控制相关文件.git文件夹、.gitignore、LICENSE。业务问题.git版本控制元文件不希望出现在业务代码树中。 解决方式在克隆得到的仓库目录内部新建业务工程目录所有业务代码放入该子目录。# 进入clone下来的仓库目录cdai-model-acess-tech# 创建业务项目文件夹mkdirAIModelAcessTechcdAIModelAcessTech用户 alice 项目路径Alice/ai-model-acess/ai-model-acess/AIModeAcess个人码云仓库地址艾莉丝努力练剑 /ai-model-acess项目含义SDK 接入 AI 大模型项目。1.1.3 SDK 目录创建与工程结构接入模型的业务代码最终编译成为静态库静态库源代码放置在 SDK 目录。AIModelAcessTech └─ sdk ├─ include # 对外头文件编译安装时对外拷贝 │ └─ common.h # 公共结构体定义头文件 └─ src # cpp源文件编译静态库对外不发布1.1.4 头文件源文件分离的设计目的SDK 编译输出静态库安装部署的时候只拷贝静态库文件 include 下的头文件src 源文件不需要对外分发。CMakeLists.txt 构建脚本编写更加方便头文件统一集中管理。1.1.5 common.h 基础文件配置文件路径sdk/include/common.h#pragma once头文件保护防止重复包含。使用命名空间ai_chat_sdk隔离本 SDK 全部类型避免和外部项目符号冲突。#pragma once #include string #include ctime namespace ai_chat_sdk { // 所有结构体写在此命名空间内部 } // end ai_chat_sdk1.2 需求分析需要定义哪些数据结构业务场景对接多家大模型DeepSeek、mino、千问、Ollama 本地模型 虽然各个厂商模型 API 细节不一样但是存在大量公共配置、公共业务对象。 需要管理的业务对象模型调用配置模型名称、temperature 温度、max_tokens、apikey、服务端点 base url聊天消息角色 role、消息 content、消息 id、消息时间戳会话管理每一轮对话是一个会话会话绑定模型、保存历史消息列表、创建时间、更新时间。这些结构体在 SDK 多个模块都会复用统一放在 common.h 头文件。1.2.1 Message 消息结构体业务含义保存单条对话消息对应 LLM 接口 messages 数组内单条元素。 字段迭代演进过程第一轮最简版本只保留_role、_content迭代增加_messageId用于消息管理、消息定位迭代增加_timestamp消息发送时间戳需要引入ctime头文件构造函数业务层只传入 role 和 contentmessageId、timestamp 由 SDK 内部自动生成填充。完整代码#pragma once #include string #include ctime #include vector namespace ai_chat_sdk { /** * brief 单条对话消息结构体 */ struct Message { std::string _messageId; // 消息唯一ID std::string _role; // 角色user / assistant / system std::string _content; // 消息文本内容 std::time_t _timestamp; // 消息发送时间戳 /** * brief 构造函数业务层只提供角色和内容 * param role 消息角色 * param content 消息文本 */ Message(const std::string role, const std::string content) : _role(role), _content(content), _timestamp(std::time(nullptr)) {} }; } // end ai_chat_sdk1.2.2 Config 模型调用基础配置结构体核心思考APIKey 不放入 Config 基类云端 API 模型deepseek、千问、mino需要 API‑KeyOllama 本地部署模型不需要 API‑Key。 因此基类只存放全部模型通用参数云端特有参数使用子类继承扩展。成员说明_modelName要调用的模型名字_temperature采样温度默认 0.7取值范围 0~2数值越大输出随机性越高想象力天马行空数值越小输出严谨、确定性高。官方建议不要同时修改 temperature 与 top_p 两个参数。 | 使用场景 | temperature 参考值 | | ---- | ---- | | 代码生成 / 数学解题 | 0.0 | | 数据抽取 / 数据分析 | 1.0 | | 通用对话 | 1.3 | | 翻译 | 1.3 | | 创意写作、诗歌创作 | 1.5 |_maxTokens单次请求最大输出 token 数量默认 2048受模型总上下文窗口限制。虚析构函数virtual ~Config() default;开启 RTTI 运行时类型识别支持多态向下转型。/** * brief LLM基础配置基类所有模型通用运行参数 */ struct Config { std::string _modelName; double _temperature 0.7; int _maxTokens 2048; // 虚析构支持多态RTTI virtual ~Config() default; }; /** * brief 云端API调用模型的配置继承Config增加apikey * note Ollama本地模型不使用该结构体 */ struct APIConfig : public Config { std::string _apiKey; // 云端服务身份密钥 };1.2.3 ModelInfo 模型元信息结构体业务定位用于前端模型选择界面描述模型静态信息不包含运行时调用参数。 字段_modelName模型名称_modelDesc模型功能描述文本_provider模型厂商、提供者_endpointAPI 服务 Base URL前置 URL接口根地址如https://api.deepseek.com_isAvailable标记模型是否初始化就绪可用默认 false。构造函数提供带默认参数的构造方便实例化。/** * brief LLM模型元信息用于展示模型列表信息 */ struct ModelInfo { std::string _modelName; std::string _modelDesc; std::string _provider; std::string _endpoint; bool _isAvailable false; ModelInfo(const std::string name, const std::string desc , const std::string provider , const std::string endpoint ) : _modelName(name), _modelDesc(desc), _provider(provider), _endpoint(endpoint), _isAvailable(false) {} };1.2.4 Session 会话结构体业务含义代表一次完整对话会话一个会话绑定一个模型内部维护多条历史消息用于多轮对话。 字段说明_sessionId会话唯一 ID_modelName会话绑定的模型名称_messagesstd::vectorMessage存储会话全部历史消息_createdAt会话创建时间戳对象实例化时刻生成_updatedAt会话最后更新时间戳每新增一条消息就更新此字段用于历史会话列表展示最近会话时间。构造函数设计要点构造函数仅接收 modelName_sessionId不能在构造函数直接赋值需要 SDK 业务层手动生成_createdAt对象创建时初始化_updatedAt初始化为创建时间追加消息时手动刷新。/** * brief 会话结构体保存一轮完整对话上下文 */ struct Session { std::string _sessionId; std::string _modelName; std::vectorMessage _messages; std::time_t _createdAt; std::time_t _updatedAt; Session(const std::string modelName ) : _modelName(modelName), _createdAt(std::time(nullptr)), _updatedAt(std::time(nullptr)) {} };1.3 Token 概念、换算、计费规则1.3.1 Token 基础概念Token大模型处理文本的最小单元同时也是计费单元。直观理解可以近似理解为 “词 / 字”但不是严格一一对应。经验估算换算不同模型分词器不一样仅参考不能作为精确计算依据英文字符1 字符 ≈0.3 token中文字符1 字符 ≈0.6 token真实 token 消耗以 API 返回 response 内usage字段为准。可以使用 tokenizer 工具做离线预计算。1.3.2 DeepSeek 模型计费规则计费 输入 token 数量 输出 token 数量 × 对应单价单位百万 tokens。区分缓存命中输入、缓存未命中输入、输出三档价格。余额扣费顺序优先扣赠送余额赠送余额耗尽之后扣充值余额。模型上下文限制deepseek‑chat 支持 128K 上下文窗口输出存在最大长度限制。特殊说明deepseek‑reasoner 开启 tools 函数调用时底层实际降级为 deepseek‑chat 执行。1.3.3 temperature 参数官方使用场景表业务场景temperature 推荐取值代码生成 / 数学解题0.0数据抽取 / 分析1.0通用对话1.3翻译1.3创意类写作 / 诗歌创作1.5注意默认temperature1.0本项目结构体默认设置 0.7。1.4 工程与数据结构设计思想完整复盘1.4.1 继承设计Config基类存放所有模型通用运行参数。APIConfig : public Config子类扩展云端模型特有 apiKey适配 Ollama 无密钥场景避免无效字段。1.4.2 对象分层ModelInfo静态元数据层模型描述、厂商、endpoint用于 UI 展示不参与调用时参数。Config / APIConfig运行调用参数层发起请求时使用。Message消息最小单元。Session会话聚合层聚合消息列表维护会话时间实现多轮对话上下文。1.4.3 C 工程 SDK 设计要点头文件与源文件分离编译静态库交付产物.a静态库 .h头文件。使用命名空间隔离 SDK 全部类型防止符号冲突。时间统一使用std::time_t标准库时间戳。基类提供虚析构保证多态析构安全开启 RTTI 支持运行时类型识别。1.4.4 业务后续开发方向定义完以上公共数据结构之后下一步就可以开始编写不同模型的 API 请求封装逻辑分别对接 DeepSeek、千问、mino、Ollama。附录完整 common.h 全部整合代码#pragmaonce#includestring#includectime#includevectornamespaceai_chat_sdk{/** * brief 单条对话消息结构体 */structMessage{std::string _messageId;// 消息唯一IDstd::string _role;// 角色user / assistant / systemstd::string _content;// 消息文本内容std::time_t _timestamp;// 消息发送时间戳Message(conststd::stringrole,conststd::stringcontent):_role(role),_content(content),_timestamp(std::time(nullptr)){}};/** * brief LLM基础配置基类所有模型通用运行参数 */structConfig{std::string _modelName;double_temperature0.7;int_maxTokens2048;virtual~Config()default;};/** * brief 云端API调用模型的配置继承Config增加apikey * note Ollama本地模型不使用该结构体 */structAPIConfig:publicConfig{std::string _apiKey;// 云端服务身份密钥};/** * brief LLM模型元信息用于展示模型列表信息 */structModelInfo{std::string _modelName;std::string _modelDesc;std::string _provider;std::string _endpoint;bool_isAvailablefalse;ModelInfo(conststd::stringname,conststd::stringdesc,conststd::stringprovider,conststd::stringendpoint):_modelName(name),_modelDesc(desc),_provider(provider),_endpoint(endpoint),_isAvailable(false){}};/** * brief 会话结构体保存一轮完整对话上下文 */structSession{std::string _sessionId;std::string _modelName;std::vectorMessage_messages;std::time_t _createdAt;std::time_t _updatedAt;Session(conststd::stringmodelName):_modelName(modelName),_createdAt(std::time(nullptr)),_updatedAt(std::time(nullptr)){}};}// end ai_chat_sdk结尾uu们本文的内容到这里就全部结束了艾莉丝在这里再次感谢您的阅读艾莉丝努力练剑C/C Linux 底层探索者 | 一个正在努力练剑的技术博主【关注】跟随我一起深耕技术领域见证每一次成长。❤️【点赞】让优质内容被更多人看见让知识传递更有力量。⭐【收藏】把核心知识点存好在需要时随时查、随时用。【评论】分享你的经验或疑问评论区一起交流避坑不要忘记给博主“一键四连”哦“今日练剑达成”“技术之路难免有困惑但同行的人会让前进更有方向。”结语希望对学习Linux相关内容的uu有所帮助不要忘记给博主“一键四连”哦往期回顾【AI接入大模型SDK】Deepseek API Apifox博主在这里放了一只小狗大家看完了摸摸小狗放松一下吧૮₍ ˶ ˊ ᴥ ˋ˶₎ა