当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > Go 接 Ollama API 做模型健康检查:版本、模型存在性与超时处理

Go 接 Ollama API 做模型健康检查:版本、模型存在性与超时处理

来源:17golang原创 2026-08-10 12:58:24 0浏览 收藏
所属专题:AI 流式输出可靠性实战专题 - SSE、断线重连与事件去重

本地 Ollama 服务“能访问”不等于“能稳定生成”。实际接入 Go 服务时,常见故障是 11434 端口还在监听,但目标模型没有安装;或者模型第一次加载太慢,业务网关先把请求切断。健康检查应该分成三层:先拿版本确认服务响应,再读模型清单确认名称,最后用一个短的非流式请求验证真正的生成路径。

要点速览
  • /api/version 只证明 Ollama API 可响应,不能证明目标模型存在。
  • /api/tags 用于核对模型名,不能把本地别名和业务配置混在一起。
  • 短探针要设置独立超时,并把“模型未安装”和“加载太慢”分成不同状态。
  • keep_alive 影响下一次请求的首包延迟,也直接影响显存或内存占用。

先把“服务在线”和“模型可用”拆开

Ollama 默认把本地 API 暴露在 http://localhost:11434/api。Go 程序先调用 GET /api/version,这一步适合做进程级存活检查;随后调用 GET /api/tags,从返回的 models[].name 中寻找业务配置的模型名。

这两个接口都成功时,结论仍然只是“服务和模型清单可读”。如果模型刚被删除、配置写成了错误的 tag,真正生成时仍会失败。所以健康检查要保留三个结果字段,而不是只返回一个布尔值:

检查层接口能确认什么不能确认什么
进程/api/versionAPI 可响应、版本可读目标模型是否安装
模型/api/tags模型名、大小、摘要模型能否完成生成
能力/api/generate加载与生成链路可用长文本质量和业务正确性

Go 调用 Ollama API 依次检查版本、模型清单和生成能力的三层门禁

Go 客户端先统一地址和截止时间

不要在每个检查函数里拼接地址或各自创建超时。下面的客户端只负责 HTTP 传输,具体检查结果交给上层组合;健康接口本身可以给它 2 到 3 秒,生成探针则单独放宽到模型冷启动能够承受的时间。

type OllamaClient struct {
    BaseURL string
    HTTP    *http.Client
}

func NewOllamaClient(base string) *OllamaClient {
    return &OllamaClient{
        BaseURL: strings.TrimRight(base, "/"),
        HTTP:    &http.Client{},
    }
}

func (c *OllamaClient) getJSON(ctx context.Context, path string, out any) error {
    req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.BaseURL+path, nil)
    if err != nil {
        return err
    }
    res, err := c.HTTP.Do(req)
    if err != nil {
        return err
    }
    defer res.Body.Close()
    if res.StatusCode = 300 {
        return fmt.Errorf("ollama %s returned %s", path, res.Status)
    }
    return json.NewDecoder(res.Body).Decode(out)
}

这里的 http.Client 没有设置全局 Timeout,是因为每次探针的截止时间由 context.WithTimeout 控制,后续还可以按检查类型增加独立的重试或连接参数。服务端返回非 2xx 时,保留状态码和接口路径,排障时比一句“检查失败”有用得多。

版本和模型清单检查要返回可解释状态

type versionReply struct {
    Version string `json:"version"`
}

type modelReply struct {
    Models []struct {
        Name string `json:"name"`
        Size int64  `json:"size"`
    } `json:"models"`
}

func (c *OllamaClient) CheckCatalog(ctx context.Context, want string) (string, bool, error) {
    var ver versionReply
    if err := c.getJSON(ctx, "/api/version", &ver); err != nil {
        return "", false, err
    }

    var list modelReply
    if err := c.getJSON(ctx, "/api/tags", &list); err != nil {
        return ver.Version, false, err
    }
    for _, item := range list.Models {
        if item.Name == want {
            return ver.Version, true, nil
        }
    }
    return ver.Version, false, nil
}

调用方可以把结果写成 api_unreachablemodel_missingcatalog_ok。其中模型名要使用 Ollama 返回的完整名称,例如带 tag 的 gemma3:4b,不要用展示名称去猜测。

最后用短生成请求验证真正能力

模型清单通过后,再发一个固定且很短的探针。要显式设置 stream:false,否则 /api/generate 默认可能返回逐行 JSON 流;健康接口只需要确认最终响应里有 done:true,不需要收集一段长文本。

type generateRequest struct {
    Model     string `json:"model"`
    Prompt    string `json:"prompt"`
    Stream    bool   `json:"stream"`
    KeepAlive string `json:"keep_alive,omitempty"`
}

type generateReply struct {
    Response string `json:"response"`
    Done     bool   `json:"done"`
    Reason   string `json:"done_reason"`
}

