C大模型SDK会话管理模块实现大语言模型本身不会保存会话上下文多轮对话中的会话、消息和时间状态必须由业务侧手动维护同时多线程并发访问会话管理器时必须做线程安全控制。C大模型接入SDK中的SessionManager正是围绕这两个约束设计的会话管理模块。来源说明以下实现与接口来自一篇CSDN社区文章的示例代码属于社区作者的个人实践总结未经官方核验。文中所有代码、接口命名和设计取舍均以该社区文章为参照不代表任何官方SDK的规范或承诺。会话基础概念该社区文章将会话定义为用户与大模型之间一组连续交互的集合用于维护聊天上下文与会话状态保障多轮对话语义连贯。其核心存储模型是 session_id 到 Session 的映射通过会话ID快速定位会话。完整的业务需求包括创建会话并分配唯一 sessionid、绑定模型名称按 sessionid 查询会话向指定会话追加用户或模型消息获取指定会话全部历史消息用于组装给大模型的上下文请求获取全部会话ID列表供 UI 展示删除指定会话更新最后更新时间戳清空全部会话获取当前会话总数生成全局唯一 sessionid 和会话内唯一的 messageid以及线程安全。公共数据结构在数据结构上common.h 定义了 Message 和 Session。Message 包含messageId、role、_content其中 _role 取 user、assistant 或 system构造函数只接收 role 和 content_messageId 后续生成。Session 包含 _sessionId、modelName、messages、createdAt、updatedAt_messages 是 vector构造函数初始化 modelName并把创建时间和更新时间设为当前时间。// common.h #pragma once #include string #include vector #include ctime struct Message { std::string _messageId; std::string _role; std::string _content; Message(const std::string role, const std::string content) : _role(role), _content(content) {} }; struct Session { std::string _sessionId; std::string _modelName; std::vectorMessage _messages; std::time_t _createdAt; std::time_t _updatedAt; explicit Session(const std::string modelName ) : _modelName(modelName), _createdAt(std::time(nullptr)), _updatedAt(std::time(nullptr)) {} };SessionManager 接口设计SessionManager.h 的接口覆盖上述业务createSession、getSession、addMessage、getHistoryMessages、updateSessionTimestamp、getSessionLists、deleteSession、clearAllSessions、getSessionCount。私有工具包括 generateSessionId 和 generateMessageId。成员变量有三个关键点一是 unorderedmapptr _sessions二是 mutable std::mutex _mutex三是 std::atomic _sessionCounter{0}。// SessionManager.h #pragma once #include unordered_map #include mutex #include memory #include atomic #include vector #include string #include ctime #include sstream #include algorithm #include common.h namespace ai_chat_sdk { class SessionManager { public: std::string createSession(const std::string modelName); std::shared_ptrSession getSession(const std::string sessionId) const; bool addMessage(const std::string sessionId, const Message message); std::vectorMessage getHistoryMessages(const std::string sessionId) const; void updateSessionTimestamp(const std::string sessionId); std::vectorstd::string getSessionLists() const; bool deleteSession(const std::string sessionId); void clearAllSessions(); size_t getSessionCount() const; private: std::string generateSessionId(); std::string generateMessageId(size_t messageCounter); std::unordered_mapstd::string, std::shared_ptrSession _sessions; mutable std::mutex _mutex; std::atomicint64_t _sessionCounter{0}; }; } // namespace ai_chat_sdk关键设计要点存储选择使用 unorderedmapptr。该社区文章明确不直接存储 Session 对象值以避免 map 容器存储大量大对象带来的拷贝开销会话对象放在堆内存由智能指针管理生命周期。key 是会话ID字符串平均 O(1) 查找。mutable 修饰互斥锁const 成员函数承诺不修改对象业务数据但锁的 lock/unlock 会修改 mutex 内部状态普通 mutex 无法在 const 函数中使用mutable 专门用于这种场景。原子变量 _sessionCounter用于无锁线程安全自增多线程并发创建会话不会出现序号重复。对外接口以 sessionid 为契约该社区文章的设计意图是让外部模块通过 sessionid 操作会话以降低模块耦合适配持久化 SQLite 数据库 CURD并避免跨进程传递裸内存指针。但需要指出getSession 返回 sharedptr外部调用方可以持有该指针并直接修改 Session 内容因此“不暴露内部 Session 对象”这一表述并不严格成立。作者分析若严格遵循该设计意图getSession 应改为返回只读视图或消息副本若保留 sharedptr 返回则必须在文档中明确调用方不得在锁外修改 Session否则会绕过互斥锁造成数据竞争。源文件实现源文件实现中createSession 先用 lockguard 加锁调用 generateSessionId 生成唯一会话ID再通过 makeshared 在堆上构造对象设置sessionId 后存入哈希表最后返回 sessionid。getSession 加锁后查找不存在返回 nullptr存在则返回 shared_ptr。addMessage 加锁后查找会话不存在返回 false以当前 _messages.size() 作为消息序号入参构造新 Message设置messageId 为 generateMessageId(msgSeq)pushback 进消息列表并把 _updatedAt 更新为当前时间返回 true。getHistoryMessages 加锁查找不存在返回空 vector存在则返回 _messages。updateSessionTimestamp 加锁查找不存在直接返回存在则更新 _updatedAt。getSessionLists 同样加锁返回全部会话ID列表并按 _updatedAt 降序排列使最新会话排在最前面。// SessionManager.cpp #include SessionManager.h #include iomanip namespace ai_chat_sdk { std::string SessionManager::createSession(const std::string modelName) { std::lock_guardstd::mutex lock(_mutex); std::string sessionId generateSessionId(); auto session std::make_sharedSession(modelName); session-_sessionId sessionId; _sessions[sessionId] session; return sessionId; } std::shared_ptrSession SessionManager::getSession(const std::string sessionId) const { std::lock_guardstd::mutex lock(_mutex); auto iter _sessions.find(sessionId); if (iter _sessions.end()) { return nullptr; } return iter-second; } bool SessionManager::addMessage(const std::string sessionId, const Message message) { std::lock_guardstd::mutex lock(_mutex); auto iter _sessions.find(sessionId); if (iter _sessions.end()) { return false; } size_t msgSeq iter-second-_messages.size(); Message newMsg(message._role, message._content); newMsg._messageId generateMessageId(msgSeq); iter-second-_messages.push_back(newMsg); iter-second-_updatedAt std::time(nullptr); return true; } std::vectorMessage SessionManager::getHistoryMessages(const std::string sessionId) const { std::lock_guardstd::mutex lock(_mutex); auto iter _sessions.find(sessionId); if (iter _sessions.end()) { return {}; } return iter-second-_messages; } void SessionManager::updateSessionTimestamp(const std::string sessionId) { std::lock_guardstd::mutex lock(_mutex); auto iter _sessions.find(sessionId); if (iter _sessions.end()) { return; } iter-second-_updatedAt std::time(nullptr); } std::vectorstd::string SessionManager::getSessionLists() const { std::lock_guardstd::mutex lock(_mutex); std::vectorstd::pairstd::time_t, std::string tmp; for (const auto kv : _sessions) { tmp.emplace_back(kv.second-_updatedAt, kv.first); } std::sort(tmp.begin(), tmp.end(), [](const auto a, const auto b) { return a.first b.first; }); std::vectorstd::string result; result.reserve(tmp.size()); for (const auto p : tmp) { result.push_back(p.second); } return result; } bool SessionManager::deleteSession(const std::string sessionId) { std::lock_guardstd::mutex lock(_mutex); return _sessions.erase(sessionId) 0; } void SessionManager::clearAllSessions() { std::lock_guardstd::mutex lock(_mutex); _sessions.clear(); } size_t SessionManager::getSessionCount() const { std::lock_guardstd::mutex lock(_mutex); return _sessions.size(); } std::string SessionManager::generateSessionId() { int64_t seq _sessionCounter.fetch_add(1); std::time_t now std::time(nullptr); std::ostringstream oss; oss session_ now _ std::setw(8) std::setfill(0) seq; return oss.str(); } std::string SessionManager::generateMessageId(size_t messageCounter) { std::time_t now std::time(nullptr); std::ostringstream oss; oss msg_ now _ std::setw(8) std::setfill(0) messageCounter; return oss.str(); } } // namespace ai_chat_sdk线程安全与ID生成线程安全实现依赖 std::lockguard 的 RAII 机制进入函数自动加锁离开作用域自动释放。ID 生成规则为 session时间戳8位序号和 msg时间戳8位序号。作者分析sessionid 使用全局原子计数器sessionCounter 生成序号可保证全局唯一messageid 使用当前会话messages.size() 作为序号只能保证会话内唯一不同会话在同一秒内可能生成相同的 msg时间戳00000000因此不能保证全局唯一。若业务需要 messageid 全局唯一应改用全局原子计数器、UUID或在 ID 中拼接 session_id。内存模型内存模型使用 sharedptr让会话对象生命周期由智能指针接管规避裸指针风险。该社区文章还列出常见面试考点unorderedmap 与 map 的会话存储选型、mutable 关键字使用场景、std::atomic fetchadd、RAII 锁 std::lockguard以及会话管理器的扩展方向。工程分析从工程分析角度看这套实现把模型无状态与业务侧有状态解耦以 session_id 为外部契约内部用哈希表、互斥锁、原子计数和智能指针支撑多轮对话上下文维护。作者建议该结构可作为 C 大模型接入 SDK 会话管理层的参考起点但生产环境仍需按实际 SDK 约束、持久化方案和并发模型进行验证与调整。
企业数字化 ERP 产品动态
相关推荐
C#文字修仙游戏源码解析:数值驱动架构与核心系统实现 简介:这份资源是面向C#初学者与毕业设计学生的文字修仙游戏完整源码包,以WinForms桌面程序形式实现,帮助读者理解游戏主循环、场景管理、数据持久化与事件驱动等核心开发流程。压缩包共75个文件,约2MB,其中15个cs源文件… · 2026/9/23 18:47:15
Quick Reference 速查手册:Grep 命令从入门到正则表达式实战指南 Quick Reference 速查手册:Grep 命令从入门到正则表达式实战指南 【免费下载链接】reference 为开发人员分享快速参考备忘清单(速查表) 项目地址: https://gitcode.com/jaywcjlove/reference
grep 是 Linux/Unix 命令行世界最常用的文本搜索工具,… · 2026/9/23 18:47:09
Ekko Agent 配置页面:Hermes Studio 中内置 Agent 的内存、技能与 MCP 配置面详解 AI 应用人工智能AI Agent本地部署前端后端工作流自动化 【免费下载链接】ekko-studio Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web. 项目地址: https://gitcode.com/gh_mirr… · 2026/9/23 18:47:09
Atlas 300V 24G推理加速卡与YOLOv5部署全流程解析 先说一个我几乎每周都能在群里看到的提问:Atlas 300V 24G是运算加速卡吗?这类问题通常出现在有人第一次接触昇腾推理硬件时。我的回答很直接:是,但它做的事情和大多数人想象中的“运算加速”不太一样。它不是用来训练模型的&#… · 2026/9/23 19:20:35
Atlas 300V 24G部署YOLOv5全流程:从模型转换到推理调优的昇腾实战指南 做AI部署这几年,Atlas这个词在我这儿出现的频率直线上升。早几年聊推理加速,大家默认就是英伟达的卡,CUDA、TensorRT一套组合拳打天下。但昇腾系列冒头之后,越来越多的项目在选型阶段就会问一句:能不能用Atlas跑&#… · 2026/9/23 19:20:35
中文微博情感分析源码拆包:从贝叶斯到BERT的完整基线 简介:这份资源面向计算机、人工智能、通信、自动化等相关专业的本科生与研究生,以及需要完成课程设计、大作业或毕业设计的开发者,提供一套完整的中文微博情感分析项目源码与配套文档。项目围绕中文微博文本展开,覆盖朴素贝叶斯、… · 2026/9/23 19:20:35
2026最新无人机机巢性能优化:告别卡顿与死机,效率提升5倍 2026最新无人机机巢性能优化:告别卡顿与死机,效率提升5倍 打开官方文档,是不是感觉像读天书?几十页的协议参数、复杂的通信时序图,看得人头晕眼花,却抓不住重点。其实,2026最新的无人机机巢开发中,最大的坑不在硬件,而在软件层的资源调度与… · 2026/9/23 19:20:35
面试必问Coldfusion核心源码拆解与版本升级避坑指南 面试必问Coldfusion核心源码拆解与版本升级避坑指南 版本升级后 API 全变了,这是很多老 Java 开发者转岗或接手遗留系统时最头疼的问题。尤其是 Adobe ColdFusion 这种在金融、医疗行业大量存在的遗留技术,一旦从… · 2026/9/23 19:20:28
PX4 VTOL 无空速传感器飞行:参数配置、日志分析与失速安全实战指南 嵌入式物联网机器人自动驾驶智能硬件 【免费下载链接】PX4-Autopilot PX4 Autopilot Software 项目地址: https://gitcode.com/gh_mirrors/px/PX4-Autopilot 点击查看 免费下载 VTOL(垂直起降)固定翼飞行器依赖空速传感器来判断流过机翼的气… · 2026/9/23 19:20:22
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29