python 访问 ollama api

模型与算力

写给 Python 开发者:怎么用代码连上本地 Ollama 服务跑模型,从装依赖、发请求到流式输出和排查连接失败。

本地已经把模型跑起来了,但一写到 Python 里就卡住:不知道该装哪个包、服务地址填什么、流式输出怎么接、报连接错误又该先看哪一步。这篇按「先确认服务能用,再换成代码调」的顺序走一遍,给出可直接抄的调用骨架和排查顺序。涉及端口、模型名这类会变的参数,都告诉你到站内对应页面去核对。

本地已经把模型跑起来了,但一写到 Python 里就卡住:不知道该装哪个包、服务地址填什么、流式输出怎么接、报连接错误又该先看哪一步。这篇按「先确认服务能用,再换成代码调」的顺序走一遍,给出可直接抄的调用骨架和排查顺序。

涉及端口、模型名这类会变的参数,正文里不写死,一律告诉你到站内对应页面去核对当时的数字。下面每个小节都配了能立刻动手的动作,别只读不试。

先确认服务本身是通的,再写 Python

命令行里能用交互界面跑通模型,不代表后台的 HTTP 服务已经开着,这两件事是分开的。很多人第一次卡住就是这里:界面能用,脚本一跑就连接被拒。写代码之前先确认服务进程在监听本地端口。

  1. 确认进程在跑用系统自带的进程查看方式确认服务进程存在;不存在就先手动起一次,别在代码里瞎试。
  2. 打一次最简单接口用浏览器或 curl 访问服务根路径和模型列表接口,能看到返回就说明 HTTP 层通了。
  3. 确认模型名从模型列表里挑一个真实存在的名字,后面代码里只填这个名字,别凭记忆写。
  4. 再上生成先用最简单的一次生成请求打通全链路,成功之后才考虑流式。

服务地址和端口以站内「本地部署 ollama 服务的 api 地址」那页写的为准,别照抄别人博客里的默认值,别人改过配置或者跑在容器里,地址就不是你以为的那个。

两条调用路子:官方 Python 库和 HTTP 直连

Python 调本地模型,本质上就两条路。选哪条不看哪个高级,看你的使用场景:自己跑试验、写一次性脚本,用官方库最省事;要嵌进已有服务、要接自己的日志和重试中间件,就自己发 HTTP 请求。

官方 Python 库
装好包之后几行就能跑,适合快速验证和本地脚本;缺点是版本迭代快,参数名可能对不上你手上的文档
HTTP 直连
用 requests 或 httpx 自己拼 JSON,好处是能直接复用你已有的重试、超时、日志中间件
共同前提
模型名一定要写成服务端真实存在的那个,写错会报找不到模型,而不是报参数错
场景推荐路子理由
本地试验、一次性脚本官方库代码最短,改起来快
嵌进已有服务HTTP 直连超时、重试、并发上限自己控
需要自定义日志HTTP 直连能挂在自己那套中间件上
批量跑离线任务看情况先测一次基线再决定,别凭感觉

依赖装哪个版本别抄文章里的版本号,到站内模型资料库对应页面看当时的说明。装完先写一个最小脚本跑通一次生成,再加参数。

import requests

BASE = "http://127.0.0.1:11434"  # 以站内页面实际地址为准
resp = requests.post(
    f"{BASE}/api/generate",
    json={"model": "你的模型名", "prompt": "你好", "stream": False},
    timeout=60,
)
resp.raise_for_status()
print(resp.json().get("response"))

流式输出怎么接、怎么不卡住

流式的本质是服务端一段段吐 JSON 行,客户端要按行读、逐块解析,不能一次性等整个响应读完再处理。你要做的第一件事是把 stream 参数打开,然后改成逐行读,而不是继续用等完整响应那种写法。

  • 按行迭代响应体,每一行单独解析,别把它当普通字符串直接拼
  • 每段都可能是半截 JSON,解析失败先跳过或累积再试,不要直接抛异常退出
  • 做打字机效果时,把「拼文本」和「渲染」拆到两层,渲染不要放在读网络那一层
  • 处理完或中途退出,记得把响应和连接关掉,长跑脚本不关会堆积
  • 对延迟敏感的场景先测一次基线,用站内接口测速页量一量首次响应和逐字吐字的大致水平

有个常见坑:把流式响应当普通字符串处理,结果只拿到第一段就以为模型只回了一句。另一个坑是超时按非流式设置,流式本来就更久,超时太短会在中间被掐断,表现出来像「模型卡住了」。

import json, requests

with requests.post(
    f"{BASE}/api/generate",
    json={"model": "你的模型名", "prompt": "你好", "stream": True},
    stream=True, timeout=(10, 300),
) as r:
    for line in r.iter_lines():
        if not line:
            continue
        chunk = json.loads(line)
        print(chunk.get("response", ""), end="", flush=True)

连不上的排查顺序

连接失败是这类任务里最高频的问题,而且原因往往不在代码里。按下面的顺序从上往下查,别一上来就怀疑自己的 Python 写得不对。

  1. 看服务在不在进程没起或中途崩了,代码里报什么都是表象;先确认服务是活的。
  2. 看地址对不对本机脚本和服务不在同一台机器时,别用本机回环地址;跨机器要确认服务对外开放了监听。
  3. 看网络与防火墙容器里跑的脚本常常连不到宿主机端口,这类问题占排查时间的大头,先问清楚脚本跑在哪。
  4. 看代码层超时设太短、代理环境变量把本地请求也带走了,都会表现成「连不上」;临时清掉代理变量再试一次。
  5. 看错误原文把异常信息完整打出来,连接被拒和超时是两类问题,别用同一套办法硬治。
现象优先怀疑先做的动作
连接被拒服务没起或端口不对确认进程和监听地址
请求超时流式被当非流式、超时太短拉长超时并改逐行读
找不到模型模型名写错从模型列表里复制名字
一会儿通一会儿不通并发或资源占用降并发,先单请求跑通
容器里全失败网络模式没配对确认脚本能访问宿主机的服务端口

如果折腾半天还是失败,站内的连接失败排查清单可以直接照着走一遍,里面按错误类型分了常见原因和对应动作,比盲目改代码省时间。

最后提醒一句:接口地址、服务端口、模型名这些值会随部署方式变,文章里给的是结构不是常量。真要落地之前,到站内页面核对当时的那几个数字,再动手写。

下一步把地址、模型名和测速基线先在站内核对一遍,再回来跑上面的骨架,能省掉大半排查时间。

常见问题

用 Python 调本地 Ollama 需要 API Key 吗?

本地自建的服务通常不需要,因为请求根本没出你的机器。但如果你把它挂到公网、或者前面套了网关,就该按网关的要求带凭证。关于要不要设、怎么设,站内有专门的 api key 主题页面,先去核对再决定,别默认「本地就一定不用」。

为什么命令行能跑,Python 里就报连接失败?

大概率不是模型的问题,而是访问路径的问题:服务只监听了本机回环地址、你在容器或另一台机器里发请求;或者代码里配了全局代理,把本地请求也转发出去了。按「服务在不在→地址对不对→网络通不通→代码配置」这个顺序查,通常前三步就能定位。

流式返回和一次性返回,该用哪个?

看交互形态。要做聊天界面、让用户尽早看到字,用流式;要批量跑任务、把结果存库或再加工,用一次性返回更省事,代码也简单。同一条链路里别混着用,否则超时设置和错误处理会变得很难维护。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。