【AI大模型接入SDK】 —— 前端页面 & 项目总结与拓展

🌈欢迎来到实战项目专栏 ~~ 从零实现AI大模型接入SDK

AI大模型接入SDK

🌏前端页面

前端页面直接让ai生成,提示词可以参考⼀下内容


假设你是一个具有十年前端的开发经验的资深工程师,请帮我按照如下要求实现一个前端页面。

我实现了一个智能聊天助手的服务器,服务器地址是192.168.100.238,端口是8080。

服务端代码以及所有接口均进行了严格的测试,没有问题。

服务器提供以下功能:

  1. 获取所有会话列表
  2. 获取可用模型
  3. 创建新会话
  4. 获取会话历史消息
  5. 发送消息 - 流式响应
  6. 删除会话

接口的请求和响应参数以json格式组织,接口具体定义如下:

1. 获取会话列表

请求URL:GET /api/sessions

返回响应:200 OK

响应格式:

json 复制代码
{
  "success" : "bool",       // 是否成功
  "message" : "string",     // 结果描述
  "data": [                 // 响应数据
      {
          "id" : "string",             // 会话id
          "model" : "string",          // 模型名称
          "created_at" : "int64_t",    // 会话创建时间
          "updated_at" : "int64_t",    // 会话更新时间
          "message_count" : "int",     // 对话次数
          "first_user_message" : "string"   // 第一条正文消息
      }
  ]
}

2. 获取可用模型

请求URL:GET /api/models

返回响应:200 OK

响应格式:

json 复制代码
{
  "success" : "bool",       // 是否成功
  "message" : "string",     // 结果描述
  "data": [                 // 响应数据
      {
          "name" : "string",    // 模型名称
          "desc" : "string"     // 模型描述
      }
  ]
}

3. 创建新会话

请求URL:POST /api/session

请求参数:

json 复制代码
{
  "model" : "string"        // 模型名称
}

返回响应:200 OK

响应格式:

json 复制代码
{
  "success" : "bool",       // 是否成功
  "message" : "string",     // 结果描述
  "data": {                 // 响应数据
      "session_id" : "string",   // 会话id
      "model" : "string"         // 模型名称
  }
}

4. 发送消息 - 流式响应

请求URL:POST /api/message/async

请求参数:

json 复制代码
{
  "session_id" : "string",  // 会话id
  "message" : "string"      // 消息内容
}

返回响应:200 OK

流式响应,格式如下:

复制代码
data: 正文\n\n
data: 正文\n\n
data: 正文\n\n
data: [DONE]

5. 删除会话

请求URL:DELETE /api/session/${session_id}

返回响应:200 OK

响应格式:

json 复制代码
{
  "success" : "bool",       // 是否成功
  "message" : "string"      // 结果描述
}

6. 获取会话历史

请求URL:GET /api/session/${session_id}/history

返回响应:200 OK

响应格式:

json 复制代码
{
  "success" : "bool",
  "message" : "string",
  "data": [
    {
      "id" : "string",
      "role" : "string",
      "content" : "string",
      "timestamp" : 0
    }
  ]
}

结合以上内容帮我生成一个前端页面,类似于deepseek的网页聊天助手,页面要求如下:

  1. 前端页面的html、JavaScript、css等代码分开存放

  2. 页面左上角有一个AIChat图标,图标之后跟 "AI聊天助手" 的文本,文本之后紧跟一个按钮,按钮上文本为"新建对话",点击按钮之后,会创建新会话。

  3. 页面左侧栏为历史会话列表,每条会话信息展示:会话更改时间、会话第一条消息、模型名称、以及删除会话按钮,按钮文本为"...",点击删除按钮会删除该会话,同步删除服务器上session_id的会话

  4. 网页右侧默认为一个图标,图标下是一段文本,"选择一个历史对话继续,或创建新的对话,开启您的AI之旅",文本下是一个按钮,按钮文本是"新建对话",点击按钮会创建新会话

  5. 点击新建对话按钮,要弹出一个无边框窗口,窗口内部以网格方式展示所支持的模型,支持所有模型在会话中以单选按钮展示且包含模型描述,用户需要选择本次会话的模型,选择好之后点击确定按钮,本次会话就创建完成,模型选择窗口关闭;点击取消按钮则不创建会话,模型选择窗口也自动关闭。注意:每次只能选择一个模型

  6. 会话创建成功之后,主页面85%高度为聊天消息显示区域,消息展示区域左侧展示模型消息,右侧展示用户消息,每条消息下方紧跟消息收发时间

  7. 消息显示区域下方为用户输入问题的编辑框,在未输入文本时,框内提示"请输入您的消息...(Enter发送,Shift+Enter换行)",用户输入文本后提示消失,消息编辑框右侧为发送按钮,按钮下显示用户消息文本总字数/输入文本最大限制(最大限制2000字)

  8. 从服务器获取到index.html之后,客户端需自动到服务器获取会话列表,将会话列表信息显示在页面左侧

  9. 点击页面左上角和右侧偏下位置"新建对话"按钮时,需要到服务器获取支持的模型列表,用户选择模型并点击确定按钮之后,创建新会话,将该会话加入页面左侧,开始新一轮会话

  10. 对于流式消息,服务器返回的是标准SSE格式,比如:

    data: 文本数据\n\n
    data: 文本数据\n\n
    data: [DONE]

对服务器返回的流式数据以markdown格式解析,代码放到代码块中语法高亮显示,代码支持一键复制

