Skip to content

Ollama 编程语言调用

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


官方 SDK:Python 与 JavaScript

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

安装

bash

# 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 调用,覆盖前面几篇学过的大部分能力:

实例

python

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 中的等价写法:

实例

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 指定:

实例

python

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 接入本地模型:

实例

javascript

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 同理:

实例

python

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、流式、历史管理拼成一个可用的终端聊天工具。

实例

python

# 文件路径: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
$ python cli_chat.py
开始对话(模型 qwen3.5:4b),输入 exit 退出。

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

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

你:exit

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


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

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

chat-app-arch.svg

后端:Flask 封装 Ollama 流式接口

实例

bash

# 文件路径: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 流式读取

实例

javascript

// 浏览器端:逐行读取 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)

  }

}

运行与验证

实例

bash

# 启动后端

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 应用实战章节会继续扩展它。

AI 思考中...

Ollama 六大模型能力实战

Ollama 工具和编辑器集成

基于 VitePress 构建,部署于 GitHub Pages