func (c *OllamaClient) Probe(ctx context.Context, model string) error {
    body := generateRequest{Model: model, Prompt: "只回复 OK", Stream: false, KeepAlive: "5m"}
    raw, err := json.Marshal(body)
    if err != nil {
        return err
    }
    req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.BaseURL+"/api/generate", bytes.NewReader(raw))
    if err != nil {
        return err
    }
    req.Header.Set("Content-Type", "application/json")
    res, err := c.HTTP.Do(req)
    if err != nil {
        return err
    }
    defer res.Body.Close()
    if res.StatusCode = 300 {
        return fmt.Errorf("probe returned %s", res.Status)
    }
    var reply generateReply
    if err := json.NewDecoder(res.Body).Decode(&reply); err != nil {
        return err
    }
    if !reply.Done {
        return errors.New("probe did not finish")
    }
    return nil
}

探针提示词越短越好,避免把健康检查变成内容生成任务。业务服务可以只在启动、发布或告警恢复时跑一次;不建议每秒对模型发探针,否则检查本身会制造负载。

Go Ollama 生成探针区分模型未安装、超时和完成状态,并结合 keep_alive 控制驻留

超时、模型未安装和常驻内存要分别处理

连接超时:服务可能没启动或地址不对

dial tcp ... connection refused 更像进程或地址问题;它不应该被标成模型质量问题。检查容器网络、OLLAMA_HOST 和实际监听地址,再决定是否告警。

模型未安装:清单检查比生成报错更早

如果 /api/tags 中没有目标模型,直接调用生成只会把故障推迟到用户请求上。发布时先执行 ollama pull 并重新跑清单检查,应用侧将状态标为 model_missing,不要无限重试。

冷启动超时:检查窗口要和模型大小匹配

第一次生成通常还包含模型加载,健康检查的超时不能照搬版本接口的 2 秒。可以把“清单通过、生成超时”记录成 model_loading_slow,并在发布或扩容阶段预热,而不是立即判定 Ollama 不可用。

Ollama 文档说明,keep_alive 可以用时长、秒数、负数或 0 控制模型驻留;设置为 0 会在本次生成后卸载,设置为较长时长则减少下一次冷启动,但会占用更多内存。这个参数应成为容量策略的一部分,而不是随手写死在探针里。

把三层结果接入发布门禁

发布脚本可以按下面的顺序执行:

  1. 用短截止时间调用 /api/version,失败则标记 api_unreachable
  2. 调用 /api/tags 查找完整模型名,缺失则标记 model_missing
  3. 用更长窗口发送一次 stream:false 探针,超时则标记 model_loading_slow
  4. 三层都通过后再放行依赖本地模型的流量,记录版本、模型名和探针耗时。

若把这些状态统一成一个绿色或红色开关,运维人员仍然要重新登录机器找原因。保留分层状态,才能知道是 Ollama 没启动、模型没拉下来,还是冷启动窗口太短。

常见问题

/api/version 返回成功,为什么生成仍然失败?

版本接口只能证明 API 进程能响应,不能证明目标模型存在,也不能证明模型已经加载成功。还要检查 /api/tags 和一次短生成探针。

健康检查应该使用 /api/generate 还是 /api/chat

检查生成能力时,两者都可以;如果业务实际使用对话接口,探针应采用同一接口和消息形状。无论哪种接口,都建议关闭流式返回,降低检查逻辑复杂度。

为什么不直接调用 ollama list

命令行适合机器本地运维,Go 服务更适合访问 HTTP API。API 返回的模型名和摘要可以直接写入结构化检查结果,也不依赖子进程环境。

keep_alive: 0 适合生产探针吗?

它能释放模型占用,但每次检查都可能触发下一次冷启动。低频发布门禁可以这样做;在线流量场景要结合模型大小和内存预算决定驻留时间。

让健康检查回答“哪里坏了”

Go 接 Ollama 时,最小可靠闭环不是一个 GET 请求,而是版本、模型清单和短生成三道门。把接口不可达、模型缺失、冷启动过慢和生成完成分别记录,再根据 keep_alive 做内存取舍,告警才能直接指向处理动作。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go 回调地址怎么做 SSRF 防护:域名白名单、解析结果与跳转控制Go 回调地址怎么做 SSRF 防护:域名白名单、解析结果与跳转控制
上一篇
Go 回调地址怎么做 SSRF 防护:域名白名单、解析结果与跳转控制
Redis CLIENT TRACKING 怎么验收:失效通知、BCAST 与 NOLOOP 边界
下一篇
Redis CLIENT TRACKING 怎么验收:失效通知、BCAST 与 NOLOOP 边界
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ljg-skills -
    ljg-skills
    ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
    4841次使用
  • MELO音乐 - AI 音乐生成平台,支持多模态创作能力
    MELO音乐
    MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
    4431次使用
  • UniScribe - AI 免费在线音视频转文字平台
    UniScribe
    UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
    4373次使用
  • 剧云 - 免费 AI 智能中文剧本创作平台
    剧云
    剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
    4607次使用
  • 万象有声 - AI 一站式有声内容创作平台
    万象有声
    万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
    4563次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码