Files
metona-ai-desktop/apis/ollama-api-docs-20260518.html
T
thzxx 1d185db6b3 feat: MetonaAI Desktop 初始项目
- Electron + React + TypeScript 架构
- 三栏布局: Sidebar | ChatPanel | DetailPanel
- 9 个内置工具 (文件系统/网络/记忆/命令)
- SQLite 持久化 (better-sqlite3)
- MUI 暗色/亮色主题系统
- Agent Loop ReAct 状态机引擎
- DeepSeek / Agnes AI / Ollama Provider 适配器
- MCP 协议集成
- 系统托盘 + 全局快捷键
- Tailwind CSS v4 + Tailwind Merge
- 修复: Sidebar 缺失 TextField 导入导致黑屏
2026-06-27 21:33:27 +08:00

1877 lines
112 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ollama API 完整接口文档 | 20260518</title>
<style>
:root {
--bg: #0f1117;
--bg-card: #1a1d27;
--bg-code: #12141c;
--bg-nav: #141620;
--text: #e1e4ed;
--text-dim: #8b8fa7;
--accent: #6c9eff;
--accent2: #a78bfa;
--green: #34d399;
--orange: #fb923c;
--red: #f87171;
--cyan: #22d3ee;
--border: #2a2d3a;
--get: #34d399;
--post: #6c9eff;
--delete: #f87171;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.7;
display: flex;
}
/* === SIDEBAR === */
.sidebar {
position: fixed;
top: 0; left: 0;
width: 280px;
height: 100vh;
background: var(--bg-nav);
border-right: 1px solid var(--border);
overflow-y: auto;
z-index: 100;
padding: 24px 0;
}
.sidebar-logo {
padding: 0 20px 20px;
border-bottom: 1px solid var(--border);
margin-bottom: 16px;
}
.sidebar-logo h2 {
font-size: 20px;
background: linear-gradient(135deg, var(--accent), var(--accent2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
display: flex;
align-items: center;
gap: 8px;
}
.sidebar-logo .badge {
font-size: 11px;
background: var(--accent);
color: #fff;
padding: 2px 8px;
border-radius: 10px;
-webkit-text-fill-color: #fff;
}
.sidebar-section {
padding: 8px 20px;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 1.2px;
color: var(--text-dim);
font-weight: 600;
}
.sidebar a {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 20px;
color: var(--text-dim);
text-decoration: none;
font-size: 13.5px;
transition: all 0.15s;
}
.sidebar a:hover, .sidebar a.active {
color: var(--text);
background: rgba(108, 158, 255, 0.06);
}
.sidebar a .method {
font-size: 10px;
font-weight: 700;
padding: 1px 6px;
border-radius: 3px;
min-width: 42px;
text-align: center;
font-family: 'SF Mono', 'Fira Code', monospace;
}
.method-get { background: rgba(52,211,153,0.15); color: var(--get); }
.method-post { background: rgba(108,158,255,0.15); color: var(--post); }
.method-delete { background: rgba(248,113,113,0.15); color: var(--delete); }
/* === MAIN === */
.main {
margin-left: 280px;
flex: 1;
min-height: 100vh;
}
.hero {
background: linear-gradient(135deg, rgba(108,158,255,0.08), rgba(167,139,250,0.08));
border-bottom: 1px solid var(--border);
padding: 60px 60px 50px;
}
.hero h1 {
font-size: 36px;
font-weight: 800;
background: linear-gradient(135deg, var(--accent), var(--accent2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 12px;
}
.hero p {
color: var(--text-dim);
font-size: 16px;
max-width: 680px;
}
.hero-meta {
display: flex;
gap: 24px;
margin-top: 20px;
flex-wrap: wrap;
}
.hero-meta span {
font-size: 13px;
color: var(--text-dim);
display: flex;
align-items: center;
gap: 6px;
}
.hero-meta .dot {
width: 6px; height: 6px;
border-radius: 50%;
display: inline-block;
}
.dot-green { background: var(--green); }
.dot-blue { background: var(--accent); }
.dot-orange { background: var(--orange); }
.content {
padding: 40px 60px 100px;
max-width: 1000px;
}
/* === SECTION === */
.api-section {
margin-bottom: 60px;
scroll-margin-top: 20px;
}
.api-section h2 {
font-size: 24px;
font-weight: 700;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 12px;
}
.api-section .desc {
color: var(--text-dim);
font-size: 15px;
margin-bottom: 24px;
}
/* === ENDPOINT BAR === */
.endpoint-bar {
display: flex;
align-items: center;
gap: 12px;
background: var(--bg-code);
border: 1px solid var(--border);
border-radius: 10px;
padding: 12px 18px;
margin-bottom: 24px;
font-family: 'SF Mono', 'Fira Code', monospace;
font-size: 14px;
}
.endpoint-bar .http-method {
font-weight: 700;
padding: 4px 10px;
border-radius: 5px;
font-size: 12px;
}
.endpoint-bar .url {
color: var(--text);
}
/* === PARAMS TABLE === */
.params-title {
font-size: 14px;
font-weight: 600;
color: var(--accent);
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
table.params {
width: 100%;
border-collapse: collapse;
margin-bottom: 28px;
font-size: 13.5px;
}
table.params th {
text-align: left;
padding: 10px 14px;
background: var(--bg-card);
border-bottom: 1px solid var(--border);
color: var(--text-dim);
font-weight: 600;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.8px;
}
table.params td {
padding: 10px 14px;
border-bottom: 1px solid rgba(42,45,58,0.5);
vertical-align: top;
}
table.params tr:last-child td { border-bottom: none; }
.param-name {
font-family: 'SF Mono', 'Fira Code', monospace;
color: var(--cyan);
font-weight: 600;
font-size: 13px;
}
.param-type {
font-family: 'SF Mono', 'Fira Code', monospace;
color: var(--accent2);
font-size: 12px;
}
.param-required {
color: var(--red);
font-size: 11px;
font-weight: 600;
}
.param-optional {
color: var(--text-dim);
font-size: 11px;
}
.param-default {
color: var(--text-dim);
font-size: 12px;
}
/* === CODE BLOCK === */
.code-tabs {
display: flex;
gap: 0;
border-bottom: 1px solid var(--border);
margin-bottom: 0;
}
.code-tab {
padding: 10px 20px;
font-size: 13px;
font-weight: 600;
color: var(--text-dim);
cursor: pointer;
border-bottom: 2px solid transparent;
transition: all 0.15s;
background: transparent;
border-top: none;
border-left: none;
border-right: none;
}
.code-tab:hover { color: var(--text); }
.code-tab.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.code-block {
background: var(--bg-code);
border: 1px solid var(--border);
border-top: none;
border-radius: 0 0 10px 10px;
padding: 20px;
overflow-x: auto;
margin-bottom: 24px;
}
.code-block pre {
margin: 0;
font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
font-size: 13px;
line-height: 1.65;
color: var(--text);
}
.code-panel { display: none; }
.code-panel.active { display: block; }
/* Syntax colors */
.hl-kw { color: var(--accent2); }
.hl-str { color: var(--green); }
.hl-num { color: var(--orange); }
.hl-cm { color: var(--text-dim); font-style: italic; }
.hl-fn { color: var(--accent); }
.hl-prop { color: var(--cyan); }
/* === RESPONSE === */
.response-title {
font-size: 14px;
font-weight: 600;
color: var(--green);
margin-bottom: 10px;
}
.response-block {
background: var(--bg-code);
border: 1px solid var(--border);
border-radius: 10px;
padding: 20px;
overflow-x: auto;
margin-bottom: 28px;
}
.response-block pre {
margin: 0;
font-family: 'SF Mono', 'Fira Code', monospace;
font-size: 13px;
line-height: 1.65;
color: var(--text);
}
/* === DIVIDER === */
.section-divider {
border: none;
height: 1px;
background: var(--border);
margin: 60px 0;
}
/* === OVERVIEW TABLE === */
.overview-table {
width: 100%;
border-collapse: collapse;
margin: 24px 0 40px;
font-size: 13.5px;
}
.overview-table th {
text-align: left;
padding: 12px 16px;
background: var(--bg-card);
border-bottom: 2px solid var(--border);
color: var(--text-dim);
font-weight: 600;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.8px;
}
.overview-table td {
padding: 10px 16px;
border-bottom: 1px solid rgba(42,45,58,0.5);
}
.overview-table a {
color: var(--accent);
text-decoration: none;
}
.overview-table a:hover { text-decoration: underline; }
/* === SCROLLBAR === */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }
/* === NOTE BOX === */
.note-box {
background: rgba(108,158,255,0.06);
border-left: 3px solid var(--accent);
border-radius: 0 8px 8px 0;
padding: 14px 18px;
margin-bottom: 24px;
font-size: 13.5px;
color: var(--text-dim);
}
.note-box strong { color: var(--accent); }
@media (max-width: 900px) {
.sidebar { display: none; }
.main { margin-left: 0; }
.hero { padding: 30px 24px; }
.content { padding: 24px; }
}
</style>
</head>
<body>
<!-- ========== SIDEBAR ========== -->
<nav class="sidebar">
<div class="sidebar-logo">
<h2>🦧 Ollama API <span class="badge">最新</span></h2>
</div>
<div class="sidebar-section">概述</div>
<a href="#overview">📋 接口总览</a>
<a href="#quickstart">⚡ 快速开始</a>
<a href="#model-options">⚙️ 模型参数 Options</a>
<div class="sidebar-section">生成接口</div>
<a href="#generate"><span class="method method-post">POST</span> /api/generate</a>
<a href="#chat"><span class="method method-post">POST</span> /api/chat</a>
<a href="#embed"><span class="method method-post">POST</span> /api/embed</a>
<div class="sidebar-section">模型管理</div>
<a href="#tags"><span class="method method-get">GET</span> /api/tags</a>
<a href="#show"><span class="method method-post">POST</span> /api/show</a>
<a href="#create"><span class="method method-post">POST</span> /api/create</a>
<a href="#copy"><span class="method method-post">POST</span> /api/copy</a>
<a href="#delete"><span class="method method-delete">DELETE</span> /api/delete</a>
<a href="#pull"><span class="method method-post">POST</span> /api/pull</a>
<a href="#push"><span class="method method-post">POST</span> /api/push</a>
<div class="sidebar-section">运行时</div>
<a href="#ps"><span class="method method-get">GET</span> /api/ps</a>
<a href="#version"><span class="method method-get">GET</span> /api/version</a>
</nav>
<!-- ========== MAIN CONTENT ========== -->
<div class="main">
<!-- HERO -->
<div class="hero">
<h1>Ollama API 完整接口文档</h1>
<p>基于官方文档 <a href="https://docs.ollama.com" style="color:var(--accent)">docs.ollama.com</a> 全面解析。覆盖所有 HTTP API 端点,每个接口均提供 <strong>JavaScript SDK</strong><strong>HTTP Fetch</strong> 两种调用方式的详细示例代码。</p>
<div class="hero-meta">
<span><span class="dot dot-green"></span> 支持模型: <strong>gpt-oss · Gemma 3 · DeepSeek-R1 · Qwen3 等</strong></span>
<span><span class="dot dot-blue"></span> 文档日期: <strong>2026-05-18</strong></span>
<span><span class="dot dot-orange"></span> 本地: <strong>http://localhost:11434</strong> · 云端: <strong>https://ollama.com/api</strong></span>
</div>
</div>
<div class="content">
<!-- ========== 接口总览 ========== -->
<section class="api-section" id="overview">
<h2>📋 接口总览</h2>
<p class="desc">Ollama 提供 RESTful HTTP API,默认监听在 <code style="color:var(--cyan)">http://localhost:11434</code>。所有请求与响应均使用 JSON 格式。流式响应使用 NDJSONnewline-delimited JSON)。云端模型可通过 <code style="color:var(--cyan)">https://ollama.com/api</code> 访问相同的 API。</p>
<table class="overview-table">
<thead>
<tr><th>方法</th><th>接口路径</th><th>描述</th></tr>
</thead>
<tbody>
<tr><td><span class="method method-post">POST</span></td><td><a href="#generate">/api/generate</a></td><td>生成文本响应(补全模式)</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#chat">/api/chat</a></td><td>对话模式生成消息</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#embed">/api/embed</a></td><td>生成文本向量嵌入</td></tr>
<tr><td><span class="method method-get">GET</span></td><td><a href="#tags">/api/tags</a></td><td>列出所有本地模型</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#show">/api/show</a></td><td>查看模型详细信息</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#create">/api/create</a></td><td>创建自定义模型</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#copy">/api/copy</a></td><td>复制模型</td></tr>
<tr><td><span class="method method-delete">DELETE</span></td><td><a href="#delete">/api/delete</a></td><td>删除模型</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#pull">/api/pull</a></td><td>从仓库拉取模型</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#push">/api/push</a></td><td>推送模型到仓库</td></tr>
<tr><td><span class="method method-get">GET</span></td><td><a href="#ps">/api/ps</a></td><td>列出正在运行的模型</td></tr>
<tr><td><span class="method method-get">GET</span></td><td><a href="#version">/api/version</a></td><td>获取 Ollama 版本</td></tr>
</tbody>
</table>
</section>
<!-- ========== 快速开始 ========== -->
<section class="api-section" id="quickstart">
<h2>⚡ 快速开始</h2>
<p class="desc">在开始之前,确保 Ollama 已安装并运行。安装 SDK 依赖后即可使用。</p>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'qs-sdk')">JavaScript SDK</button>
<button class="code-tab" onclick="switchTab(this, 'qs-http')">HTTP Fetch</button>
</div>
<div class="code-block">
<div class="code-panel active" id="qs-sdk">
<pre><span class="hl-cm">// 安装: npm install ollama</span>
<span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-cm">// 默认连接本地 http://localhost:11434</span>
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 也可以指定远程地址</span>
<span class="hl-kw">const</span> remoteOllama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>({ <span class="hl-prop">host</span>: <span class="hl-str">'http://192.168.1.100:11434'</span> });
<span class="hl-cm">// 使用云端模型 (ollama.com)</span>
<span class="hl-kw">const</span> cloudOllama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>({ <span class="hl-prop">host</span>: <span class="hl-str">'https://ollama.com/api'</span> });</pre>
</div>
<div class="code-panel" id="qs-http">
<pre><span class="hl-cm">// 无需安装任何依赖,使用原生 fetch 即可</span>
<span class="hl-kw">const</span> OLLAMA_BASE = <span class="hl-str">'http://localhost:11434'</span>;
<span class="hl-cm">// 所有请求都是 POST (除少数 GET 接口)</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">`${OLLAMA_BASE}/api/generate`</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">prompt</span>: <span class="hl-str">'你好,世界!'</span>,
}),
});
<span class="hl-kw">const</span> data = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(data.response);</pre>
</div>
</div>
</section>
<!-- ========== Model Options ========== -->
<section class="api-section" id="model-options">
<h2>⚙️ 模型参数 (Options)</h2>
<p class="desc">以下参数可在 <code style="color:var(--cyan)">options</code> 字段中传入,控制生成行为。适用于 <code>/api/generate</code><code>/api/chat</code> 等接口。</p>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">seed</td><td class="param-type">integer</td><td>随机种子,用于可复现的输出</td></tr>
<tr><td class="param-name">temperature</td><td class="param-type">float</td><td>控制随机性,值越高越随机(默认约 0.8)</td></tr>
<tr><td class="param-name">top_k</td><td class="param-type">integer</td><td>限制下一个 token 从概率最高的 K 个中选取</td></tr>
<tr><td class="param-name">top_p</td><td class="param-type">float</td><td>核采样的累积概率阈值</td></tr>
<tr><td class="param-name">min_p</td><td class="param-type">float</td><td>token 选择的最低概率阈值</td></tr>
<tr><td class="param-name">stop</td><td class="param-type">string | string[]</td><td>停止序列,遇到时终止生成</td></tr>
<tr><td class="param-name">num_ctx</td><td class="param-type">integer</td><td>上下文窗口大小(token 数)</td></tr>
<tr><td class="param-name">num_predict</td><td class="param-type">integer</td><td>最大生成 token 数</td></tr>
</tbody>
</table>
</section>
<hr class="section-divider">
<!-- ==================== GENERATE ==================== -->
<section class="api-section" id="generate">
<h2><span class="method method-post">POST</span> /api/generate</h2>
<p class="desc">生成文本响应(补全模式)。支持流式/非流式、结构化输出、图像输入、Thinking 模式、logprobs 等功能。适用于 gpt-oss、Gemma 3、DeepSeek-R1、Qwen3 等模型。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/generate</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>模型名称,如 "gemma3"</td></tr>
<tr><td class="param-name">prompt</td><td class="param-type">string</td><td class="param-optional">可选</td><td>提示文本。省略时仅加载模型</td></tr>
<tr><td class="param-name">suffix</td><td class="param-type">string</td><td class="param-optional">可选</td><td>中间填充模式 (FIM) 中,出现在 prompt 后、response 前的文本</td></tr>
<tr><td class="param-name">images</td><td class="param-type">string[]</td><td class="param-optional">可选</td><td>Base64 编码的图像数组(多模态模型)</td></tr>
<tr><td class="param-name">format</td><td class="param-type">string | object</td><td class="param-optional">可选</td><td>结构化输出格式,可传 "json" 或 JSON Schema 对象</td></tr>
<tr><td class="param-name">system</td><td class="param-type">string</td><td class="param-optional">可选</td><td>系统提示词</td></tr>
<tr><td class="param-name">stream</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否流式返回(默认 true</td></tr>
<tr><td class="param-name">think</td><td class="param-type">boolean | string</td><td class="param-optional">可选</td><td>启用 Thinking 模式。可传 true/false 或 "high"/"medium"/"low"</td></tr>
<tr><td class="param-name">raw</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>跳过模板处理,返回模型原始输出</td></tr>
<tr><td class="param-name">keep_alive</td><td class="param-type">string | number</td><td class="param-optional">可选</td><td>模型保持加载时间,如 "5m"。传 0 立即卸载</td></tr>
<tr><td class="param-name">options</td><td class="param-type">object</td><td class="param-optional">可选</td><td>模型参数(见上方 Options 表格)</td></tr>
<tr><td class="param-name">logprobs</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否返回 token 的对数概率</td></tr>
<tr><td class="param-name">top_logprobs</td><td class="param-type">integer</td><td class="param-optional">可选</td><td>每个位置返回的候选 token 数(需 logprobs=true</td></tr>
</tbody>
</table>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td>模型名称</td></tr>
<tr><td class="param-name">created_at</td><td class="param-type">string</td><td>ISO 8601 时间戳</td></tr>
<tr><td class="param-name">response</td><td class="param-type">string</td><td>模型生成的文本</td></tr>
<tr><td class="param-name">thinking</td><td class="param-type">string</td><td>Thinking 模式下的思考输出</td></tr>
<tr><td class="param-name">done</td><td class="param-type">boolean</td><td>是否生成完毕</td></tr>
<tr><td class="param-name">done_reason</td><td class="param-type">string</td><td>停止原因(如 "stop"</td></tr>
<tr><td class="param-name">total_duration</td><td class="param-type">integer</td><td>总耗时(纳秒)</td></tr>
<tr><td class="param-name">load_duration</td><td class="param-type">integer</td><td>模型加载耗时(纳秒)</td></tr>
<tr><td class="param-name">prompt_eval_count</td><td class="param-type">integer</td><td>输入 token 数</td></tr>
<tr><td class="param-name">prompt_eval_duration</td><td class="param-type">integer</td><td>Prompt 评估耗时(纳秒)</td></tr>
<tr><td class="param-name">eval_count</td><td class="param-type">integer</td><td>输出 token 数</td></tr>
<tr><td class="param-name">eval_duration</td><td class="param-type">integer</td><td>生成 token 耗时(纳秒)</td></tr>
</tbody>
</table>
<div class="note-box"><strong>💡 提示:</strong>流式模式下,每个 chunk 都是独立的 NDJSON 事件,<code>response</code> 字段为当前片段文本,最后一个 chunk 的 <code>done</code> 为 true 并包含统计信息。</div>
<!-- 示例 -->
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'gen-sdk-1')">SDK · 流式生成</button>
<button class="code-tab" onclick="switchTab(this, 'gen-http-1')">HTTP · 流式生成</button>
<button class="code-tab" onclick="switchTab(this, 'gen-sdk-2')">SDK · 非流式 + 结构化输出</button>
<button class="code-tab" onclick="switchTab(this, 'gen-http-2')">HTTP · 结构化输出</button>
<button class="code-tab" onclick="switchTab(this, 'gen-sdk-3')">SDK · 图像识别</button>
<button class="code-tab" onclick="switchTab(this, 'gen-http-3')">HTTP · 图像识别</button>
</div>
<div class="code-block">
<div class="code-panel active" id="gen-sdk-1">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 流式生成</span>
<span class="hl-kw">const</span> stream = <span class="hl-kw">await</span> ollama.<span class="hl-fn">generate</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">prompt</span>: <span class="hl-str">'用简单的语言解释量子计算'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>,
<span class="hl-prop">options</span>: {
<span class="hl-prop">temperature</span>: <span class="hl-num">0.7</span>,
<span class="hl-prop">num_predict</span>: <span class="hl-num">512</span>,
},
});
<span class="hl-kw">for await</span> (<span class="hl-kw">const</span> chunk <span class="hl-kw">of</span> stream) {
process.stdout.<span class="hl-fn">write</span>(chunk.response);
<span class="hl-kw">if</span> (chunk.done) {
console.<span class="hl-fn">log</span>(<span class="hl-str">`\n\n[完成] 总耗时: ${(chunk.total_duration / 1e9).toFixed(2)}s`</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">`[统计] 输入: ${chunk.prompt_eval_count} tokens, 输出: ${chunk.eval_count} tokens`</span>);
}
}</pre>
</div>
<div class="code-panel" id="gen-http-1">
<pre><span class="hl-cm">// 流式生成(逐行读取 NDJSON)</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/generate'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">prompt</span>: <span class="hl-str">'用简单的语言解释量子计算'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>,
<span class="hl-prop">options</span>: { <span class="hl-prop">temperature</span>: <span class="hl-num">0.7</span> },
}),
});
<span class="hl-kw">const</span> reader = response.body.getReader();
<span class="hl-kw">const</span> decoder = <span class="hl-kw">new</span> <span class="hl-fn">TextDecoder</span>();
<span class="hl-kw">let</span> buffer = <span class="hl-str">''</span>;
<span class="hl-kw">while</span> (<span class="hl-kw">true</span>) {
<span class="hl-kw">const</span> { done, value } = <span class="hl-kw">await</span> reader.<span class="hl-fn">read</span>();
<span class="hl-kw">if</span> (done) <span class="hl-kw">break</span>;
buffer += decoder.<span class="hl-fn">decode</span>(value, { <span class="hl-prop">stream</span>: <span class="hl-kw">true</span> });
<span class="hl-kw">const</span> lines = buffer.<span class="hl-fn">split</span>(<span class="hl-str">'\n'</span>);
buffer = lines.<span class="hl-fn">pop</span>(); <span class="hl-cm">// 保留不完整行</span>
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> line <span class="hl-kw">of</span> lines) {
<span class="hl-kw">if</span> (!line.<span class="hl-fn">trim</span>()) <span class="hl-kw">continue</span>;
<span class="hl-kw">const</span> chunk = JSON.<span class="hl-fn">parse</span>(line);
process.stdout.<span class="hl-fn">write</span>(chunk.response);
<span class="hl-kw">if</span> (chunk.done) console.<span class="hl-fn">log</span>(<span class="hl-str">'\n[流结束]'</span>);
}
}</pre>
</div>
<div class="code-panel" id="gen-sdk-2">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 非流式 + 结构化 JSON 输出</span>
<span class="hl-kw">const</span> result = <span class="hl-kw">await</span> ollama.<span class="hl-fn">generate</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">prompt</span>: <span class="hl-str">'列出中国人口最多的5个城市,包含城市名和人口数'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
<span class="hl-prop">format</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'object'</span>,
<span class="hl-prop">properties</span>: {
<span class="hl-prop">cities</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'array'</span>,
<span class="hl-prop">items</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'object'</span>,
<span class="hl-prop">properties</span>: {
<span class="hl-prop">name</span>: { <span class="hl-prop">type</span>: <span class="hl-str">'string'</span> },
<span class="hl-prop">population</span>: { <span class="hl-prop">type</span>: <span class="hl-str">'integer'</span> },
},
<span class="hl-prop">required</span>: [<span class="hl-str">'name'</span>, <span class="hl-str">'population'</span>],
},
},
},
<span class="hl-prop">required</span>: [<span class="hl-str">'cities'</span>],
},
});
<span class="hl-kw">const</span> data = JSON.<span class="hl-fn">parse</span>(result.response);
console.<span class="hl-fn">log</span>(<span class="hl-str">'结构化结果:'</span>, JSON.<span class="hl-fn">stringify</span>(data, <span class="hl-kw">null</span>, <span class="hl-num">2</span>));</pre>
</div>
<div class="code-panel" id="gen-http-2">
<pre><span class="hl-cm">// HTTP 非流式 + 结构化输出</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/generate'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">prompt</span>: <span class="hl-str">'列出中国人口最多的5个城市'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
<span class="hl-prop">format</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'object'</span>,
<span class="hl-prop">properties</span>: {
<span class="hl-prop">cities</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'array'</span>,
<span class="hl-prop">items</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'object'</span>,
<span class="hl-prop">properties</span>: {
<span class="hl-prop">name</span>: { <span class="hl-prop">type</span>: <span class="hl-str">'string'</span> },
<span class="hl-prop">population</span>: { <span class="hl-prop">type</span>: <span class="hl-str">'integer'</span> },
},
<span class="hl-prop">required</span>: [<span class="hl-str">'name'</span>, <span class="hl-str">'population'</span>],
},
},
},
<span class="hl-prop">required</span>: [<span class="hl-str">'cities'</span>],
},
}),
});
<span class="hl-kw">const</span> data = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(JSON.<span class="hl-fn">parse</span>(data.response));</pre>
</div>
<div class="code-panel" id="gen-sdk-3">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">import</span> { readFileSync } <span class="hl-kw">from</span> <span class="hl-str">'fs'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 读取图片并转为 Base64</span>
<span class="hl-kw">const</span> imageBuffer = <span class="hl-fn">readFileSync</span>(<span class="hl-str">'./photo.jpg'</span>);
<span class="hl-kw">const</span> imageBase64 = imageBuffer.<span class="hl-fn">toString</span>(<span class="hl-str">'base64'</span>);
<span class="hl-cm">// 多模态图像识别</span>
<span class="hl-kw">const</span> result = <span class="hl-kw">await</span> ollama.<span class="hl-fn">generate</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">prompt</span>: <span class="hl-str">'这张图片里有什么?请详细描述。'</span>,
<span class="hl-prop">images</span>: [imageBase64],
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
});
console.<span class="hl-fn">log</span>(result.response);</pre>
</div>
<div class="code-panel" id="gen-http-3">
<pre><span class="hl-cm">// HTTP 图像识别</span>
<span class="hl-cm">// 将本地图片转为 Base64</span>
<span class="hl-kw">const</span> fs = <span class="hl-fn">require</span>(<span class="hl-str">'fs'</span>);
<span class="hl-kw">const</span> imageBuffer = fs.<span class="hl-fn">readFileSync</span>(<span class="hl-str">'./photo.jpg'</span>);
<span class="hl-kw">const</span> imageBase64 = imageBuffer.<span class="hl-fn">toString</span>(<span class="hl-str">'base64'</span>);
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/generate'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">prompt</span>: <span class="hl-str">'这张图片里有什么?请详细描述。'</span>,
<span class="hl-prop">images</span>: [imageBase64],
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
}),
});
<span class="hl-kw">const</span> data = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(data.response);</pre>
</div>
</div>
<div class="response-title">📤 响应示例</div>
<div class="response-block">
<pre>{
<span class="hl-prop">"model"</span>: <span class="hl-str">"gemma3"</span>,
<span class="hl-prop">"created_at"</span>: <span class="hl-str">"2026-05-18T08:14:07.414671Z"</span>,
<span class="hl-prop">"response"</span>: <span class="hl-str">"量子计算是一种利用量子力学原理进行计算的新型计算方式..."</span>,
<span class="hl-prop">"done"</span>: <span class="hl-kw">true</span>,
<span class="hl-prop">"done_reason"</span>: <span class="hl-str">"stop"</span>,
<span class="hl-prop">"total_duration"</span>: <span class="hl-num">174560334</span>,
<span class="hl-prop">"load_duration"</span>: <span class="hl-num">101397084</span>,
<span class="hl-prop">"prompt_eval_count"</span>: <span class="hl-num">11</span>,
<span class="hl-prop">"prompt_eval_duration"</span>: <span class="hl-num">13074791</span>,
<span class="hl-prop">"eval_count"</span>: <span class="hl-num">128</span>,
<span class="hl-prop">"eval_duration"</span>: <span class="hl-num">52479709</span>
}</pre>
</div>
</section>
<hr class="section-divider">
<!-- ==================== CHAT ==================== -->
<section class="api-section" id="chat">
<h2><span class="method method-post">POST</span> /api/chat</h2>
<p class="desc">对话模式生成消息。支持多轮对话、工具调用 (Tool Calling)、Thinking 模式、结构化输出、图像输入、logprobs。适用于 gpt-oss、Gemma 3、Qwen3 等模型。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/chat</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>模型名称</td></tr>
<tr><td class="param-name">messages</td><td class="param-type">array</td><td class="param-required">必填</td><td>对话历史消息数组</td></tr>
<tr><td class="param-name">messages[].role</td><td class="param-type">string</td><td class="param-required">必填</td><td>角色: "system" | "user" | "assistant" | "tool"</td></tr>
<tr><td class="param-name">messages[].content</td><td class="param-type">string</td><td class="param-required">必填</td><td>消息文本</td></tr>
<tr><td class="param-name">messages[].images</td><td class="param-type">string[]</td><td class="param-optional">可选</td><td>Base64 编码的图像数组</td></tr>
<tr><td class="param-name">messages[].tool_calls</td><td class="param-type">array</td><td class="param-optional">可选</td><td>工具调用请求</td></tr>
<tr><td class="param-name">tools</td><td class="param-type">array</td><td class="param-optional">可选</td><td>可用的函数工具列表</td></tr>
<tr><td class="param-name">format</td><td class="param-type">string | object</td><td class="param-optional">可选</td><td>结构化输出格式</td></tr>
<tr><td class="param-name">stream</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否流式返回(默认 true</td></tr>
<tr><td class="param-name">think</td><td class="param-type">boolean | string</td><td class="param-optional">可选</td><td>Thinking 模式</td></tr>
<tr><td class="param-name">keep_alive</td><td class="param-type">string | number</td><td class="param-optional">可选</td><td>模型保持加载时间</td></tr>
<tr><td class="param-name">options</td><td class="param-type">object</td><td class="param-optional">可选</td><td>模型参数</td></tr>
<tr><td class="param-name">logprobs</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否返回对数概率</td></tr>
<tr><td class="param-name">top_logprobs</td><td class="param-type">integer</td><td class="param-optional">可选</td><td>每位置候选 token 数</td></tr>
</tbody>
</table>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td>模型名称</td></tr>
<tr><td class="param-name">created_at</td><td class="param-type">string</td><td>ISO 8601 时间戳</td></tr>
<tr><td class="param-name">message</td><td class="param-type">object</td><td>包含 role, content, thinking, tool_calls 等</td></tr>
<tr><td class="param-name">message.role</td><td class="param-type">string</td><td>始终为 "assistant"</td></tr>
<tr><td class="param-name">message.content</td><td class="param-type">string</td><td>助手回复文本</td></tr>
<tr><td class="param-name">message.thinking</td><td class="param-type">string</td><td>Thinking 模式的思考输出</td></tr>
<tr><td class="param-name">message.tool_calls</td><td class="param-type">array</td><td>模型请求的工具调用</td></tr>
<tr><td class="param-name">message.images</td><td class="param-type">string[]</td><td>Base64 编码的图像(部分模型支持)</td></tr>
<tr><td class="param-name">done</td><td class="param-type">boolean</td><td>是否完成</td></tr>
<tr><td class="param-name">done_reason</td><td class="param-type">string</td><td>停止原因</td></tr>
<tr><td class="param-name">total_duration</td><td class="param-type">integer</td><td>总耗时(纳秒)</td></tr>
<tr><td class="param-name">eval_count</td><td class="param-type">integer</td><td>输出 token 数</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'chat-sdk-1')">SDK · 多轮对话</button>
<button class="code-tab" onclick="switchTab(this, 'chat-http-1')">HTTP · 多轮对话</button>
<button class="code-tab" onclick="switchTab(this, 'chat-sdk-2')">SDK · 工具调用</button>
<button class="code-tab" onclick="switchTab(this, 'chat-http-2')">HTTP · 工具调用</button>
<button class="code-tab" onclick="switchTab(this, 'chat-sdk-3')">SDK · Thinking 模式</button>
<button class="code-tab" onclick="switchTab(this, 'chat-http-3')">HTTP · Thinking 模式</button>
</div>
<div class="code-block">
<div class="code-panel active" id="chat-sdk-1">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 多轮对话</span>
<span class="hl-kw">const</span> messages = [
{ <span class="hl-prop">role</span>: <span class="hl-str">'system'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'你是一个专业的编程助手,请用中文回答。'</span> },
{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'JavaScript 中 Promise 和 async/await 的区别是什么?'</span> },
];
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> ollama.<span class="hl-fn">chat</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">messages</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>,
});
<span class="hl-kw">let</span> fullReply = <span class="hl-str">''</span>;
<span class="hl-kw">for await</span> (<span class="hl-kw">const</span> chunk <span class="hl-kw">of</span> response) {
<span class="hl-kw">const</span> text = chunk.message.content;
fullReply += text;
process.stdout.<span class="hl-fn">write</span>(text);
}
<span class="hl-cm">// 追加助手回复,继续对话</span>
messages.<span class="hl-fn">push</span>({ <span class="hl-prop">role</span>: <span class="hl-str">'assistant'</span>, <span class="hl-prop">content</span>: fullReply });
messages.<span class="hl-fn">push</span>({ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'能给一个 async/await 的代码示例吗?'</span> });</pre>
</div>
<div class="code-panel" id="chat-http-1">
<pre><span class="hl-cm">// HTTP 多轮对话(非流式)</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/chat'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
<span class="hl-prop">messages</span>: [
{ <span class="hl-prop">role</span>: <span class="hl-str">'system'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'你是一个专业的编程助手。'</span> },
{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'解释 JavaScript 的事件循环机制'</span> },
],
}),
});
<span class="hl-kw">const</span> data = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(data.message.content);
console.<span class="hl-fn">log</span>(<span class="hl-str">`输出 ${data.eval_count} tokens,耗时 ${(data.eval_duration / 1e6).toFixed(0)}ms`</span>);</pre>
</div>
<div class="code-panel" id="chat-sdk-2">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 定义工具</span>
<span class="hl-kw">const</span> tools = [{
<span class="hl-prop">type</span>: <span class="hl-str">'function'</span>,
<span class="hl-prop">function</span>: {
<span class="hl-prop">name</span>: <span class="hl-str">'get_weather'</span>,
<span class="hl-prop">description</span>: <span class="hl-str">'获取指定城市的当前天气信息'</span>,
<span class="hl-prop">parameters</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'object'</span>,
<span class="hl-prop">properties</span>: {
<span class="hl-prop">city</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'string'</span>,
<span class="hl-prop">description</span>: <span class="hl-str">'城市名称,如 "北京"'</span>,
},
<span class="hl-prop">unit</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'string'</span>,
<span class="hl-prop">enum</span>: [<span class="hl-str">'celsius'</span>, <span class="hl-str">'fahrenheit'</span>],
<span class="hl-prop">description</span>: <span class="hl-str">'温度单位'</span>,
},
},
<span class="hl-prop">required</span>: [<span class="hl-str">'city'</span>],
},
},
}];
<span class="hl-cm">// 第一轮:模型可能请求调用工具</span>
<span class="hl-kw">const</span> response1 = <span class="hl-kw">await</span> ollama.<span class="hl-fn">chat</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'qwen3'</span>,
<span class="hl-prop">messages</span>: [{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'北京今天天气怎么样?'</span> }],
<span class="hl-prop">tools</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
});
<span class="hl-kw">if</span> (response1.message.tool_calls?.length) {
<span class="hl-kw">const</span> toolCall = response1.message.tool_calls[<span class="hl-num">0</span>];
console.<span class="hl-fn">log</span>(<span class="hl-str">`模型调用: ${toolCall.function.name}`</span>, toolCall.function.arguments);
<span class="hl-cm">// 模拟工具执行结果</span>
<span class="hl-kw">const</span> weatherResult = <span class="hl-str">'晴天,温度 22°C,微风'</span>;
<span class="hl-cm">// 第二轮:将工具结果返回给模型</span>
<span class="hl-kw">const</span> response2 = <span class="hl-kw">await</span> ollama.<span class="hl-fn">chat</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'qwen3'</span>,
<span class="hl-prop">messages</span>: [
{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'北京今天天气怎么样?'</span> },
response1.message,
{
<span class="hl-prop">role</span>: <span class="hl-str">'tool'</span>,
<span class="hl-prop">content</span>: weatherResult,
},
],
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
});
console.<span class="hl-fn">log</span>(<span class="hl-str">'最终回复:'</span>, response2.message.content);
}</pre>
</div>
<div class="code-panel" id="chat-http-2">
<pre><span class="hl-cm">// HTTP 工具调用</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/chat'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'qwen3'</span>,
<span class="hl-prop">messages</span>: [
{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'巴黎今天天气如何?'</span> },
],
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
<span class="hl-prop">tools</span>: [{
<span class="hl-prop">type</span>: <span class="hl-str">'function'</span>,
<span class="hl-prop">function</span>: {
<span class="hl-prop">name</span>: <span class="hl-str">'get_current_weather'</span>,
<span class="hl-prop">description</span>: <span class="hl-str">'获取指定地点的当前天气'</span>,
<span class="hl-prop">parameters</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'object'</span>,
<span class="hl-prop">properties</span>: {
<span class="hl-prop">location</span>: { <span class="hl-prop">type</span>: <span class="hl-str">'string'</span>, <span class="hl-prop">description</span>: <span class="hl-str">'地点'</span> },
<span class="hl-prop">format</span>: { <span class="hl-prop">type</span>: <span class="hl-str">'string'</span>, <span class="hl-prop">enum</span>: [<span class="hl-str">'celsius'</span>, <span class="hl-str">'fahrenheit'</span>] },
},
<span class="hl-prop">required</span>: [<span class="hl-str">'location'</span>, <span class="hl-str">'format'</span>],
},
},
}],
}),
});
<span class="hl-kw">const</span> data = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">'工具调用:'</span>, data.message.tool_calls);</pre>
</div>
<div class="code-panel" id="chat-sdk-3">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// Thinking 模式 - 让模型先思考再回答</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> ollama.<span class="hl-fn">chat</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gpt-oss'</span>,
<span class="hl-prop">messages</span>: [
{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'如果一个房间里有3个人,每两个人握手一次,一共握了几次手?'</span> },
],
<span class="hl-prop">think</span>: <span class="hl-str">'low'</span>, <span class="hl-cm">// 可选: true/false/"high"/"medium"/"low"</span>
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>,
});
<span class="hl-kw">let</span> thinking = <span class="hl-str">''</span>;
<span class="hl-kw">let</span> content = <span class="hl-str">''</span>;
<span class="hl-kw">for await</span> (<span class="hl-kw">const</span> chunk <span class="hl-kw">of</span> response) {
<span class="hl-kw">if</span> (chunk.message.thinking) {
thinking += chunk.message.thinking;
process.stderr.<span class="hl-fn">write</span>(chunk.message.thinking); <span class="hl-cm">// 思考过程</span>
}
<span class="hl-kw">if</span> (chunk.message.content) {
content += chunk.message.content;
process.stdout.<span class="hl-fn">write</span>(chunk.message.content); <span class="hl-cm">// 最终答案</span>
}
}</pre>
</div>
<div class="code-panel" id="chat-http-3">
<pre><span class="hl-cm">// HTTP Thinking 模式(流式读取)</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/chat'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'gpt-oss'</span>,
<span class="hl-prop">messages</span>: [
{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'如果一个房间里有3个人,每两个人握手一次,一共握了几次手?'</span> },
],
<span class="hl-prop">think</span>: <span class="hl-str">'low'</span>,
}),
});
<span class="hl-kw">const</span> reader = response.body.getReader();
<span class="hl-kw">const</span> decoder = <span class="hl-kw">new</span> <span class="hl-fn">TextDecoder</span>();
<span class="hl-kw">let</span> buffer = <span class="hl-str">''</span>;
console.<span class="hl-fn">log</span>(<span class="hl-str">'=== 思考过程 ==='</span>);
<span class="hl-kw">while</span> (<span class="hl-kw">true</span>) {
<span class="hl-kw">const</span> { done, value } = <span class="hl-kw">await</span> reader.<span class="hl-fn">read</span>();
<span class="hl-kw">if</span> (done) <span class="hl-kw">break</span>;
buffer += decoder.<span class="hl-fn">decode</span>(value, { <span class="hl-prop">stream</span>: <span class="hl-kw">true</span> });
<span class="hl-kw">const</span> lines = buffer.<span class="hl-fn">split</span>(<span class="hl-str">'\n'</span>);
buffer = lines.<span class="hl-fn">pop</span>();
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> line <span class="hl-kw">of</span> lines) {
<span class="hl-kw">if</span> (!line.<span class="hl-fn">trim</span>()) <span class="hl-kw">continue</span>;
<span class="hl-kw">const</span> chunk = JSON.<span class="hl-fn">parse</span>(line);
<span class="hl-kw">if</span> (chunk.message?.thinking) {
process.stderr.<span class="hl-fn">write</span>(chunk.message.thinking);
}
<span class="hl-kw">if</span> (chunk.message?.content) {
process.stdout.<span class="hl-fn">write</span>(chunk.message.content);
}
}
}</pre>
</div>
</div>
<div class="response-title">📤 响应示例</div>
<div class="response-block">
<pre>{
<span class="hl-prop">"model"</span>: <span class="hl-str">"gemma3"</span>,
<span class="hl-prop">"created_at"</span>: <span class="hl-str">"2026-05-18T08:14:07.414671Z"</span>,
<span class="hl-prop">"message"</span>: {
<span class="hl-prop">"role"</span>: <span class="hl-str">"assistant"</span>,
<span class="hl-prop">"content"</span>: <span class="hl-str">"Promise 和 async/await 的主要区别在于语法和错误处理方式..."</span>
},
<span class="hl-prop">"done"</span>: <span class="hl-kw">true</span>,
<span class="hl-prop">"done_reason"</span>: <span class="hl-str">"stop"</span>,
<span class="hl-prop">"total_duration"</span>: <span class="hl-num">174560334</span>,
<span class="hl-prop">"load_duration"</span>: <span class="hl-num">101397084</span>,
<span class="hl-prop">"prompt_eval_count"</span>: <span class="hl-num">24</span>,
<span class="hl-prop">"prompt_eval_duration"</span>: <span class="hl-num">13074791</span>,
<span class="hl-prop">"eval_count"</span>: <span class="hl-num">156</span>,
<span class="hl-prop">"eval_duration"</span>: <span class="hl-num">52479709</span>
}</pre>
</div>
</section>
<hr class="section-divider">
<!-- ==================== EMBED ==================== -->
<section class="api-section" id="embed">
<h2><span class="method method-post">POST</span> /api/embed</h2>
<p class="desc">生成文本的向量嵌入。用于语义搜索、RAG 检索增强生成、文本相似度比较等场景。支持批量输入和自定义维度。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/embed</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>嵌入模型名称,如 "embeddinggemma"</td></tr>
<tr><td class="param-name">input</td><td class="param-type">string | string[]</td><td class="param-required">必填</td><td>待编码的文本或文本数组</td></tr>
<tr><td class="param-name">truncate</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否截断超长输入(默认 true</td></tr>
<tr><td class="param-name">dimensions</td><td class="param-type">integer</td><td class="param-optional">可选</td><td>生成的嵌入维度数</td></tr>
<tr><td class="param-name">keep_alive</td><td class="param-type">string</td><td class="param-optional">可选</td><td>模型保持加载时间</td></tr>
<tr><td class="param-name">options</td><td class="param-type">object</td><td class="param-optional">可选</td><td>模型参数</td></tr>
</tbody>
</table>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td>使用的模型</td></tr>
<tr><td class="param-name">embeddings</td><td class="param-type">number[][]</td><td>向量嵌入数组</td></tr>
<tr><td class="param-name">total_duration</td><td class="param-type">integer</td><td>总耗时(纳秒)</td></tr>
<tr><td class="param-name">load_duration</td><td class="param-type">integer</td><td>模型加载耗时(纳秒)</td></tr>
<tr><td class="param-name">prompt_eval_count</td><td class="param-type">integer</td><td>输入 token 数</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'embed-sdk')">SDK · 批量嵌入</button>
<button class="code-tab" onclick="switchTab(this, 'embed-http')">HTTP · 批量嵌入</button>
<button class="code-tab" onclick="switchTab(this, 'embed-usage')">实际用法 · 语义搜索</button>
</div>
<div class="code-block">
<div class="code-panel active" id="embed-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 单条文本嵌入</span>
<span class="hl-kw">const</span> single = <span class="hl-kw">await</span> ollama.<span class="hl-fn">embed</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'embeddinggemma'</span>,
<span class="hl-prop">input</span>: <span class="hl-str">'Ollama 是一个本地运行大语言模型的工具'</span>,
});
console.<span class="hl-fn">log</span>(<span class="hl-str">`维度: ${single.embeddings[0].length}`</span>);
<span class="hl-cm">// 批量文本嵌入</span>
<span class="hl-kw">const</span> batch = <span class="hl-kw">await</span> ollama.<span class="hl-fn">embed</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'embeddinggemma'</span>,
<span class="hl-prop">input</span>: [
<span class="hl-str">'JavaScript 是一种编程语言'</span>,
<span class="hl-str">'Python 常用于数据科学'</span>,
<span class="hl-str">'机器学习是 AI 的子领域'</span>,
],
<span class="hl-prop">dimensions</span>: <span class="hl-num">256</span>, <span class="hl-cm">// 自定义维度</span>
});
console.<span class="hl-fn">log</span>(<span class="hl-str">`生成了 ${batch.embeddings.length} 个向量`</span>);</pre>
</div>
<div class="code-panel" id="embed-http">
<pre><span class="hl-cm">// HTTP 批量嵌入</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/embed'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'embeddinggemma'</span>,
<span class="hl-prop">input</span>: [
<span class="hl-str">'什么是机器学习?'</span>,
<span class="hl-str">'深度学习与传统机器学习的区别'</span>,
<span class="hl-str">'如何训练一个神经网络'</span>,
],
<span class="hl-prop">dimensions</span>: <span class="hl-num">128</span>,
}),
});
<span class="hl-kw">const</span> data = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">`模型: ${data.model}`</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">`向量数: ${data.embeddings.length}`</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">`维度: ${data.embeddings[0].length}`</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">`耗时: ${(data.total_duration / 1e6).toFixed(0)}ms`</span>);</pre>
</div>
<div class="code-panel" id="embed-usage">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 实际用法: 语义搜索</span>
<span class="hl-kw">function</span> <span class="hl-fn">cosineSimilarity</span>(a, b) {
<span class="hl-kw">const</span> dot = a.<span class="hl-fn">reduce</span>((s, v, i) => s + v * b[i], <span class="hl-num">0</span>);
<span class="hl-kw">const</span> magA = Math.<span class="hl-fn">sqrt</span>(a.<span class="hl-fn">reduce</span>((s, v) => s + v * v, <span class="hl-num">0</span>));
<span class="hl-kw">const</span> magB = Math.<span class="hl-fn">sqrt</span>(b.<span class="hl-fn">reduce</span>((s, v) => s + v * v, <span class="hl-num">0</span>));
<span class="hl-kw">return</span> dot / (magA * magB);
}
<span class="hl-kw">const</span> docs = [
<span class="hl-str">'Python 是一种通用编程语言'</span>,
<span class="hl-str">'机器学习使用统计方法让计算机学习'</span>,
<span class="hl-str">'React 是一个前端 JavaScript 框架'</span>,
];
<span class="hl-cm">// 生成文档嵌入</span>
<span class="hl-kw">const</span> docEmbeddings = <span class="hl-kw">await</span> ollama.<span class="hl-fn">embed</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'embeddinggemma'</span>, <span class="hl-prop">input</span>: docs });
<span class="hl-cm">// 生成查询嵌入</span>
<span class="hl-kw">const</span> query = <span class="hl-str">'什么是 AI'</span>;
<span class="hl-kw">const</span> queryEmbed = <span class="hl-kw">await</span> ollama.<span class="hl-fn">embed</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'embeddinggemma'</span>, <span class="hl-prop">input</span>: query });
<span class="hl-cm">// 计算相似度并排序</span>
<span class="hl-kw">const</span> results = docEmbeddings.embeddings
.<span class="hl-fn">map</span>((emb, i) => ({
<span class="hl-prop">text</span>: docs[i],
<span class="hl-prop">score</span>: <span class="hl-fn">cosineSimilarity</span>(queryEmbed.embeddings[<span class="hl-num">0</span>], emb),
}))
.<span class="hl-fn">sort</span>((a, b) => b.score - a.score);
console.<span class="hl-fn">log</span>(<span class="hl-str">'搜索结果:'</span>, results);</pre>
</div>
</div>
<div class="response-title">📤 响应示例</div>
<div class="response-block">
<pre>{
<span class="hl-prop">"model"</span>: <span class="hl-str">"embeddinggemma"</span>,
<span class="hl-prop">"embeddings"</span>: [
[<span class="hl-num">0.010071029</span>, <span class="hl-num">-0.0017594862</span>, <span class="hl-num">0.05007221</span>, <span class="hl-num">0.04692972</span>, <span class="hl-num">0.054916814</span>, ...]
],
<span class="hl-prop">"total_duration"</span>: <span class="hl-num">14143917</span>,
<span class="hl-prop">"load_duration"</span>: <span class="hl-num">1019500</span>,
<span class="hl-prop">"prompt_eval_count"</span>: <span class="hl-num">8</span>
}</pre>
</div>
</section>
<hr class="section-divider">
<!-- ==================== TAGS ==================== -->
<section class="api-section" id="tags">
<h2><span class="method method-get">GET</span> /api/tags</h2>
<p class="desc">列出所有已下载到本地的模型及其详细信息(名称、大小、格式、量化级别等)。</p>
<div class="endpoint-bar">
<span class="http-method method-get">GET</span>
<span class="url">http://localhost:11434/api/tags</span>
</div>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">models[]</td><td class="param-type">array</td><td>模型列表</td></tr>
<tr><td class="param-name">models[].name</td><td class="param-type">string</td><td>模型名称</td></tr>
<tr><td class="param-name">models[].model</td><td class="param-type">string</td><td>模型标识</td></tr>
<tr><td class="param-name">models[].remote_model</td><td class="param-type">string</td><td>上游模型名称(远程模型时)</td></tr>
<tr><td class="param-name">models[].remote_host</td><td class="param-type">string</td><td>上游 Ollama 主机 URL(远程模型时)</td></tr>
<tr><td class="param-name">models[].modified_at</td><td class="param-type">string</td><td>最后修改时间</td></tr>
<tr><td class="param-name">models[].size</td><td class="param-type">integer</td><td>磁盘大小(字节)</td></tr>
<tr><td class="param-name">models[].digest</td><td class="param-type">string</td><td>SHA256 摘要</td></tr>
<tr><td class="param-name">models[].details</td><td class="param-type">object</td><td>格式、家族、参数量、量化级别</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'tags-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'tags-http')">HTTP</button>
</div>
<div class="code-block">
<div class="code-panel active" id="tags-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 列出所有本地模型</span>
<span class="hl-kw">const</span> { models } = <span class="hl-kw">await</span> ollama.<span class="hl-fn">list</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">`共 ${models.length} 个模型:\n`</span>);
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> m <span class="hl-kw">of</span> models) {
<span class="hl-kw">const</span> sizeGB = (m.size / 1e9).<span class="hl-fn">toFixed</span>(<span class="hl-num">2</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">` ${m.name} [${sizeGB} GB] ${m.details.parameter_size} ${m.details.quantization_level}`</span>);
}</pre>
</div>
<div class="code-panel" id="tags-http">
<pre><span class="hl-cm">// HTTP 列出模型</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/tags'</span>);
<span class="hl-kw">const</span> { models } = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> m <span class="hl-kw">of</span> models) {
console.<span class="hl-fn">log</span>(<span class="hl-str">`${m.name} - ${(m.size / 1e9).toFixed(2)} GB`</span>);
}</pre>
</div>
</div>
<div class="response-title">📤 响应示例</div>
<div class="response-block">
<pre>{
<span class="hl-prop">"models"</span>: [
{
<span class="hl-prop">"name"</span>: <span class="hl-str">"gemma3:latest"</span>,
<span class="hl-prop">"model"</span>: <span class="hl-str">"gemma3:latest"</span>,
<span class="hl-prop">"modified_at"</span>: <span class="hl-str">"2026-05-17T23:34:03.409490317+08:00"</span>,
<span class="hl-prop">"size"</span>: <span class="hl-num">3338801804</span>,
<span class="hl-prop">"digest"</span>: <span class="hl-str">"a2af6cc3eb7fa8be8504abaf9b04e88f17a119ec..."</span>,
<span class="hl-prop">"details"</span>: {
<span class="hl-prop">"format"</span>: <span class="hl-str">"gguf"</span>,
<span class="hl-prop">"family"</span>: <span class="hl-str">"gemma"</span>,
<span class="hl-prop">"families"</span>: [<span class="hl-str">"gemma"</span>],
<span class="hl-prop">"parameter_size"</span>: <span class="hl-str">"4.3B"</span>,
<span class="hl-prop">"quantization_level"</span>: <span class="hl-str">"Q4_K_M"</span>
}
}
]
}</pre>
</div>
</section>
<hr class="section-divider">
<!-- ==================== SHOW ==================== -->
<section class="api-section" id="show">
<h2><span class="method method-post">POST</span> /api/show</h2>
<p class="desc">查看指定模型的详细信息,包括参数设置、许可证、模板、模型能力、模型架构元数据等。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/show</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>模型名称</td></tr>
<tr><td class="param-name">verbose</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否返回详细的 verbose 信息</td></tr>
</tbody>
</table>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">parameters</td><td class="param-type">string</td><td>模型参数设置文本</td></tr>
<tr><td class="param-name">license</td><td class="param-type">string</td><td>模型许可证</td></tr>
<tr><td class="param-name">modified_at</td><td class="param-type">string</td><td>最后修改时间</td></tr>
<tr><td class="param-name">details</td><td class="param-type">object</td><td>模型格式、家族、参数量等</td></tr>
<tr><td class="param-name">template</td><td class="param-type">string</td><td>提示模板</td></tr>
<tr><td class="param-name">capabilities</td><td class="param-type">string[]</td><td>支持的功能列表(如 "completion", "vision"</td></tr>
<tr><td class="param-name">model_info</td><td class="param-type">object</td><td>详细的模型架构元数据</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'show-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'show-http')">HTTP</button>
</div>
<div class="code-block">
<div class="code-panel active" id="show-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 查看模型信息</span>
<span class="hl-kw">const</span> info = <span class="hl-kw">await</span> ollama.<span class="hl-fn">show</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>, <span class="hl-prop">verbose</span>: <span class="hl-kw">true</span> });
console.<span class="hl-fn">log</span>(<span class="hl-str">'能力:'</span>, info.capabilities); <span class="hl-cm">// ["completion", "vision"]</span>
console.<span class="hl-fn">log</span>(<span class="hl-str">'参数量:'</span>, info.details.parameter_size);
console.<span class="hl-fn">log</span>(<span class="hl-str">'格式:'</span>, info.details.format);
console.<span class="hl-fn">log</span>(<span class="hl-str">'上下文长度:'</span>, info.model_info?.[<span class="hl-str">'gemma3.context_length'</span>]);</pre>
</div>
<div class="code-panel" id="show-http">
<pre><span class="hl-cm">// HTTP 查看模型详情</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/show'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>, <span class="hl-prop">verbose</span>: <span class="hl-kw">true</span> }),
});
<span class="hl-kw">const</span> info = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">'能力:'</span>, info.capabilities);
console.<span class="hl-fn">log</span>(<span class="hl-str">'模型信息:'</span>, info.model_info);</pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== CREATE ==================== -->
<section class="api-section" id="create">
<h2><span class="method method-post">POST</span> /api/create</h2>
<p class="desc">基于已有模型创建自定义模型。可以自定义系统提示词、模板、参数,也可以进行量化。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/create</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>新模型的名称</td></tr>
<tr><td class="param-name">from</td><td class="param-type">string</td><td class="param-optional">可选</td><td>基础模型名称</td></tr>
<tr><td class="param-name">template</td><td class="param-type">string</td><td class="param-optional">可选</td><td>自定义提示模板</td></tr>
<tr><td class="param-name">system</td><td class="param-type">string</td><td class="param-optional">可选</td><td>嵌入模型的系统提示词</td></tr>
<tr><td class="param-name">license</td><td class="param-type">string | string[]</td><td class="param-optional">可选</td><td>许可证</td></tr>
<tr><td class="param-name">parameters</td><td class="param-type">object</td><td class="param-optional">可选</td><td>模型参数</td></tr>
<tr><td class="param-name">messages</td><td class="param-type">array</td><td class="param-optional">可选</td><td>用于模型的消息历史</td></tr>
<tr><td class="param-name">quantize</td><td class="param-type">string</td><td class="param-optional">可选</td><td>量化级别,如 "q4_K_M", "q8_0"</td></tr>
<tr><td class="param-name">stream</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否流式返回创建进度(默认 true</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'create-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'create-http')">HTTP</button>
<button class="code-tab" onclick="switchTab(this, 'create-quant')">量化模型</button>
</div>
<div class="code-block">
<div class="code-panel active" id="create-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 创建自定义模型</span>
<span class="hl-kw">const</span> stream = <span class="hl-kw">await</span> ollama.<span class="hl-fn">create</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'my-assistant'</span>,
<span class="hl-prop">from</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">system</span>: <span class="hl-str">'你是一个专业的中文编程助手。回答简洁明了,优先使用代码示例。'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>,
});
<span class="hl-kw">for await</span> (<span class="hl-kw">const</span> chunk <span class="hl-kw">of</span> stream) {
<span class="hl-kw">if</span> (chunk.status) process.stdout.<span class="hl-fn">write</span>(<span class="hl-str">`状态: ${chunk.status}\n`</span>);
}</pre>
</div>
<div class="code-panel" id="create-http">
<pre><span class="hl-cm">// HTTP 创建模型</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/create'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'emoji-bot'</span>,
<span class="hl-prop">from</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">system</span>: <span class="hl-str">'你只会用表情符号回答问题。'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
}),
});
<span class="hl-kw">const</span> result = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(result.status); <span class="hl-cm">// "success"</span></pre>
</div>
<div class="code-panel" id="create-quant">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 创建量化版本模型(减少显存占用)</span>
<span class="hl-kw">const</span> stream = <span class="hl-kw">await</span> ollama.<span class="hl-fn">create</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'llama3:8b-q4'</span>,
<span class="hl-prop">from</span>: <span class="hl-str">'llama3:8b-instruct-fp16'</span>,
<span class="hl-prop">quantize</span>: <span class="hl-str">'q4_K_M'</span>, <span class="hl-cm">// 量化到 Q4_K_M 级别</span>
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>,
});
<span class="hl-kw">for await</span> (<span class="hl-kw">const</span> chunk <span class="hl-kw">of</span> stream) {
<span class="hl-kw">if</span> (chunk.total && chunk.completed) {
<span class="hl-kw">const</span> pct = ((chunk.completed / chunk.total) * <span class="hl-num">100</span>).<span class="hl-fn">toFixed</span>(<span class="hl-num">1</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">`量化进度: ${pct}%`</span>);
}
}</pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== COPY ==================== -->
<section class="api-section" id="copy">
<h2><span class="method method-post">POST</span> /api/copy</h2>
<p class="desc">复制一个已有模型到新名称。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/copy</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">source</td><td class="param-type">string</td><td class="param-required">必填</td><td>源模型名称</td></tr>
<tr><td class="param-name">destination</td><td class="param-type">string</td><td class="param-required">必填</td><td>目标模型名称</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'copy-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'copy-http')">HTTP</button>
</div>
<div class="code-block">
<div class="code-panel active" id="copy-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-kw">await</span> ollama.<span class="hl-fn">copy</span>({
<span class="hl-prop">source</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">destination</span>: <span class="hl-str">'gemma3-backup'</span>,
});
console.<span class="hl-fn">log</span>(<span class="hl-str">'复制完成'</span>);</pre>
</div>
<div class="code-panel" id="copy-http">
<pre><span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/copy'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">source</span>: <span class="hl-str">'gemma3'</span>,
<span class="hl-prop">destination</span>: <span class="hl-str">'gemma3-backup'</span>,
}),
});
console.<span class="hl-fn">log</span>(<span class="hl-str">'复制完成'</span>); <span class="hl-cm">// 成功返回 200</span></pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== DELETE ==================== -->
<section class="api-section" id="delete">
<h2><span class="method method-delete">DELETE</span> /api/delete</h2>
<p class="desc">删除本地模型文件,释放磁盘空间。</p>
<div class="endpoint-bar">
<span class="http-method method-delete">DELETE</span>
<span class="url">http://localhost:11434/api/delete</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>要删除的模型名称</td></tr>
</tbody>
</table>
<div class="note-box"><strong>⚠️ 警告:</strong>此操作不可恢复。模型文件将被永久删除。</div>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'del-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'del-http')">HTTP</button>
</div>
<div class="code-block">
<div class="code-panel active" id="del-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-kw">await</span> ollama.<span class="hl-fn">delete</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'gemma3-backup'</span> });
console.<span class="hl-fn">log</span>(<span class="hl-str">'模型已删除'</span>);</pre>
</div>
<div class="code-panel" id="del-http">
<pre><span class="hl-cm">// HTTP 删除模型 (注意是 DELETE 方法)</span>
<span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/delete'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'DELETE'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'gemma3-backup'</span> }),
});
console.<span class="hl-fn">log</span>(<span class="hl-str">'模型已删除'</span>);</pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== PULL ==================== -->
<section class="api-section" id="pull">
<h2><span class="method method-post">POST</span> /api/pull</h2>
<p class="desc">从 Ollama 模型仓库下载模型到本地。支持流式进度显示。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/pull</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>要下载的模型名称,如 "gemma3", "llama3:70b"</td></tr>
<tr><td class="param-name">insecure</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>允许不安全连接下载</td></tr>
<tr><td class="param-name">stream</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否流式返回进度(默认 true</td></tr>
</tbody>
</table>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">status</td><td class="param-type">string</td><td>状态消息(如 "pulling manifest", "success"</td></tr>
<tr><td class="param-name">digest</td><td class="param-type">string</td><td>当前层的内容摘要</td></tr>
<tr><td class="param-name">total</td><td class="param-type">integer</td><td>总字节数</td></tr>
<tr><td class="param-name">completed</td><td class="param-type">integer</td><td>已传输字节数</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'pull-sdk')">SDK · 进度条</button>
<button class="code-tab" onclick="switchTab(this, 'pull-http')">HTTP · 进度条</button>
</div>
<div class="code-block">
<div class="code-panel active" id="pull-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 下载模型并显示进度</span>
<span class="hl-kw">const</span> stream = <span class="hl-kw">await</span> ollama.<span class="hl-fn">pull</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span>, <span class="hl-prop">stream</span>: <span class="hl-kw">true</span> });
<span class="hl-kw">for await</span> (<span class="hl-kw">const</span> chunk <span class="hl-kw">of</span> stream) {
<span class="hl-kw">if</span> (chunk.total && chunk.completed) {
<span class="hl-kw">const</span> pct = ((chunk.completed / chunk.total) * <span class="hl-num">100</span>).<span class="hl-fn">toFixed</span>(<span class="hl-num">1</span>);
<span class="hl-kw">const</span> doneMB = (chunk.completed / 1e6).<span class="hl-fn">toFixed</span>(<span class="hl-num">0</span>);
<span class="hl-kw">const</span> totalMB = (chunk.total / 1e6).<span class="hl-fn">toFixed</span>(<span class="hl-num">0</span>);
process.stdout.<span class="hl-fn">write</span>(<span class="hl-str">`\r${chunk.status}: ${pct}% (${doneMB}/${totalMB} MB)`</span>);
} <span class="hl-kw">else</span> {
console.<span class="hl-fn">log</span>(chunk.status);
}
}
console.<span class="hl-fn">log</span>(<span class="hl-str">'\n下载完成!'</span>);</pre>
</div>
<div class="code-panel" id="pull-http">
<pre><span class="hl-cm">// HTTP 下载模型并跟踪进度</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/pull'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({ <span class="hl-prop">model</span>: <span class="hl-str">'gemma3'</span> }),
});
<span class="hl-kw">const</span> reader = response.body.getReader();
<span class="hl-kw">const</span> decoder = <span class="hl-kw">new</span> <span class="hl-fn">TextDecoder</span>();
<span class="hl-kw">let</span> buffer = <span class="hl-str">''</span>;
<span class="hl-kw">while</span> (<span class="hl-kw">true</span>) {
<span class="hl-kw">const</span> { done, value } = <span class="hl-kw">await</span> reader.<span class="hl-fn">read</span>();
<span class="hl-kw">if</span> (done) <span class="hl-kw">break</span>;
buffer += decoder.<span class="hl-fn">decode</span>(value, { <span class="hl-prop">stream</span>: <span class="hl-kw">true</span> });
<span class="hl-kw">const</span> lines = buffer.<span class="hl-fn">split</span>(<span class="hl-str">'\n'</span>);
buffer = lines.<span class="hl-fn">pop</span>();
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> line <span class="hl-kw">of</span> lines) {
<span class="hl-kw">if</span> (!line.<span class="hl-fn">trim</span>()) <span class="hl-kw">continue</span>;
<span class="hl-kw">const</span> event = JSON.<span class="hl-fn">parse</span>(line);
<span class="hl-kw">if</span> (event.total) {
console.<span class="hl-fn">log</span>(<span class="hl-str">`${event.status}: ${((event.completed / event.total) * 100).toFixed(1)}%`</span>);
}
}
}</pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== PUSH ==================== -->
<section class="api-section" id="push">
<h2><span class="method method-post">POST</span> /api/push</h2>
<p class="desc">将本地自定义模型推送到 Ollama 模型仓库(需要先登录 <code>ollama.com</code>)。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">http://localhost:11434/api/push</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>要推送的模型名称(格式:username/model</td></tr>
<tr><td class="param-name">insecure</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>允许不安全连接</td></tr>
<tr><td class="param-name">stream</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否流式返回进度(默认 true</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'push-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'push-http')">HTTP</button>
</div>
<div class="code-block">
<div class="code-panel active" id="push-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 推送模型到仓库</span>
<span class="hl-kw">const</span> stream = <span class="hl-kw">await</span> ollama.<span class="hl-fn">push</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'my-username/my-custom-model'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>,
});
<span class="hl-kw">for await</span> (<span class="hl-kw">const</span> chunk <span class="hl-kw">of</span> stream) {
<span class="hl-kw">if</span> (chunk.total && chunk.completed) {
<span class="hl-kw">const</span> pct = ((chunk.completed / chunk.total) * <span class="hl-num">100</span>).<span class="hl-fn">toFixed</span>(<span class="hl-num">1</span>);
process.stdout.<span class="hl-fn">write</span>(<span class="hl-str">`\r推送进度: ${pct}%`</span>);
}
}
console.<span class="hl-fn">log</span>(<span class="hl-str">'\n推送完成!'</span>);</pre>
</div>
<div class="code-panel" id="push-http">
<pre><span class="hl-cm">// HTTP 推送模型</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/push'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: { <span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span> },
<span class="hl-prop">body</span>: <span class="hl-fn">JSON.stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'my-username/my-model'</span>,
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
}),
});
<span class="hl-kw">const</span> result = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(result.status); <span class="hl-cm">// "success"</span></pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== PS ==================== -->
<section class="api-section" id="ps">
<h2><span class="method method-get">GET</span> /api/ps</h2>
<p class="desc">列出当前正在内存中运行的模型。显示 VRAM 占用、上下文长度、过期时间等信息。</p>
<div class="endpoint-bar">
<span class="http-method method-get">GET</span>
<span class="url">http://localhost:11434/api/ps</span>
</div>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">models[]</td><td class="param-type">array</td><td>正在运行的模型列表</td></tr>
<tr><td class="param-name">models[].name</td><td class="param-type">string</td><td>模型名称</td></tr>
<tr><td class="param-name">models[].size</td><td class="param-type">integer</td><td>模型大小(字节)</td></tr>
<tr><td class="param-name">models[].digest</td><td class="param-type">string</td><td>SHA256 摘要</td></tr>
<tr><td class="param-name">models[].details</td><td class="param-type">object</td><td>格式、家族等详细信息</td></tr>
<tr><td class="param-name">models[].expires_at</td><td class="param-type">string</td><td>模型自动卸载时间</td></tr>
<tr><td class="param-name">models[].size_vram</td><td class="param-type">integer</td><td>VRAM 占用(字节)</td></tr>
<tr><td class="param-name">models[].context_length</td><td class="param-type">integer</td><td>当前上下文长度</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'ps-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'ps-http')">HTTP</button>
</div>
<div class="code-block">
<div class="code-panel active" id="ps-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 列出正在运行的模型</span>
<span class="hl-kw">const</span> { models } = <span class="hl-kw">await</span> ollama.<span class="hl-fn">ps</span>();
<span class="hl-kw">if</span> (models.length === <span class="hl-num">0</span>) {
console.<span class="hl-fn">log</span>(<span class="hl-str">'当前没有运行中的模型'</span>);
} <span class="hl-kw">else</span> {
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> m <span class="hl-kw">of</span> models) {
console.<span class="hl-fn">log</span>(<span class="hl-str">`模型: ${m.name}`</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">` VRAM: ${(m.size_vram / 1e9).toFixed(2)} GB`</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">` 上下文: ${m.context_length} tokens`</span>);
console.<span class="hl-fn">log</span>(<span class="hl-str">` 过期: ${m.expires_at}`</span>);
}
}</pre>
</div>
<div class="code-panel" id="ps-http">
<pre><span class="hl-cm">// HTTP 列出运行中的模型</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/ps'</span>);
<span class="hl-kw">const</span> { models } = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">`运行中: ${models.length} 个模型`</span>);
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> m <span class="hl-kw">of</span> models) {
console.<span class="hl-fn">log</span>(<span class="hl-str">` ${m.name} → VRAM: ${(m.size_vram / 1e9).toFixed(2)} GB`</span>);
}</pre>
</div>
</div>
<div class="response-title">📤 响应示例</div>
<div class="response-block">
<pre>{
<span class="hl-prop">"models"</span>: [
{
<span class="hl-prop">"name"</span>: <span class="hl-str">"gemma3:latest"</span>,
<span class="hl-prop">"model"</span>: <span class="hl-str">"gemma3:latest"</span>,
<span class="hl-prop">"size"</span>: <span class="hl-num">6591830464</span>,
<span class="hl-prop">"digest"</span>: <span class="hl-str">"a2af6cc3eb7fa..."</span>,
<span class="hl-prop">"details"</span>: {
<span class="hl-prop">"parent_model"</span>: <span class="hl-str">""</span>,
<span class="hl-prop">"format"</span>: <span class="hl-str">"gguf"</span>,
<span class="hl-prop">"family"</span>: <span class="hl-str">"gemma3"</span>,
<span class="hl-prop">"families"</span>: [<span class="hl-str">"gemma3"</span>],
<span class="hl-prop">"parameter_size"</span>: <span class="hl-str">"4.3B"</span>,
<span class="hl-prop">"quantization_level"</span>: <span class="hl-str">"Q4_K_M"</span>
},
<span class="hl-prop">"expires_at"</span>: <span class="hl-str">"2026-05-18T16:47:07.93355+08:00"</span>,
<span class="hl-prop">"size_vram"</span>: <span class="hl-num">5333539264</span>,
<span class="hl-prop">"context_length"</span>: <span class="hl-num">4096</span>
}
]
}</pre>
</div>
</section>
<hr class="section-divider">
<!-- ==================== VERSION ==================== -->
<section class="api-section" id="version">
<h2><span class="method method-get">GET</span> /api/version</h2>
<p class="desc">获取当前 Ollama 服务的版本号。</p>
<div class="endpoint-bar">
<span class="http-method method-get">GET</span>
<span class="url">http://localhost:11434/api/version</span>
</div>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">version</td><td class="param-type">string</td><td>Ollama 版本号</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'ver-sdk')">SDK</button>
<button class="code-tab" onclick="switchTab(this, 'ver-http')">HTTP</button>
</div>
<div class="code-block">
<div class="code-panel active" id="ver-sdk">
<pre><span class="hl-kw">import</span> Ollama <span class="hl-kw">from</span> <span class="hl-str">'ollama'</span>;
<span class="hl-kw">const</span> ollama = <span class="hl-kw">new</span> <span class="hl-fn">Ollama</span>();
<span class="hl-cm">// 获取版本</span>
<span class="hl-kw">const</span> { version } = <span class="hl-kw">await</span> ollama.<span class="hl-fn">version</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">`Ollama 版本: ${version}`</span>); <span class="hl-cm">// 如 "0.12.6"</span></pre>
</div>
<div class="code-panel" id="ver-http">
<pre><span class="hl-cm">// HTTP 获取版本</span>
<span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'http://localhost:11434/api/version'</span>);
<span class="hl-kw">const</span> { version } = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">`Ollama 版本: ${version}`</span>);</pre>
</div>
</div>
<div class="response-title">📤 响应示例</div>
<div class="response-block">
<pre>{
<span class="hl-prop">"version"</span>: <span class="hl-str">"0.12.6"</span>
}</pre>
</div>
</section>
<!-- FOOTER -->
<div style="text-align:center; padding: 40px 0 20px; color: var(--text-dim); font-size: 13px; border-top: 1px solid var(--border);">
<p>📄 本文档基于 <a href="https://docs.ollama.com" style="color:var(--accent)">docs.ollama.com</a> 官方文档生成</p>
<p>支持模型: <strong style="color:var(--green)">gpt-oss · Gemma 3 · DeepSeek-R1 · Qwen3</strong> · 文档日期: <strong style="color:var(--accent)">2026-05-18</strong></p>
<p style="margin-top:8px;">JavaScript SDK: <a href="https://github.com/ollama/ollama-js" style="color:var(--accent)">github.com/ollama/ollama-js</a> · Python SDK: <a href="https://github.com/ollama/ollama-python" style="color:var(--accent)">github.com/ollama/ollama-python</a></p>
</div>
</div>
</div>
<script>
function switchTab(clickedTab, panelId) {
const tabContainer = clickedTab.parentElement;
const blockContainer = tabContainer.nextElementSibling;
tabContainer.querySelectorAll('.code-tab').forEach(t => t.classList.remove('active'));
blockContainer.querySelectorAll('.code-panel').forEach(p => p.classList.remove('active'));
clickedTab.classList.add('active');
document.getElementById(panelId).classList.add('active');
}
// Smooth scroll for sidebar links
document.querySelectorAll('.sidebar a[href^="#"]').forEach(a => {
a.addEventListener('click', e => {
e.preventDefault();
const target = document.querySelector(a.getAttribute('href'));
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
});
// Highlight active sidebar item on scroll
const sections = document.querySelectorAll('.api-section');
const sidebarLinks = document.querySelectorAll('.sidebar a[href^="#"]');
window.addEventListener('scroll', () => {
let current = '';
sections.forEach(s => {
if (window.scrollY >= s.offsetTop - 100) current = s.id;
});
sidebarLinks.forEach(a => {
a.classList.toggle('active', a.getAttribute('href') === '#' + current);
});
});
</script>
</body>
</html>