现在位置: 首页 > Ollama 教程 > 正文

Ollama 编程语言调用

本篇系统梳理调用 Ollama 的四条代码路线:Python 官方库、JavaScript 官方库、原生 HTTP、以及 OpenAI / Anthropic 兼容 SDK,并用两个实战项目把它们串起来。


官方 SDK:Python 与 JavaScript

官方提供两个一手维护的库,接口设计保持一致,会一个就等于会两个。

安装

# Python
pip install ollama

# JavaScript / TypeScript
npm install ollama

两个库的核心方法对照:

方法用途关键参数
chat多轮对话(主力方法)model、messages、stream、tools、think、format、options
generate单轮文本生成model、prompt、stream、suffix
embed向量嵌入model、input(单条或数组)
list列出本地模型无
pull拉取模型(可监听进度)model、stream

Python 中一次带全参数的 chat 调用,覆盖前面几篇学过的大部分能力:

实例

from ollama import chat
from pydantic import BaseModel

# 定义结构化输出的 schema
class Answer(BaseModel):
    site: str
    free: bool

response = chat(
    model='qwen3.5',
    messages=[{'role': 'user', 'content': '介绍 RUNOOB 菜鸟教程'}],
    stream=False,                        # 流式开关
    think=False,                         # 思考模式开关
    format=Answer.model_json_schema(),   # 结构化输出 schema
    options={'temperature': 0.3, 'num_ctx': 8192},  # 生成参数
)

print(Answer.model_validate_json(response.message.content))

JavaScript 中的等价写法:

实例

import ollama from 'ollama'

// 流式对话示例
const stream = await ollama.chat({
  model: 'qwen3.5',
  messages: [{ role: 'user', content: '用三句话介绍 RUNOOB' }],
  stream: true,
})

// 逐块输出
let content = ''
for await (const chunk of stream) {
  process.stdout.write(chunk.message.content)
  content += chunk.message.content
}

连接非默认地址(如远程服务器或 Ollama Cloud)时,用 host 与 headers 指定:

实例

import os
from ollama import Client

# 连接远程 Ollama 或 Ollama Cloud(Bearer 认证)
client = Client(
    host='https://ollama.com',
    headers={'Authorization': 'Bearer ' + os.environ.get('OLLAMA_API_KEY')},
)

response = client.chat(model='qwen3.5', messages=[
    {'role': 'user', 'content': '用一句话介绍 RUNOOB'}
])

原生 HTTP:curl 速查

写脚本、调试接口、排查问题时,curl 是最快的工具。

场景命令
单轮生成(非流式)curl http://localhost:11434/api/generate -d '{"model":"qwen3.5","prompt":"你好","stream":false}'
对话curl http://localhost:11434/api/chat -d '{"model":"qwen3.5","messages":[...],"stream":false}'
向量嵌入curl http://localhost:11434/api/embed -d '{"model":"embeddinggemma","input":"文本"}'
列出模型curl http://localhost:11434/api/tags
模型详情curl http://localhost:11434/api/show -d '{"model":"qwen3.5"}'
拉取模型curl http://localhost:11434/api/pull -d '{"model":"qwen3.5:4b"}'
删除模型curl -X DELETE http://localhost:11434/api/delete -d '{"model":"qwen3.5:4b"}'

复用 OpenAI / Anthropic SDK

已有项目迁移时,兼容层比重写省事得多。

JavaScript 项目里用 OpenAI SDK 接入本地模型:

实例

import OpenAI from "openai"

// 只改 base_url,api_key 随意填写
const openai = new OpenAI({
  baseURL: "http://localhost:11434/v1",
  apiKey: "ollama",
})

const res = await openai.chat.completions.create({
  model: "qwen3.5",
  messages: [{ role: "user", content: "用一句话介绍 RUNOOB" }],
})
console.log(res.choices[0].message.content)

Python 项目里用 Anthropic SDK 同理:

实例

import anthropic

# base_url 指向本地,key 随意填写
client = anthropic.Anthropic(
    base_url='http://localhost:11434',
    api_key='ollama',
)

message = client.messages.create(
    model='qwen3.5',
    max_tokens=1024,
    messages=[{'role': 'user', 'content': '用一句话介绍 RUNOOB'}],
)
print(message.content[0].text)

选择建议:新项目直接用官方 SDK(能力最全);存量项目按现有 SDK 走兼容层(改动最小);被某个只认 OpenAI 协议的框架集成时,兼容层是唯一通路。