注意:服务器返回的流式数据可能会较多,避免数据过长而导致界面变形或者乱码

  1. 要求整个页面协调美观,颜色搭配舒适

生成提示词

生成页面

🌏SessionManager线程安全问题

通过查看vector的实现细节,我们发现容器都不是线程安全的,之前我们在实现的时候并没有考虑到,所以现在要进行修改!

cpp 复制代码
//通过会话id获取会话信息
std::shared_ptr<Session> SessionManager::getSession(const std::string &sessionId) {
    //先在内存中对_sessions进行查找 
    std::lock_guard<std::mutex> lock(_mutex);  //自动加锁和解锁
    auto it = _sessions.find(sessionId);
    if(it != _sessions.end())   
    {   
        //获取当前会话的历史信息:从数据库中补充缺失的消息_messages
        it->second->_messages = _dataManager.getMessages(sessionId);
        return it->second;
    }

    //在内存中找不到,则从数据库中获取
    auto session = _dataManager.getSession(sessionId);
    if(session)
    {
        auto it = _sessions.find(sessionId);
        if (it == _sessions.end()) {         //在内存确实没有找到,将会话添加到会话列表中
            _sessions[sessionId] = session;  //懒加载缓存,如果不写回,下次获取时还是没有
        }
        //不需要从数据库中补充缺失的消息,getSession中已经获取了
        return session;
    }
    WARN("Session not found: {}", sessionId);
    return nullptr;
}

也就是要把解锁放在对容器的操作之后,而不是之前...

又发现日志打印也有可能被多个线程执行,所以此处干脆改成一个RAII的锁即可

对于SessionManager的其他函数逐个分析

  • generateSessionId:生成会话id,是在创建会话函数里实现的,已经在一个加锁环境里了
  • generateMessageId:生成消息id同理,发送新消息里创建的,也已经加锁
  • createSession:创建会话,要注意因为insertSession操作是加了锁的,所以这个函数我们手动的加锁
  • getHistoryMessages:同上

剩余函数的逻辑都没有怎么变,只有getSession这里的线程有问题

🌏遇到的Bugs

这里遇到的bug还是挺多的:

  • 没有考虑到函数的出口出错的问题等等...
  • Markdown格式解析
  • 代码块复制问题 & 模型不响应等等

通过这些bugs可以回看之前写的代码,加强了对项目的理解吧

🌏项目拓展

1️⃣可以尝试接入一下其他的大模型

2️⃣支持用户注册的功能

3️⃣支持ToolCalling,比如发送邮件、查询数据库。让大模型能够自动调用工具完成具体的事宜

🌏项目总结

1️⃣从零开始,使用C++语言接入DeepSeek-v4-flash、gemini-3.7-flash、gpt-5.6-sol 三种云端模型 ,以及通过ollama接入本地下载 的deepseek-r1:1.5b,并且将模型接入代码封装成了SDK

2️⃣利用封装好的SDK实现了一个智能聊天助手的应用

  • 掌握AI相关的基础知识:大模型相关的名词、不同大模型产品的使用介绍、大模型相关岗位

  • 掌握trae、apifox、cmake、ollama

  • 掌握spdlog、gflags、gtest、jsoncpp、httplib等第三方库在项目中的使用

  • 掌握大模型接入的思路

    • 到官方申请apikey
    • 查看官方文档中提供访问模型的API接口,了解接口的功能,以及熟悉接口的请求参数格式、以及响应的格式
  • 使用第三方工具对接口进行快速验证:apifox、curl

    • 编码开发
  • 掌握单例模式、策略模式的使用

  • 掌握流式响应处理,SSE数据格式,如何通过httplib库实现流式响应

  • 掌握ollama工具的使用,比如如何下载模型、查看下载模型、当前运行模型,以及运行模型...

  • 掌握sqlite数据的使用,以及如何使用C++代码操作sqlite数据库

  • 掌握什么是SDK,如何封装SDK,SDK的安装,以及cmake文件的编写

  • 掌握如何让大模型帮助我们生成代码,提示词,如何与大模型交互解决项目中的问题

📢写在最后

完结撒花

相关推荐
石狮松松1 分钟前
第 05 章 你的第一行"AI"代码:拟合一条直线
人工智能
用户360055579001 分钟前
Kestrel_VLLM - 14 · router 两个方向判否,与 decode 的真瓶颈
人工智能
狒狒AI4 分钟前
Remotion / GSAP+Three / HyperFrames / Skia 四栈实测:代码渲染知识视频的选栈方法(附开源技能)
前端·人工智能·aigc
修炼的dance5 分钟前
浏览器里导出H.265,8.5秒和55.5秒差在硬件
前端
补码缩写6 分钟前
WebCodecs选编码器,探测之后还要验解码和播放
前端
大文说跨境7 分钟前
亚马逊多账号管理浏览器怎么选?云登/紫鸟/AdsPower 对比
java·前端·自动化
自养Agent9 分钟前
Agent Harness 从用到会造:报错的那层,往往不是坏掉的那层
人工智能
RockChinQ9 分钟前
一个 Telegram 群,三条事件路由:欢迎、群规问答与群管理各归一个 Agent
人工智能
hunter_0769 分钟前
iOS 首页复杂嵌套滚动技术方案:头部固定 + 网格滚动 + Tab 吸顶 + 每 Tab 独立下拉刷新
前端
果霸大叔12 分钟前
从根上吃透AI Agent:Agent拆解系列之DeerFlow2.0深度拆解
人工智能