从零实现 C++ AI 大模型接入 SDK(二):项目演示、环境搭建与 ChatSDK 快速上手

发布时间:2026/9/12 19:40:58
从零实现 C++ AI 大模型接入 SDK(二):项目演示、环境搭建与 ChatSDK 快速上手 目录一、先看一下最终项目效果1.1 启动 AIChatServer1.2 打开网页聊天界面1.3 实际发送一条消息二、开发环境搭建2.1 本系列采用的开发方式2.2 安装 Trae 并连接远程服务器2.3 clangd 和 CMake Tools三、安装项目需要的第三方依赖3.1 先看项目到底依赖什么3.2 Ubuntu 安装命令3.3 安装 cpp-httplib四、获取并编译我们自己的 ChatSDK4.1 克隆项目4.2 为什么先“安装”一次 SDK4.3 编译并安装 SDK五、ChatSDK 快速上手5.1 先从使用者角度看 ChatSDK5.2 新建一个快速体验 Demo5.3 编写 main.cpp5.4 API Key 不要写进源码5.5 编写 CMakeLists.txt5.6 编译 Demo5.7 运行命令行 Demo六、回到完整项目编译并启动 ChatServer七、写到最后前言系列从零实现 C AI 大模型接入 SDK第二篇项目源码AI-Chat-SDKhttps://gitee.com/kuang-zhenting/my_ai_cpp_projecthttps://gitee.com/kuang-zhenting/my_ai_cpp_project上一篇我们已经从整体上认识了这个项目最终要实现一套自己的ChatSDK统一接入 DeepSeek、ChatGPT、Gemini 和 Ollama再在 SDK 之上完成一个网页 AI 聊天助手。这一篇先不急着进入 Provider 的具体实现。我们先做三件事看一下最终项目真正运行起来是什么效果把后面写 C SDK 需要的开发环境和第三方依赖准备好暂时把最终版ChatSDK当成一个已经完成的 SDK先站在“使用者”的角度调用一次。这样做的好处是后面真正开始从零实现 SDK 时我们不会只看到一堆类和函数而是知道这些模块最后到底要服务于什么。一、先看一下最终项目效果这一节主要负责“看结果”。如果现在还是一台刚准备好的 Linux 服务器没有安装依赖也没有编译项目不需要急着跟着运行。可以先看完演示后面的环境搭建完成以后我们再回来实际启动。1.1 启动 AIChatServer最终项目的服务端可执行文件是ChatServer/build/AIChatServer在已经完成编译、并且至少配置了一个云端模型 API Key 的情况下可以进入构建目录启动cd ChatServer/build ./AIChatServer当前源码默认监听0.0.0.0:8080服务启动成功以后终端会出现类似ChatServer listening on 0.0.0.0:80801.2 打开网页聊天界面服务器启动后在浏览器访问http://服务器地址:8080/如果浏览器和服务器在同一台机器上也可以使用http://127.0.0.1:8080/最终页面主要分成两部分左侧负责会话列表和模型选择右侧负责显示聊天内容和发送消息。1.3 实际发送一条消息创建会话并选择已经配置好的模型然后发送一条简单消息例如用C语言写一个冒泡排序项目支持流式回复所以正常情况下我们会看到模型内容逐步显示而不是一直等待到整段回答全部生成后才一次性出现。除此之外当前最终项目还支持多会话管理会话切换会话重命名置顶 / 取消置顶删除会话SQLite 历史记录持久化Markdown 渲染代码高亮和代码复制。第一篇已经介绍过这些模块的整体关系这里就不重复展开了。看完最终效果以后我们就知道后面搭环境、写 SDK、做流式响应和会话管理最后是在为什么服务了。二、开发环境搭建2.1 本系列采用的开发方式我这里使用的是比较常见的远程 Linux 开发方式Windows 本机 ↓ Trae ↓ Remote SSH ↓ 远程 Ubuntu 服务器 ↓ CMake / 编译 / 运行也就是说Trae 运行在 Windows 本机但源码、编译器、CMake 和最终程序都在远程 Linux 上。这种方式有几个好处本机负责编辑和界面交互Linux 服务器负责真正的 C 编译与运行后面安装 OpenSSL、SQLite 等 Linux 开发库比较方便编译环境和最终运行环境保持一致。如果大家平时习惯 VS Code整体思路也是类似的。这里主要按照我实际使用的 Trae 环境来写。2.2 安装 Trae 并连接远程服务器打开trae官方下载链接trae下载链接https://www.trae.ai/download​Trae 安装完成以后可以通过 Remote SSH 连接远程 Linux 主机。连接时需要准备服务器 IPSSH 用户名登录密码 / SSH Key成功以后我们在 Trae 中打开的终端实际上就是远程 Linux 的终端。连接成功以后后面创建文件、运行cmake、make、启动服务器等操作默认都发生在远程主机上。2.3 clangd 和 CMake Tools为了让 C 开发体验更舒服可以在远程环境中安装clangd插件。它主要负责代码补全语法和类型错误提示跳转到定义查找引用鼠标悬停查看函数签名等。需要注意的是clangd会持续分析 C 工程。如果使用的是配置比较低的云服务器它可能占用比较明显的内存。遇到“写代码没问题一编译服务器就很卡”的情况可以在编译阶段暂时关闭clangd需要编辑代码时再开启。另外如果希望直接在 Trae 中使用 CMake 的图形化集成功能可以安装CMake Tools。三、安装项目需要的第三方依赖3.1 先看项目到底依赖什么按照当前最终源码SDK 和 ChatServer 主要会用到下面这些库依赖在项目中的作用C17 编译器编译整个 SDK 和 ChatServerCMake生成构建文件、组织 SDK 安装OpenSSL让cpp-httplib支持 HTTPSSQLite3保存会话和聊天消息jsoncpp构造、解析 JSONspdlog日志输出fmt格式化支持gflagsChatServer 命令行参数与配置cpp-httplibHTTP 客户端、HTTP ServerGoogle Test后续测试代码会用到curl调试网络和 API 时很方便pkg-config帮助构建系统查找第三方库其中cpp-httplib比较特殊它是 header-only 库我们只需要让编译器能够找到httplib.h。3.2 Ubuntu 安装命令如果使用 Ubuntu可以先更新软件包索引sudo apt update然后安装本系列会用到的依赖sudo apt install -y \ cmake \ pkg-config \ curl \ git \ libssl-dev \ libsqlite3-dev \ libgflags-dev \ libspdlog-dev \ libfmt-dev \ libjsoncpp-dev \ libgtest-dev这里面最需要注意的是 OpenSSL。我们后面访问 DeepSeek、ChatGPT、Gemini 等云端模型时使用的是 HTTPS。如果没有 OpenSSL 开发库即使 HTTP 代码本身写对了也无法正常建立 HTTPS 请求。curl则主要作为调试工具。以后在怀疑 API 地址、网络连接或者 Key 是否有问题时可以先脱离自己的 C 代码用curl单独确认网络侧是否正常。安装完成后可以简单检查cmake --version g --version pkg-config --version只要当前机器已经具备支持 C17 的编译器并且 CMake 版本不低于项目要求就可以继续。3.3 安装 cpp-httplib先克隆cpp-httplibgit clone https://github.com/yhirose/cpp-httplib.git它最核心的就是httplib.h当前项目源码直接通过#include httplib.h包含这个头文件所以按照当前项目约定把它复制到/usr/local/include/sudo cp cpp-httplib/httplib.h /usr/local/include/检查一下ls /usr/local/include/httplib.h能看到这个文件就可以了。这里不需要再单独“编译一个 httplib 库”因为我们当前使用方式就是直接包含它的头文件。到这里项目的基础环境就基本准备好了。四、获取并编译我们自己的 ChatSDK接下来开始使用自己的项目。4.1 克隆项目项目地址https://gitee.com/kuang-zhenting/my_ai_cpp_project克隆git clone https://gitee.com/kuang-zhenting/my_ai_cpp_project.git cd my_ai_cpp_project项目中的核心 SDK 位于SDK/当前源码的 SDK 会被编译成静态库libai_chat_sdk.a4.2 为什么先“安装”一次 SDK我们后面当然会从零实现这套 SDK。但在正式实现之前先把最终版本当成一个现成的第三方 SDK 使用一次会更容易理解 SDK 对外到底应该提供什么。当前工程不是把 SDK 安装到/usr/local而是安装到项目自己的SDK/install/这样 ChatServer 和后面的 Demo 都直接使用当前项目本地的 SDK不需要依赖系统里可能已经过期的旧副本。目录关系可以先理解成SDK/ ├── include/ ├── src/ ├── build/ └── install/ ├── include/ │ └── ai_chat_sdk/ └── lib/ └── libai_chat_sdk.a4.3 编译并安装 SDK进入 SDK 目录cd SDK为了避免旧构建结果干扰这里第一次可以直接重新创建构建目录rm -rf build install mkdir build cd build生成构建文件时明确指定安装位置cmake .. -DCMAKE_INSTALL_PREFIX../install然后编译make -j最后安装make install注意这里没有使用sudo make install因为我们并不是安装到系统目录而是安装到当前项目自己的SDK/install/。安装完成以后可以检查ls ../install/lib/libai_chat_sdk.a ls ../install/include/ai_chat_sdk/ChatSDK.h如果这两个文件都存在说明我们已经得到了可以给其他 C 工程使用的 SDK 静态库和公开头文件。五、ChatSDK 快速上手5.1 先从使用者角度看 ChatSDK现在我们暂时不研究 SDK 内部的LLMManager、Provider、SessionManager是怎么写出来的。先只看一个使用者真正关心的问题我要怎样用这个 SDK 和 DeepSeek 聊一次天整个过程其实只有几步初始化日志 ↓ 创建 ChatSDK ↓ 准备 DeepSeek 配置 ↓ initModels() ↓ createSession() ↓ 读取用户输入 ↓ sendMessageStream() ↓ 通过回调接收流式内容这一节只使用 DeepSeek 做最小演示。等后面真正实现多模型接入时我们再分别研究 ChatGPT、Gemini 和 Ollama。5.2 新建一个快速体验 Demo回到项目根目录cd ../..创建一个单独的 Demomkdir -p quick_start_demo cd quick_start_demo最终结构大致如下my_ai_cpp_project/ ├── SDK/ ├── ChatServer/ ├── quick_start_demo/ │ ├── main.cpp │ └── CMakeLists.txt └── ...这里的quick_start_demo/是为了快速上手额外创建的体验工程不属于当前最终源码原本固定的目录结构。5.3 编写 main.cpp新建main.cpp#include ai_chat_sdk/ChatSDK.h #include ai_chat_sdk/common.h #include ai_chat_sdk/util/myLOG.h #include spdlog/spdlog.h #include cstdlib #include iostream #include memory #include string #include vector int main() { // 1. 先初始化日志。 // ChatSDK 内部很多模块都会输出日志因此要在创建 ChatSDK 之前完成。 myLOG::Logger::init_logger(ChatSDKDemo, stdout, spdlog::level::info); // 2. 从环境变量读取 DeepSeek API Key。 const char *api_key std::getenv(DEEPSEEK_KEY_API); if (api_key nullptr || std::string(api_key).empty()) { std::cerr 请先设置环境变量 DEEPSEEK_KEY_API std::endl; return 1; } // 3. 创建 SDK 对象。 ai_chat_sdk::ChatSDK chat_sdk; // 4. 准备 DeepSeek 配置。 auto deepseek_config std::make_sharedai_chat_sdk::APIConfig(); deepseek_config-_model_name deepseek-chat; deepseek_config-_api_key api_key; deepseek_config-_temperature 0.7; deepseek_config-_max_tokens 2048; std::vectorstd::shared_ptrai_chat_sdk::Config configs; configs.push_back(deepseek_config); // 5. 初始化模型。 if (!chat_sdk.initModels(configs)) { std::cerr ChatSDK 初始化失败 std::endl; return 1; } // 6. 创建一个绑定 DeepSeek 的会话。 const std::string session_id chat_sdk.createSession(deepseek-chat); if (session_id.empty()) { std::cerr 创建会话失败 std::endl; return 1; } std::cout 会话创建成功: session_id std::endl; std::cout 输入 0 退出程序 std::endl; // 7. 进入简单的命令行聊天循环。 while (true) { std::cout \nuser ; std::string message; if (!std::getline(std::cin, message)) { break; } if (message 0) { break; } if (message.empty()) { continue; } std::cout assistant std::flush; // 8. 流式发送消息。 const std::string full_reply chat_sdk.sendMessageStream(session_id, message, [](const std::string chunk, bool done) { if (!chunk.empty()) { std::cout chunk std::flush; } if (done) { std::cout std::endl; } }); if (full_reply.empty()) { std::cerr \n本轮没有得到有效回复 std::endl; } } std::cout 程序退出 std::endl; return 0; }这段 Demo 并没有绕过 SDK 去直接创建DeepSeekProvider。我们只使用ai_chat_sdk::ChatSDK这正是 SDK 对外封装的意义。上层准备模型配置、创建会话然后调用sendMessageStream()至于历史消息怎么保存、DeepSeek HTTP 请求怎么发、SSE 数据怎么解析全部交给 SDK 内部。5.4 API Key 不要写进源码当前最终源码使用的 DeepSeek 环境变量名称是DEEPSEEK_KEY_API运行 Demo 之前先设置export DEEPSEEK_KEY_API你的真实 DeepSeek API Key可以检查变量是否已经存在echo $DEEPSEEK_KEY_API5.5 编写 CMakeLists.txt在quick_start_demo/下新建CMakeLists.txt内容如下cmake_minimum_required(VERSION 3.10) project(ChatSDKQuickStart LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # ------------------- 可配置的 SDK 路径 ------------------- # 允许通过命令行 -DSDK_ROOT/path/to/sdk 指定安装目录 if(NOT SDK_ROOT) set(SDK_ROOT ${CMAKE_SOURCE_DIR}/../SDK/install CACHE PATH Path to ChatSDK install directory) endif() # ------------------- 可执行程序 ------------------- add_executable(chat_sdk_demo main.cpp) # 头文件路径 target_include_directories(chat_sdk_demo PRIVATE ${SDK_ROOT}/include ) # 宏定义保持与 SDK 一致的 HTTPS 支持 target_compile_definitions(chat_sdk_demo PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT ) # ------------------- 查找依赖库 ------------------- find_package(OpenSSL REQUIRED) find_package(Threads REQUIRED) find_package(SQLite3 REQUIRED) find_package(jsoncpp REQUIRED) find_package(spdlog REQUIRED) find_package(fmt REQUIRED) # ------------------- 链接库 ------------------- target_link_libraries(chat_sdk_demo PRIVATE ${SDK_ROOT}/lib/libai_chat_sdk.a # 静态库放在最前 jsoncpp_lib spdlog::spdlog fmt::fmt OpenSSL::SSL OpenSSL::Crypto SQLite::SQLite3 Threads::Threads )这里有两个路径最关键../SDK/install/include ../SDK/install/lib/libai_chat_sdk.a它们必须和前面真正安装 SDK 的位置一致。这也是为什么前面执行 CMake 时要明确-DCMAKE_INSTALL_PREFIX../install5.6 编译 Demo在quick_start_demo/中执行mkdir build cd build cmake .. make -j正常情况下会生成chat_sdk_demo如果cmake ..阶段失败一般优先检查SDK 是否真的已经安装到SDK/install/OpenSSL、SQLite、jsoncpp、spdlog、fmt 等开发库是否安装/usr/local/include/httplib.h是否存在CMake 查找第三方库时是否报错。如果make阶段失败再去看具体的编译错误或链接错误。5.7 运行命令行 Demo启动./chat_sdk_demo程序初始化成功后会创建一个绑定deepseek-chat的 Session。然后输入一个简单问题你是谁或者简单介绍一下 SSE。因为调用的是sendMessageStream()所以模型生成的内容会通过回调不断输出到终端。输入0退出程序。另外ChatSDK内部的 Session 会使用 SQLite 持久化所以从quick_start_demo/build/运行时可以看到当前工作目录下出现chat.db这也是后面我们实现会话持久化时会重新讲到的内容这里先有个印象即可。六、回到完整项目编译并启动 ChatServerChatSDK 已经验证能够使用以后我们再回到完整项目。前面的 SDK 已经安装到了SDK/install/而当前ChatServer/CMakeLists.txt正是直接使用这份本地 SDK。回到 ChatServercd ../../ChatServer mkdir build cd build生成构建文件cmake ..编译make -j正常完成以后会得到AIChatServer当前源码从环境变量读取三个云端模型的 API KeyDEEPSEEK_KEY_API CHATGPT_KEY_API GEMINI_KEY_API没有设置的模型不会加入当前可用模型。需要特别注意的是按照当前main.cpp的启动校验逻辑三个云端 Key 中至少需要设置一个否则AIChatServer会直接提示配置校验失败并退出。例如只使用 DeepSeekexport DEEPSEEK_KEY_API你的真实 DeepSeek API Key然后启动./AIChatServer第一次启动时可执行文件同目录下还会自动生成ChatServer.conf默认端口是8080于是浏览器访问http://服务器地址:8080/就可以重新得到文章开头演示的完整网页聊天助手。七、写到最后这一篇还没有正式开始“造轮子”主要是把后面开发前的准备工作做完。我们先看到了最终项目的运行效果然后完成了远程 Linux 开发环境 ↓ Trae / Remote SSH ↓ C 项目依赖 ↓ cpp-httplib ↓ 编译自己的 ChatSDK ↓ 使用 ChatSDK 创建 Session ↓ sendMessageStream() 调用 DeepSeek ↓ 编译并启动 ChatServer其中最重要的一点是我们已经站在 SDK 使用者的角度看到了最终接口应该是什么样ChatSDK ↓ initModels() ↓ createSession() ↓ sendMessageStream()现在我们知道这个 SDK 最后要怎么用后面再去从零实现它时每写一个模块都会更有方向。下一篇开始我们再补齐真正和大模型 API 接入直接相关的基础知识然后逐步进入 ChatSDK 的正式实现。