当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > 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_unreachable、model_missing 或 catalog_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推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    256次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    301次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    277次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    257次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    62次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码