实战一:命令行聊天脚本

用不到 40 行 Python,把前面学的 chat、流式、历史管理拼成一个可用的终端聊天工具。

实例

# 文件路径:cli_chat.py
# 运行:python cli_chat.py
from ollama import chat

MODEL = 'qwen3.5:4b'

# 会话历史:system 定角色,后续追加对话
messages = [{
    'role': 'system',
    'content': '你是 RUNOOB 的编程助手,回答简洁并给出示例代码。',
}]

print(f'开始对话(模型 {MODEL}),输入 exit 退出。')
while True:
    user_input = input('\n你:').strip()
    if user_input.lower() == 'exit':
        break
    if not user_input:
        continue

    # 追加用户消息并发起流式请求
    messages.append({'role': 'user', 'content': user_input})
    stream = chat(model=MODEL, messages=messages, stream=True)

    # 逐块打印,同时累积完整回答
    print('助手:', end='', flush=True)
    reply = ''
    for chunk in stream:
        reply += chunk.message.content
        print(chunk.message.content, end='', flush=True)

    # 关键:把本轮回答追加回历史,模型才能"记住"上文
    messages.append({'role': 'assistant', 'content': reply})
$ python cli_chat.py
开始对话(模型 qwen3.5:4b),输入 exit 退出。

你:什么是 Python 的切片?
助手:切片是用 [start:stop:step] 从序列中取子序列的语法,
例如 s[1:3] 取索引 1 到 2 的元素。

你:给个 RUNOOB 风格的例子
助手:s = "RUNOOB"
print(s[1:4])   # 输出 UNO

你:exit

核心只有一处:每轮把 user 消息和 assistant 完整回答都 append 进 messages。模型本身无状态,"记忆"完全来自这个列表。


实战二:带记忆的多轮对话 Web 应用

把同样的思路搬上浏览器,需要一个后端居中协调:管理会话历史、调用 Ollama、把流式结果转发给前端。

带记忆的聊天应用架构

后端:Flask 封装 Ollama 流式接口

实例

# 文件路径:server.py
# 安装依赖:pip install flask ollama
from flask import Flask, request, Response, stream_with_context
from ollama import chat

app = Flask(__name__)

# 会话历史暂存内存:真实项目应换成数据库
sessions = {}

@app.route('/chat')
def do_chat():
    session_id = request.args.get('session', 'default')
    user_input = request.args.get('q', '')
    if not user_input:
        return {'error': '缺少 q 参数'}

    # 取出(或初始化)该会话的历史
    history = sessions.setdefault(session_id, [
        {'role': 'system', 'content': '你是 RUNOOB 的编程助手。'}
    ])
    history.append({'role': 'user', 'content': user_input})

    # 流式生成,NDJSON 格式逐行转发给前端
    def generate():
        reply = ''
        stream = chat(model='qwen3.5:4b', messages=history, stream=True)
        for chunk in stream:
            reply += chunk.message.content
            yield chunk.message.content + '\n'
        # 关键:把完整回答写回历史,形成记忆
        history.append({'role': 'assistant', 'content': reply})

    return Response(
        stream_with_context(generate()),
        mimetype='application/x-ndjson',
    )

if __name__ == '__main__':
    app.run(port=5000)

前端:fetch 流式读取

实例

// 浏览器端:逐行读取 NDJSON 并实时渲染
async function ask(question) {
  const resp = await fetch(
    `/chat?session=demo&q=${encodeURIComponent(question)}`
  )
  const reader = resp.body.getReader()
  const decoder = new TextDecoder()

  while (true) {
    const { done, value } = await reader.read()
    if (done) break
    // 每读到一块就追加到页面,实现打字机效果
    document.getElementById('answer').textContent +=
      decoder.decode(value)
  }
}

运行与验证

实例

# 启动后端
python server.py

# 模拟两次连续请求,验证记忆
curl "http://localhost:5000/chat?session=demo&q=什么是Python切片"
curl "http://localhost:5000/chat?session=demo&q=再给个RUNOOB风格的例子"

第二次请求中模型能顺着"切片"话题继续作答,说明服务端管理的会话历史生效了;换一个 session 参数则是一个全新会话,互不干扰。

这个几十行的骨架已经覆盖了类 ChatGPT 应用的三大要素:会话隔离(session 参数)、流式体验(NDJSON 转发)、记忆持久(历史写回)。加上数据库存储和多会话列表,就是完整实战项目的雏形,Web 应用实战章节会继续扩展它。