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

文章目录
- [1 ~> AI‑Model‑Access‑Tech 大模型接入 SDK](#1 ~> AI‑Model‑Access‑Tech 大模型接入 SDK)
-
- [1.1 项目前期准备工作](#1.1 项目前期准备工作)
-
- [1.1.1 API‑Key 资源准备](#1.1.1 API‑Key 资源准备)
- [1.1.2 Git 仓库与本地项目创建完整操作流程](#1.1.2 Git 仓库与本地项目创建完整操作流程)
- [1.1.3 SDK 目录创建与工程结构](#1.1.3 SDK 目录创建与工程结构)
-
- [1.1.4 头文件源文件分离的设计目的](#1.1.4 头文件源文件分离的设计目的)
- [1.1.5 common.h 基础文件配置](#1.1.5 common.h 基础文件配置)
- [1.2 需求分析:需要定义哪些数据结构](#1.2 需求分析:需要定义哪些数据结构)
-
- [1.2.1 Message 消息结构体](#1.2.1 Message 消息结构体)
- [1.2.2 Config 模型调用基础配置结构体](#1.2.2 Config 模型调用基础配置结构体)
- [1.2.3 ModelInfo 模型元信息结构体](#1.2.3 ModelInfo 模型元信息结构体)
- [1.2.4 Session 会话结构体](#1.2.4 Session 会话结构体)
- [1.3 Token 概念、换算、计费规则](#1.3 Token 概念、换算、计费规则)
-
- [1.3.1 Token 基础概念](#1.3.1 Token 基础概念)
- [1.3.2 DeepSeek 模型计费规则](#1.3.2 DeepSeek 模型计费规则)
- [1.3.3 temperature 参数官方使用场景表](#1.3.3 temperature 参数官方使用场景表)
- [1.4 工程与数据结构设计思想完整复盘](#1.4 工程与数据结构设计思想完整复盘)
-
- [1.4.1 继承设计](#1.4.1 继承设计)
- [1.4.2 对象分层](#1.4.2 对象分层)
- [1.4.3 C++ 工程 SDK 设计要点](#1.4.3 C++ 工程 SDK 设计要点)
- [1.4.4 业务后续开发方向](#1.4.4 业务后续开发方向)
- [附录:完整 common.h 全部整合代码](#附录:完整 common.h 全部整合代码)
- 结尾

1 ~> AI‑Model‑Access‑Tech 大模型接入 SDK
1.1 项目前期准备工作
1.1.1 API‑Key 资源准备
- 原始计划可用模型:DeepSeek、ChatGPT、Gemini
- 实际替换情况
- Gemini 存在反中访问限制,替换为通义千问
- ChatGPT 无法完成充值,替换为 mino 模型
- API‑Key 定位:连接大模型服务的身份凭证,是调用 API 的第一步;拿到密钥后阅读官方 API 文档,确认请求地址、请求体格式,即可发起模型调用。
1.1.2 Git 仓库与本地项目创建完整操作流程
操作终端:bit@bit08
bash
# 1.进入will工作目录
cd will
# 2.创建项目根目录
mkdir ai-model-acess-tech
cd ai-model-acess-tech
# 3.拉取老师提供的远程码云仓库
git clone https://gitee.com/zhibite-edu/ai-model-acess-tech.git
- git clone 执行输出日志
Bash
remote:Enumerating objects:4,done.
remote:Counting objects:100%(4/4),done.
remote:Compressing objects:100%(4/4),done.
Cloning into'ai-model-acess-tech'...
Receiving objects:100%(4/4),4.91 KiB|4.91 MiB/s,done.
- 克隆完成后目录内包含 git 版本控制相关文件:
.git文件夹、.gitignore、LICENSE。
业务问题:
.git版本控制元文件不希望出现在业务代码树中。 解决方式:在克隆得到的仓库目录内部,新建业务工程目录,所有业务代码放入该子目录。
bash
# 进入clone下来的仓库目录
cd ai-model-acess-tech
# 创建业务项目文件夹
mkdir AIModelAcessTech
cd AIModelAcessTech
- 用户 alice 项目路径:
Alice/ai-model-acess/ai-model-acess/AIModeAcess - 个人码云仓库地址:艾莉丝努力练剑 /ai-model-acess,项目含义:SDK 接入 AI 大模型项目。
1.1.3 SDK 目录创建与工程结构
接入模型的业务代码最终编译成为静态库,静态库源代码放置在 SDK 目录。
Bash
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 全部类型,避免和外部项目符号冲突。
C++
#pragma once
#include <string>
#include <ctime>
namespace ai_chat_sdk {
// 所有结构体写在此命名空间内部
} // end ai_chat_sdk
1.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 和 content;messageId、timestamp 由 SDK 内部自动生成填充。
完整代码:
C++
#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_sdk
1.2.2 Config 模型调用基础配置结构体
核心思考:APIKey 不放入 Config 基类
- 云端 API 模型(deepseek、千问、mino)需要 API‑Key
- Ollama 本地部署模型,不需要 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 运行时类型识别,支持多态向下转型。
C++
/**
* @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:模型厂商、提供者_endpoint:API 服务 Base URL(前置 URL,接口根地址,如https://api.deepseek.com)_isAvailable:标记模型是否初始化就绪可用,默认 false。
构造函数:提供带默认参数的构造,方便实例化。
C++
/**
* @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:会话绑定的模型名称_messages:std::vector<Message>存储会话全部历史消息_createdAt:会话创建时间戳,对象实例化时刻生成_updatedAt:会话最后更新时间戳;每新增一条消息,就更新此字段,用于历史会话列表展示最近会话时间。
构造函数设计要点
- 构造函数仅接收 modelName;
_sessionId不能在构造函数直接赋值,需要 SDK 业务层手动生成;_createdAt对象创建时初始化;_updatedAt初始化为创建时间,追加消息时手动刷新。
C++
/**
* @brief 会话结构体,保存一轮完整对话上下文
*/
struct Session
{
std::string _sessionId;
std::string _modelName;
std::vector<Message> _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 |
注意:默认temperature=1.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 全部整合代码
cpp
#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; // 消息发送时间戳
Message(const std::string& role, const std::string& content)
: _role(role), _content(content), _timestamp(std::time(nullptr))
{}
};
/**
* @brief LLM基础配置基类,所有模型通用运行参数
*/
struct Config
{
std::string _modelName;
double _temperature = 0.7;
int _maxTokens = 2048;
virtual ~Config() = default;
};
/**
* @brief 云端API调用模型的配置,继承Config,增加apikey
* @note Ollama本地模型不使用该结构体
*/
struct APIConfig : public Config
{
std::string _apiKey; // 云端服务身份密钥
};
/**
* @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)
{}
};
/**
* @brief 会话结构体,保存一轮完整对话上下文
*/
struct Session
{
std::string _sessionId;
std::string _modelName;
std::vector<Message> _messages;
std::time_t _createdAt;
std::time_t _updatedAt;
Session(const std::string& modelName = "")
: _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
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა
