
个人主页艾莉丝努力练剑❄专栏传送门《C语言》《数据结构与算法》《C/C干货分享学习过程记录》《Linux操作系统编程详解》《笔试/面试常见算法从基础到进阶》《Python干货分享》⭐️为天地立心为生民立命为往圣继绝学为万世开太平 艾莉丝的简介文章目录1 ~ Ollama API 基础认知1.1 核心能力与接口定位1.2 通用约定1.2.1 模型命名规则1.2.2 时长单位1.2.3 流式响应约定2 ~ /api/chat 全量返回接口规范2.1 接口基本信息2.2 请求参数体系2.2.1 必选参数2.2.2 可选高级参数2.3 响应报文结构2.4 响应核心字段说明3 ~ 环境验证与常见排障3.1 curl 接口验证命令3.2 常见故障排查3.2.1 代理冲突问题3.2.2 首次请求慢问题4 ~ C 全量返回实现流程4.1 实现总流程4.2 模型有效性检测4.3 请求参数构造4.3.1 超参数提取4.3.2 历史消息构建4.4 请求体构建与序列化4.5 HTTP 客户端配置与请求发送4.6 响应反序列化与内容提取5 ~ 单元测试与工程配置5.1 测试用例编写5.2 CMake 构建配置6 ~ 扩展知识点6.1 推理模型思考字段6.2 结构化输出支持结尾1 ~ Ollama API 基础认知1.1 核心能力与接口定位Ollama 是本地大模型部署与推理服务通过标准化 REST API 封装屏蔽不同模型的参数差异对外提供统一的调用入口。聊天补全场景核心接口为/api/chat支持流式响应与全量响应两种模式本次聚焦全量返回模式stream: false。1.2 通用约定1.2.1 模型命名规则采用模型名:标签格式例如deepseek-r1:1.5b标签用于标识具体版本与参数量。1.2.2 时长单位所有时间类字段统一以纳秒为单位返回。1.2.3 流式响应约定接口默认启用流式响应逐块返回 JSON 对象通过stream: false可关闭流式一次性返回完整响应对象。2 ~ /api/chat 全量返回接口规范2.1 接口基本信息请求方法POST接口路径/api/chat默认服务地址http://127.0.0.1:11434Content-Typeapplication/json2.2 请求参数体系2.2.1 必选参数model字符串类型指定调用的模型名称符合模型命名约定。messages数组类型存储对话历史消息用于维持对话上下文记忆。单条消息对象字段role消息角色取值为system、user、assistant、tool。content字符串类型消息文本内容。images可选数组类型多模态模型传入的图片列表。tool_calls可选数组类型模型发起的工具调用请求列表。2.2.2 可选高级参数stream布尔类型控制是否启用流式响应false为全量返回模式。format字符串类型指定响应返回格式支持json或自定义 JSON Schema用于实现结构化输出。optionsJSON 对象模型推理超参数核心字段包括temperature浮点型控制生成随机性取值范围 0~1值越高创造性越强。num_ctx整型上下文窗口大小默认值 2048对应其他平台的max_tokens语义。支持 Modelfile 中定义的其他模型参数。keep_alive字符串类型控制模型在请求后保留在内存中的时长默认 5 分钟。tools数组类型模型可调用的工具列表JSON 格式需模型支持。2.3 响应报文结构全量模式下返回单一 JSON 对象标准结构如下{model:deepseek-r1:1.5b,created_at:2026-08-28T04:56:59.195988466Z,message:{role:assistant,content:\n\n您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何问题,我会尽我所能为您提供帮助。},done:true,done_reason:stop,total_duration:39751163910,load_duration:1337544202,prompt_eval_count:6,prompt_eval_duration:1795779000,eval_count:40,eval_duration:35587041000}2.4 响应核心字段说明model本次响应使用的模型名称。created_at响应生成时间戳ISO 8601 格式。message模型回复消息对象包含role与content字段。done布尔类型标识响应是否完成全量模式下恒为true。done_reason结束原因stop表示正常结束。total_duration请求总耗时单位纳秒。load_duration模型加载耗时单位纳秒。prompt_eval_count输入 Prompt 的 Token 数量。prompt_eval_duration输入 Prompt 推理耗时单位纳秒。eval_count输出回复的 Token 数量。eval_duration输出生成耗时单位纳秒。3 ~ 环境验证与常见排障3.1 curl 接口验证命令标准全量返回验证请求命令curl-s-XPOSThttp://127.0.0.1:11434/api/chat\-HContent-Type: application/json\-d{ model: deepseek-r1:1.5b, stream: false, messages: [ { role: user, content: 你是谁? } ], options: { temperature: 0.7, num_ctx: 2048 } }3.2 常见故障排查3.2.1 代理冲突问题现象请求无响应、连接超时或失败。成因系统环境变量配置了 HTTP 代理curl 默认继承代理配置导致本地请求被代理转发。排查步骤检查并关闭终端代理环境变量执行source ~/.bashrc重新加载环境配置。检查 curl 配置文件~/.curlrc注释掉代理配置行。重启终端后重新执行请求。3.2.2 首次请求慢问题现象首次调用接口耗时显著高于后续调用。成因Ollama 需要将模型从磁盘加载到内存中属于冷启动开销。说明属于正常现象模型加载完成后后续请求速度显著提升可通过keep_alive参数延长模型驻留时间。4 ~ C 全量返回实现流程4.1 实现总流程模型有效性检测构造请求参数温度、上下文窗口、历史消息构建并序列化 JSON 请求体创建 HTTP 客户端并配置超时发送 POST 请求响应状态校验JSON 反序列化提取模型回复内容4.2 模型有效性检测// 发送消息-全量返回std::stringOllamaLLMProvider::sendMessage(conststd::vectorMessagemessages,conststd::mapstd::string,std::stringrequestParam){// 检查模型是否可用if(!isAvailable()){ERR(OllamaLLMProvider::sendMessage: model is not available);return;}4.3 请求参数构造4.3.1 超参数提取从请求参数中提取温度与上下文窗口大小未配置则使用默认值// 构造温度值和上下文Token数floattemperature0.7f;intnumCtx2048;if(requestParam.find(temperature)!requestParam.end()){temperaturestd::stof(requestParam.at(temperature));}if(requestParam.find(max_tokens)!requestParam.end()){numCtxstd::stoi(requestParam.at(max_tokens));}4.3.2 历史消息构建将内部消息结构转换为 JSON 数组格式// 构建历史消息数组Json::ValuemessageArray(Json::arrayValue);for(constautomessage:messages){Json::ValuemessageObject(Json::objectValue);messageObject[role]message._role;messageObject[content]message._content;messageArray.append(messageObject);}4.4 请求体构建与序列化**注意**Ollama 接口中上下文窗口参数字段为num_ctx而非通用的max_tokens。// 构建options超参数对象Json::Valueoptions(Json::objectValue);options[temperature]temperature;options[num_ctx]numCtx;// 构建完整请求体Json::ValuerequestBody(Json::objectValue);requestBody[model]_modelName;requestBody[messages]messageArray;requestBody[options]options;requestBody[stream]false;// 序列化请求体为字符串Json::StreamWriterBuilder writerBuilder;std::string requestBodyStrJson::writeString(writerBuilder,requestBody);4.5 HTTP 客户端配置与请求发送// 创建HTTP客户端配置超时时间httplib::Clientclient(_endpoint.c_str());client.set_connection_timeout(30,0);// 连接超时30秒client.set_read_timeout(60,0);// 读取超时60秒// 设置请求头httplib::Headers headers{{Content-Type,application/json}};// 发送POST请求autoresponseclient.Post(/api/chat,headers,requestBodyStr,application/json);if(!response){ERR(OllamaLLMProvider::sendMessage: failed to send request, error: {},to_string(response.error()));return;}INFO(OllamaLLMProvider::sendMessage: response status: {},response-status);INFO(OllamaLLMProvider::sendMessage: response body: {},response-body);// 校验响应状态码if(response-status!200){ERR(OllamaLLMProvider::sendMessage: failed to send request, status: {},response-status);return;}4.6 响应反序列化与内容提取// 响应JSON反序列化Json::Value responseBody;Json::CharReaderBuilder reader;std::string errors;std::istringstreamresponseStream(response-body);if(!Json::parseFromStream(reader,responseStream,responseBody,errors)){ERR(OllamaLLMProvider::sendMessage: failed to parse response body, errors: {},errors);return;}// 提取模型回复内容std::string modelResponse;if(responseBody.isMember(message)responseBody[message].isObject()responseBody[message].isMember(content)){modelResponseresponseBody[message][content].asString();INFO(OllamaLLMProvider::sendMessage: modelResponse: {},modelResponse);returnmodelResponse;}// 响应格式异常处理ERR(OllamaLLMProvider::sendMessage: invalid response format);return;}5 ~ 单元测试与工程配置5.1 测试用例编写基于 Google Test 框架的标准测试用例TEST(OllamaLLMProviderTest,sendMessage){autoproviderstd::make_sharedai_chat_sdk::OllamaLLMProvider();ASSERT_TRUE(provider!nullptr);// 模型配置std::mapstd::string,std::stringmodelParam;modelParam[model_name]deepseek-r1:1.5b;modelParam[model_desc]本地部署deepseek-r1:1.5b模型,采用专家混合架构,专注于深度理解与推理;modelParam[endpoint]http://localhost:11434;provider-initModel(modelParam);ASSERT_TRUE(provider-isAvailable());// 请求参数配置std::mapstd::string,std::stringrequestParam{{temperature,0.7},{max_tokens,2048}};// 构造测试消息std::vectorai_chat_sdk::Messagemessages;messages.push_back({user,你是谁?});// 调用接口std::string fullDataprovider-sendMessage(messages,requestParam);ASSERT_FALSE(fullData.empty());}5.2 CMake 构建配置project(testLLM) # 设置C标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 设置构建类型 set(CMAKE_BUILD_TYPE Debug) # 添加可执行文件 add_executable(testLLM testLLM.cpp ../sdk/src/util/myLog.cpp ../sdk/src/DeepSeekProvider.cpp ../sdk/src/ChatGPTProvider.cpp ../sdk/src/GeminiProvider.cpp ../sdk/src/OllamaLLMProvider.cpp ) # 设置输出目录 set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) # 添加头文件搜索路径 include_directories(${CMAKE_PROJECT_INCLUDE_DIR}/../sdk/include) # 依赖库配置 find_package(OpenSSL REQUIRED) include_directories(${OPENSSL_INCLUDE_DIR}) # 编译宏定义 target_compile_definitions(testLLM PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT) # 链接依赖库 target_link_libraries(testLLM jsoncpp fmt spdlog gtest OpenSSL::SSL OpenSSL::Crypto )6 ~ 扩展知识点6.1 推理模型思考字段部分推理增强模型如 DeepSeek-R1会在回复内容中包含 标签内部存储模型推理思考过程。SDK 默认直接返回完整内容思考字段的解析与过滤由上层业务自行处理。6.2 结构化输出支持通过format参数传入 JSON Schema可强制模型输出符合指定结构的 JSON 数据。适用于需要固定格式返回的业务场景如分类、信息提取、结构化生成等。结尾uu们本文的内容到这里就全部结束了艾莉丝在这里再次感谢您的阅读艾莉丝努力练剑C/C Linux 底层探索者 | 一个正在努力练剑的技术博主【关注】跟随我一起深耕技术领域见证每一次成长。❤️【点赞】让优质内容被更多人看见让知识传递更有力量。⭐【收藏】把核心知识点存好在需要时随时查、随时用。【评论】分享你的经验或疑问评论区一起交流避坑不要忘记给博主“一键四连”哦“今日练剑达成”“技术之路难免有困惑但同行的人会让前进更有方向。”结语希望对学习Linux相关内容的uu有所帮助不要忘记给博主“一键四连”哦往期回顾【AI大模型接入SDK】Ollama大模型接入架构对比与实现博主在这里放了一只小狗大家看完了摸摸小狗放松一下吧૮₍ ˶ ˊ ᴥ ˋ˶₎ა