Ollama 的 DeepSeek API 怎么接入 Python?保留多轮消息并读取流式回答

用 Python 标准库调用 Ollama Chat API,逐行处理 NDJSON、保留两轮消息历史,并识别中断和只有思考的响应。

Python 接入 Ollama 本地 DeepSeek,使用的是本机 /api/chat 接口。多轮聊天需要客户端保存并重新发送消息历史;流式回答则按每行一个 JSON 对象读取。不能把多个 JSON 块直接交给一次 json.load,也不能把思考字段当成最终回答正文。

确认本地服务和实际模型

准备 Python 3.10 或更新版本,先在终端执行 ollama ls,确认已有 deepseek-r1:7b,且本地 Ollama 正在运行。未安装模型时先完成安装和下载;本文重点是已有模型的 Python 接入,不重复基础安装步骤。

Ollama 的 DeepSeek API 怎么接入 Python?保留多轮消息并读取流式回答

模型名称可在 官方模型库 核对。Chat API 文档 规定 model、messages 和 stream 等请求字段;这里使用本地模型,不填写远端 DeepSeek 平台的 API Key。

先用非流式请求检查字段

在 PowerShell 发一条最小请求,先确认是接口连通问题还是客户端解析问题:

$payload = @{
  model = 'deepseek-r1:7b'
  messages = @(@{role='user'; content='只回答一个数字:17 加 25 等于多少?'})
  stream = $false
} | ConvertTo-Json -Depth 5
$r = Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:11434/api/chat' `
  -ContentType 'application/json; charset=utf-8' `
  -Body ([Text.Encoding]::UTF8.GetBytes($payload))
$r.done
$r.message.content

验收条件是 done=True,message.content 有答案,并且最终答案可核对。Chat 接口读取 message.content;不要照搬 Generate 接口的顶层 response 字段。

保存两轮消息,并读取流式正文

把下面代码保存为 chat_client.py,执行 python chat_client.py。它只用 Python 标准库,不需要另外安装 SDK。代码中的青禾是人为构造的会话验证例子,不能当成真实业务记录。

"""Article example: Ollama NDJSON chat with bounded history."""
import json
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen

MODEL = 'deepseek-r1:7b'
URL = 'http://127.0.0.1:11434/api/chat'

def read_reply(lines):
    content, thinking = [], []
    finished = False
    for line in lines:
        if not line.strip():
            continue
        item = json.loads(line.decode('utf-8'))
        if item.get('error'):
            raise RuntimeError(item['error'])
        message = item.get('message', {})
        text = message.get('content', '')
        if text:
            print(text, end='', flush=True)
            content.append(text)
        if message.get('thinking'):
            thinking.append(message['thinking'])
        if item.get('done') is True:
            if item.get('done_reason') == 'length':
                raise RuntimeError('达到输出上限,回答截断,未记入会话')
            finished = True
            break
    print()
    answer = ''.join(content)
    if not finished or not answer.strip():
        raise RuntimeError('回答中断或最终正文为空,未记入会话')
    reply = {'role': 'assistant', 'content': answer}
    if thinking:
        reply['thinking'] = ''.join(thinking)
    return reply

def chat(history, question):
    pending = history + [{'role': 'user', 'content': question}]
    request = Request(
        URL, data=json.dumps({'model': MODEL, 'messages': pending,
                              'stream': True}).encode('utf-8'),
        headers={'Content-Type': 'application/json'}, method='POST')
    with urlopen(request, timeout=300) as response:
        reply = read_reply(response)
    return pending + [reply]

if __name__ == '__main__':
    messages = []
    try:
        messages = chat(messages, '演示:我的项目代号是青禾。请复述代号。')
        messages = chat(messages, '上一轮的项目代号是什么?只回答代号。')
        print('保存的消息数:', len(messages))
    except (HTTPError, URLError, TimeoutError, ValueError, RuntimeError) as exc:
        print('请求失败:', exc)
        raise SystemExit(1)

依据 Streaming 文档,默认流式返回使用 NDJSON,也就是每行一个 JSON。示例把普通正文块拼接,思考内容另存;只有读到 done=true、未因输出上限截断且最终正文非空,才把这一轮记入历史。官方服务实现把输出长度上限对应的结束原因表示为 length;它也会结束生成,不能只看 done。

第二轮会把第一轮的用户消息与助手回复一起发送。正确完成两轮时,保存的消息数为 4;第二轮应根据历史回答“青禾”。这验证的是应用确实传递了上下文,不证明模型永远能正确记住长对话。

处理失败和长会话

  • 连接失败:确认 Ollama 后台已启动,地址和端口一致;此代码只连接本机回环地址。
  • 模型不存在:对照 ollama ls 的完整标签,先修正配置,不能用“DeepSeek”泛称替代。
  • 已经打印部分文字却中断:示例会报错,失败轮次不会追加到历史。界面应标记该回答未完成,不能把半段文字当成功结果。
  • HTTP 错误或 NDJSON 中的 error:保存脱敏错误原文后处理。没有自动重发,避免把同一问题重复入账或重复显示。

这里的 300 秒是网络读操作超时设置,不是整次生成的总时限。长会话不能无限追加历史:根据实际上下文预算裁剪较早的完整轮次,或生成经用户核对的摘要;不要只删用户消息而保留孤立的助手回复。需要持久化时还要区分用户和会话,避免不同人的历史混在一起。

示例验证范围

本文的流解析函数用构造的 NDJSON 数据验证了中文分块拼接、错误块、缺失结束块、输出上限截断以及只有思考没有最终正文的处理。这些是客户端解析检查,不是 DeepSeek 模型实测;未在你的电脑上调用本地模型。接口资料核验于 2026 年 10 月 1 日,实际回答与硬件可运行性需自行验证。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30132.html

赞 (0)
AI小管家的头像AI小管家
DeepSeek Excel 去重怎么做?按编号保留最新记录并导出复核表
上一篇 1天前
DeepSeek 图表代码怎么用?读取 CSV 并用 Matplotlib 导出 PNG
下一篇 1天前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部