【AI大模型接入SDK】ChatServer接口测试

🎬 个人主页 :艾莉丝努力练剑
❄专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》
《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:


文章目录

  • [1 ~> ChatServer 接口整体测试体系](#1 ~> ChatServer 接口整体测试体系)
    • [1.1 测试前置准备](#1.1 测试前置准备)
      • [1.1.1 接口清单录入(Apifox)](#1.1.1 接口清单录入(Apifox))
      • [1.1.2 Apifox 环境配置](#1.1.2 Apifox 环境配置)
      • [1.1.3 会话 ID 生成规则](#1.1.3 会话 ID 生成规则)
  • [2 ~> 逐个接口测试流程与业务逻辑](#2 ~> 逐个接口测试流程与业务逻辑)
    • [2.1 GET /api/models 获取可用模型](#2.1 GET /api/models 获取可用模型)
      • [2.1.1 请求规约](#2.1.1 请求规约)
      • [2.1.2 返回 JSON 结构](#2.1.2 返回 JSON 结构)
      • [2.1.3 测试校验点](#2.1.3 测试校验点)
    • [2.2 POST /api/session 创建会话](#2.2 POST /api/session 创建会话)
      • [2.2.1 请求规约](#2.2.1 请求规约)
      • [2.2.2 返回 JSON 结构](#2.2.2 返回 JSON 结构)
      • [2.2.3 业务逻辑](#2.2.3 业务逻辑)
    • [2.3 GET /api/sessions 获取会话列表](#2.3 GET /api/sessions 获取会话列表)
      • [2.3.1 请求规约](#2.3.1 请求规约)
      • [2.3.2 返回 JSON 结构](#2.3.2 返回 JSON 结构)
      • [2.3.3 业务校验](#2.3.3 业务校验)
    • [2.4 DELETE /api/session/{session_id} 删除会话](#2.4 DELETE /api/session/{session_id} 删除会话)
      • [2.4.1 请求规约](#2.4.1 请求规约)
      • [2.4.2 返回 JSON](#2.4.2 返回 JSON)
      • [2.4.3 业务校验](#2.4.3 业务校验)
    • [2.5 GET /api/session/{session_id}/history 获取会话历史消息](#2.5 GET /api/session/{session_id}/history 获取会话历史消息)
      • [2.5.1 请求规约](#2.5.1 请求规约)
      • [2.5.2 典型故障点(代码 BUG 复盘)](#2.5.2 典型故障点(代码 BUG 复盘))
      • [2.5.3 校验标准](#2.5.3 校验标准)
    • [2.6 POST /api/message 发送消息‑全量返回](#2.6 POST /api/message 发送消息‑全量返回)
      • [2.6.1 请求规约](#2.6.1 请求规约)
      • [2.6.2 业务逻辑](#2.6.2 业务逻辑)
      • [2.6.3 校验](#2.6.3 校验)
    • [2.7 POST /api/message/async 发送消息‑SSE 流式增量返回](#2.7 POST /api/message/async 发送消息‑SSE 流式增量返回)
      • [2.7.1 请求规约](#2.7.1 请求规约)
      • [2.7.2 SSE 流式协议关键知识点](#2.7.2 SSE 流式协议关键知识点)
      • [2.7.3 代码故障复盘](#2.7.3 代码故障复盘)
      • [2.7.4 测试校验点](#2.7.4 测试校验点)
  • [3 ~> 多模型兼容性测试](#3 ~> 多模型兼容性测试)
    • [3.1 测试策略](#3.1 测试策略)
    • [3.2 外部模型环境依赖](#3.2 外部模型环境依赖)
    • [3.3 测试流程示例(gpt‑4o‑mini)](#3.3 测试流程示例(gpt‑4o‑mini))
  • [4 ~> SQLite 数据库存储层关键要点](#4 ~> SQLite 数据库存储层关键要点)
    • [4.1 数据表](#4.1 数据表)
    • [4.2 开发调试手段](#4.2 开发调试手段)
  • [5 ~> 整体排错方法论](#5 ~> 整体排错方法论)
  • 结尾


1 ~> ChatServer 接口整体测试体系

1.1 测试前置准备

1.1.1 接口清单录入(Apifox)

  • 共 7 个后端接口,服务基于 http‑lib 实现路由注册

    表格

    请求方法 接口路径 接口功能
    POST /api/session 创建会话
    GET /api/sessions 获取会话列表
    GET /api/models 获取可用模型列表
    DELETE /api/session/{session_id} 删除指定会话
    GET /api/session/{session_id}/history 获取会话历史消息
    POST /api/message 发送消息‑全量返回
    POST /api/message/async 发送消息‑流式增量返回
cpp 复制代码
// ChatServer 路由注册核心代码片段
void ChatServer::setupHttpRoutes(){
    // 创建会话
    _chatServer->Post(pattern="/api/session", handler=[this](const httplib::Request& request, httplib::Response& response){
        handleCreateSessionRequest(request, response);
    });
    // 获取会话列表
    _chatServer->Get(pattern="/api/sessions", handler=[this](const httplib::Request& request, httplib::Response& response){
        handleGetSessionListsRequest(request, response);
    });
    // 获取可用模型
    _chatServer->Get(pattern="/api/models", handler=[this](const httplib::Request& request, httplib::Response& response){
        handleGetModelListsRequest(request, response);
    });
    // 删除会话
    _chatServer->Delete(pattern="/api/session/(.*)", handler=[this](const httplib::Request& request, httplib::Response& response){
        handleDeleteSessionRequest(request, response);
    });
    // 获取会话历史消息
    _chatServer->Get(pattern="/api/session/(.*)/history", handler=[this](const httplib::Request& request, httplib::Response& response){
        handleGetHistoryMessagesRequest(request, response);
    });
    // 发送消息-全量返回
    _chatServer->Post(pattern="/api/message", handler=[this](const httplib::Request& request, httplib::Response& response){
        handleSendMessageRequest(request, response);
    });
    // 发送消息-流式增量返回
    _chatServer->Post(pattern="/api/message/async", handler=[this](const httplib::Request& request, httplib::Response& response){
        handleSendMessageStreamRequest(request, response);
    });
}

1.1.2 Apifox 环境配置

  1. 配置测试环境前置 URL:http://服务器IP:端口,示例http://192.168.100.238:8080
  2. 环境变量配置各类大模型 API‑KEY 密钥
  3. 接口录入规范
    • 严格对齐 HTTP 请求方法、Path 路径参数、Body JSON 参数
    • 测试阶段无需维护 Mock 响应结构体,仅校验请求可达性、返回数据有效性两个核心指标
    • Path 参数禁止携带$变量符号填入实际参数值,该符号为 Apifox 变量标识,直接填入会造成参数解析失败

1.1.3 会话 ID 生成规则

  • 会话 ID 格式:session_时间戳_序号
  • 序号由服务内部静态计数器维护;服务器进程不重启,计数器持续累加,不会重置
  • SessionManager 初始化会从数据库读取已有会话,恢复计数器基数
cpp 复制代码
// 会话ID生成关键片段
std::string SessionManager::generateSessionId(){
    // _sessionCounter 静态成员变量,进程生命周期持续自增
    _sessionCounter.fetch_add(1);
    std::time_t t = std::time(nullptr);
    return "session_" + std::to_string(t) + "_" + std::to_string(_sessionCounter);
}

2 ~> 逐个接口测试流程与业务逻辑

2.1 GET /api/models 获取可用模型

2.1.1 请求规约

  • HTTP 方法:GET,无请求参数

2.1.2 返回 JSON 结构

json 复制代码
{
    "success": true,
    "message": "get model lists success",
    "data": [
        {
            "name": "deepseek-chat",
            "desc": "一款基于Deepseek的实用性强、功能强大的、中文优化的通用聊天模型,用于生成自然语言回复,适合用于聊天、问答、对话等场景"
        }
    ]
}

2.1.3 测试校验点

  • HTTP 200;success 字段为 true;data 数组返回全部配置好的模型元数据。

2.2 POST /api/session 创建会话

2.2.1 请求规约

  • HTTP 方法:POST
  • Content‑Type: application/json
  • 请求 Body
json 复制代码
{
    "model":"deepseek-chat"
}

2.2.2 返回 JSON 结构

json 复制代码
{
    "success": true,
    "message": "create session success",
    "data": {
        "model": "deepseek‑chat",
        "session_id": "session_1789031979_00000001"
    }
}

2.2.3 业务逻辑

  • 指定模型创建全新会话,生成唯一 session_id;会话初始化消息计数为 0;写入 SQLite 数据库sessions表。

2.3 GET /api/sessions 获取会话列表

2.3.1 请求规约

  • HTTP 方法:GET,无请求参数

2.3.2 返回 JSON 结构

json 复制代码
{
    "success": true,
    "message": "get session lists success",
    "data": [
        {
            "id": "session_1789049548_00000002",
            "model": "deepseek‑r1:1.5b",
            "created_at": 1789049548,
            "updated_at": 1789049548,
            "message_count": 0
        }
    ]
}

2.3.3 业务校验

  • 返回全部持久化会话集合;message_count 统计该会话下问答消息总条数。

2.4 DELETE /api/session/{session_id} 删除会话

2.4.1 请求规约

  • HTTP 方法:DELETE
  • Path 参数:session_id 会话唯一标识

2.4.2 返回 JSON

json 复制代码
{
    "success": true,
    "message": "delete session success"
}

2.4.3 业务校验

  • 删除会话数据库记录;再次调用获取会话列表接口,该会话不再出现在 data 数组。

2.5 GET /api/session/{session_id}/history 获取会话历史消息

2.5.1 请求规约

  • HTTP 方法:GET
  • Path 参数:session_id

2.5.2 典型故障点(代码 BUG 复盘)

  1. SQLite 执行判断条件错误:sqlite3_step执行查询单条记录,执行成功读取行返回SQLITE_ROW;查询结束无更多数据返回SQLITE_DONE。
    • 原始错误:判断返回值不等于SQLITE_DONE,直接判定执行失败;单条查询读完数据之后会进入SQLITE_DONE,直接返回空会话指针,提示 session not found。
cpp 复制代码
// 错误代码片段
int rc = sqlite3_step(stmt);
if(rc != SQLITE_DONE){
    // 错误:单条记录读取完毕 rc=SQLITE_DONE,误判为执行失败
}

// 修正后逻辑
int rc = sqlite3_step(stmt);
if(rc != SQLITE_ROW){
    // 只有读到行才算有效数据,SQLITE_DONE代表查询结束
}
  1. Apifox 测试故障:Path 参数误输入带$的模板变量标识,后端拿到非法 session_id,返回会话不存在。

2.5.3 校验标准

  • 根据 session_id 读取 messages 表,返回该会话完整历史问答消息集合。

2.6 POST /api/message 发送消息‑全量返回

2.6.1 请求规约

  • POST,Content‑Type:application/json
json 复制代码
{
    "session_id":"session_xxxx",
    "message":"请讲一个笑话"
}

2.6.2 业务逻辑

  1. 根据 session_id 定位会话;校验会话合法性
  2. 将用户提问持久化写入 messages 表
  3. 调用大模型 SDK 完成完整对话,等待模型全部应答完成
  4. 将模型完整回答写入 messages 表;更新会话updated_at时间戳与message_count计数
  5. 将完整模型应答一次性返回客户端。

2.6.3 校验

  • 返回完整应答文本;获取历史消息接口可以看到新增两条消息(用户提问 + 模型回复)。

2.7 POST /api/message/async 发送消息‑SSE 流式增量返回

2.7.1 请求规约

  • POST,Content‑Type:application/json,请求体与全量接口完全一致。

2.7.2 SSE 流式协议关键知识点

  • Response 的 Content‑Type 必须设置为 text/event‑stream,禁止使用 application/json;application/json 会让客户端把整体当做 JSON 报文解析,不会逐块流式渲染。

  • SSE 报文格式:

    bash 复制代码
    data: 分片内容\n\n
    data: 分片内容\n\n
    data: [DONE]\n\n
  • data: [DONE]为流结束标记;HTTP 长连接保持,分块传输 chunked 编码。

2.7.3 代码故障复盘

  1. 预发送空数据块防客户端长等待的 BUG
cpp 复制代码
// 错误代码,第二个参数last=true直接标记流结束,连接立刻关闭
writeChunk("", true);

// 修复代码 last=false,代表不是流的最后一块
writeChunk("", false);

writeChunk 第二个布尔参数 last 语义:true 表示当前 chunk 是流的最后一个分片,发送data:[DONE]结束 SSE 会话;false 代表后续还有数据分片。

  1. 响应头 content‑type 错误写成application/json,客户端无法逐片解析事件流。
cpp 复制代码
// 错误
response->set_chunked_content_provider("application/json", providerLambda);
// 修正
response->set_chunked_content_provider("text/event‑stream", providerLambda);
// 流式请求处理修正后完整核心逻辑
void ChatServer::handleSendMessageStreamRequest(const httplib::Request& request, httplib::Response& response)
{
    std::string sessionId = request.json["session_id"].asString();
    std::string message = request.json["message"].asString();
    if(sessionId.empty() || message.empty()){
        response->status = 400;
        return;
    }
    response->status = 200;
    response->set_header("Cache‑Control", "no‑cache");
    response->set_header("Connection", "keep‑alive");
    // SSE必须使用 text/event‑stream
    response->set_chunked_content_provider("text/event‑stream",
        [this, sessionId, message](size_t offset, httplib::DataSink& dataSink)->bool{
            auto writeChunk = [&](const std::string& chunk, bool last)->void{
                // 转SSE报文格式
                std::string sseData = "data: " + json::valueToQuotedString(chunk.c_str()) + "\n\n";
                dataSink.write(sseData.c_str(), sseData.size());
                if(last){
                    std::string doneData = "data: [DONE]\n\n";
                    dataSink.write(doneData.c_str(), doneData.size());
                    dataSink.done();
                }
            };
            // 发送空块,防止客户端超时等待;last=false,流不关闭
            writeChunk("", false);
            // 调用SDK流式回调
            _chatSDK->sendMessageStream(sessionId, message, writeChunk);
            return true;
        });
}

2.7.4 测试校验点

  1. Apifox 时间线分片接收模型输出文本,逐块到达;
  2. 流末尾收到data: [DONE]结束标记;
  3. 会话消息计数更新;历史消息接口可以拿到完整问答。

3 ~> 多模型兼容性测试

3.1 测试策略

  • 基础会话、会话列表、删除会话、获取模型接口仅需针对一个模型完成验证。
  • 其余模型只需要重点验证全量返回、SSE 流式增量返回两个消息发送接口。

3.2 外部模型环境依赖

  • 云端模型(GPT 系列等)服务器访问受限场景,启动服务进程前需要配置代理环境变量。
  • Ollama 本地模型无需外网代理,服务本地访问 ollama 服务端口。

3.3 测试流程示例(gpt‑4o‑mini)

  1. POST /api/session,body 指定"model":"gpt‑4o‑mini"创建会话拿到 session_id
  2. 调用 POST /api/message全量接口发送提问,校验完整应答返回
  3. 调用 POST /api/message/async流式接口,校验 SSE 分片输出正常。

4 ~> SQLite 数据库存储层关键要点

4.1 数据表

  1. sessions表:存储会话元数据:session_id、model 名称、created_at、updated_at、message_count
  2. messages表:存储会话所有对话消息,关联 session_id 外键。

4.2 开发调试手段

  • 使用 sqlite3 命令行工具直接打开 db 文件,select 查询表数据,确认业务数据是否真正持久化,区分「内存对象正常」与「数据库持久化异常」两类 BUG。

5 ~> 整体排错方法论

  1. 分层定位:
    • Apifox 层:检查请求 URL、Path 参数、JSON 请求体、请求头 Content‑Type;排除参数拼写错误、混入 Apifox 模板变量符号。
    • HTTP 服务层:看服务终端日志,确认请求已经抵达后端;区分网络不通、路由未匹配、参数解析失败。
    • SDK / 业务逻辑层:日志打印关键入参出参,区分 HTTP 链路正常,业务逻辑 BUG。
    • 数据库层:命令行直连 sqlite 数据库,确认数据是否真正写入。
  2. 修改 SDK 底层代码后完整操作流程
    1. 修改源码;
    2. 执行编译;
    3. make install更新系统静态库与头文件;
    4. 重新编译链接 ChatServer 可执行程序;
    5. 重启 ChatServer 服务,执行接口复测。

重点:静态库更新之后,上层服务必须重新编译链接,否则运行程序依旧加载旧版本 SDK 二进制。


结尾

uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ### 艾莉丝努力练剑 C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 *** ** * ** *** 👀 【关注】 跟随我一起深耕技术领域,见证每一次成长。 ❤️ 【点赞】 让优质内容被更多人看见,让知识传递更有力量。 ⭐ 【收藏】 把核心知识点存好,在需要时随时查、随时用。 💬 【评论】 分享你的经验或疑问,评论区一起交流避坑! 不要忘记给博主"一键四连"哦! "今日练剑达成!" "技术之路难免有困惑,但同行的人会让前进更有方向。" |

结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!

往期回顾:

【AI大模型接入SDK】ChatServer问题修复

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
志尊宝1 小时前
AI原生前端开发(023):端侧AI多模态应用开发
人工智能·ai-native
linktokenview1 小时前
文生图与图生视频大模型对比
人工智能
雨晨源码(同名B站)1 小时前
深度学习毕业设计选题推荐:基于YOLO11的交通标志检测系统设计与实现(Python+Django+Vue3+对接deepseek)
人工智能·python·深度学习·机器学习·django·课程设计
蓝祁子yoky1 小时前
Qt学习日记 Day15:网络编程(二)- UDP基础
网络·qt·学习
vjmap1 小时前
AI 地图动画-以真实地图为画布的 AI 视频编辑器-唯杰 AI 地图动画正式上线
人工智能·编辑器·音视频·gis·cad
海盗12341 小时前
微软技术日报 2026-11-01:语言模型 API 免申请、8 个威胁组织被分四档
人工智能·microsoft·语言模型·机器人·人工智能aigc
D e re k ZH1 小时前
C++ 模板与泛型编程进阶(No 2)
开发语言·c++
lingxiao168881 小时前
Halcon之OCR应用
人工智能·ocr