@easbot/ollama-sdk
v0.1.7
Published
Ollama provider for Vercel AI SDK - Run local LLMs with Ollama in your AI applications
Readme
@easbot/ollama-sdk
AI SDK v2 兼容的 Ollama Provider,自动生成完整的事件流。
特性
- ✅ 完整的 AI SDK v3 兼容性
- ✅ 工具调用支持(Tool Calling)
- ✅ 自动生成完整的事件流
- ✅ 原生 Ollama 实现,无需额外依赖
- ✅ TypeScript 类型支持
- ✅ 流式和非流式生成
- ✅ 完整的错误处理
- ✅ 标签推理支持
安装
pnpm add @easbot/ollama-sdk ai快速开始
基本用法
import { NativeOllamaLanguageModel } from '@easbot/ollama-sdk';
import { streamText } from 'ai';
// 创建 Ollama 模型
const model = new NativeOllamaLanguageModel('qwen3:0.6b', {
baseURL: 'http://localhost:11434', // 可选,默认值
});
// 流式生成
const result = await streamText({
model,
prompt: 'Hello, world!',
});
for await (const chunk of result.textStream) {
console.log(chunk);
}工具调用(Tool Calling)
import { NativeOllamaLanguageModel } from '@easbot/ollama-sdk';
import { generateText } from 'ai';
const model = new NativeOllamaLanguageModel('qwen3:0.6b');
// 定义工具
const tools = {
read_file: {
description: '读取文件内容',
parameters: {
type: 'object',
properties: {
path: {
type: 'string',
description: '文件路径',
},
},
required: ['path'],
},
execute: async ({ path }: { path: string }) => {
const fs = await import('fs/promises');
return await fs.readFile(path, 'utf-8');
},
},
};
// 使用工具调用
const result = await generateText({
model,
tools,
prompt: '请读取 package.json 文件的内容',
});
console.log(result.text);非流式生成
import { generateText } from 'ai';
const model = new NativeOllamaLanguageModel('qwen3:0.6b');
const result = await generateText({
model,
prompt: 'What is the capital of France?',
});
console.log(result.text);系统要求
Ollama 版本要求
- 工具调用功能: 需要 Ollama 0.1.26 或更高版本
- 基本文本生成: 支持所有 Ollama 版本
支持的模型
工具调用功能需要使用支持工具调用的模型,推荐:
qwen3:0.6b- 轻量级,适合开发测试qwen2.5:7b- 平衡性能和质量llama3.1:8b- 高质量工具调用mistral:7b- 通用模型
检查模型是否支持工具调用:
ollama show <model-name>查看模型信息中的 tools 字段。
多种调用方式
// 方式 1: 直接创建模型实例
const model1 = new NativeOllamaLanguageModel('qwen3:0.6b');
// 方式 2: 自定义 baseURL
const model2 = new NativeOllamaLanguageModel('qwen3:0.6b', {
baseURL: 'http://192.168.1.100:11434',
});
// 方式 3: 使用不同的模型
const model3 = new NativeOllamaLanguageModel('llama3.1:8b');工具调用详解
工具定义格式
工具定义遵循 AI SDK v2 规范,使用 inputSchema 字段:
const tools = {
tool_name: {
description: '工具描述',
inputSchema: {
type: 'object',
properties: {
param1: {
type: 'string',
description: '参数描述',
},
param2: {
type: 'number',
description: '数字参数',
},
},
required: ['param1'],
},
execute: async (args) => {
// 工具执行逻辑
return result;
},
},
};工具调用事件流
流式工具调用会生成以下事件序列:
response-metadata
↓
tool-input-start (工具调用开始)
↓
tool-input-delta (参数累积,多次)
↓
tool-input-end (参数接收完成)
↓
tool-call (工具调用完成)
↓
finish (finishReason: 'tool-calls')工具调用循环
AI SDK 会自动处理工具调用循环:
const result = await generateText({
model,
tools,
prompt: '请读取 package.json 并分析其内容',
maxSteps: 5, // 最多执行 5 轮工具调用
});
// AI SDK 会自动:
// 1. 调用工具
// 2. 将工具结果返回给模型
// 3. 继续生成直到完成或达到 maxSteps工具调用 + 推理
模型可以同时使用工具调用和推理( 标签):
const result = await streamText({
model,
tools,
prompt: '分析这个问题并使用工具解决',
});
for await (const event of result.fullStream) {
switch (event.type) {
case 'reasoning-delta':
console.log('[推理]', event.delta);
break;
case 'text-delta':
console.log('[文本]', event.delta);
break;
case 'tool-call':
console.log('[工具调用]', event.toolName, event.input);
break;
}
}限制和注意事项
工具调用限制
- 模型支持: 并非所有 Ollama 模型都支持工具调用,请使用支持的模型
- 参数格式: 工具参数必须是有效的 JSON 对象
- 并发调用: 单次响应可以包含多个工具调用,但它们是顺序执行的
- 参数大小: 避免传递过大的参数(建议 < 10KB)
推理标签限制
- 标签格式: 必须使用
<think>...</think>格式 - 嵌套: 不支持嵌套的 think 标签
- 混合内容: 可以与普通文本和工具调用混合使用
性能考虑
- 流式优先: 对于长文本生成,优先使用流式 API
- 工具数量: 建议每次请求提供的工具数量 < 20 个
- 参数验证: 在工具执行前验证参数,避免无效调用
常见问题(FAQ)
Q: 如何检查 Ollama 版本?
ollama --version如果版本低于 0.1.26,请升级:
# macOS/Linux
curl -fsSL https://ollama.com/install.sh | sh
# Windows
# 从 https://ollama.com/download 下载最新版本Q: 工具调用不生效怎么办?
- 检查 Ollama 版本是否 >= 0.1.26
- 确认模型支持工具调用(使用
ollama show <model>) - 检查工具定义格式是否正确(使用
inputSchema而不是parameters) - 查看日志输出,确认是否有错误信息
Q: 如何调试工具调用?
启用调试日志:
import { Log } from '@easbot/ollama-sdk';
// 初始化日志系统
await Log.init({
print: true,
dev: true,
level: 'DEBUG', // 启用 DEBUG 级别日志
});
// 现在所有工具调用的详细信息都会输出到控制台Q: 支持哪些工具参数类型?
支持所有 JSON Schema 类型:
string- 字符串number- 数字boolean- 布尔值object- 对象array- 数组null- 空值
Q: 如何处理工具调用错误?
const tools = {
risky_operation: {
description: '可能失败的操作',
inputSchema: { /* ... */ },
execute: async (args) => {
try {
// 执行操作
return result;
} catch (error) {
// 返回错误信息给模型
throw new Error(`操作失败: ${error.message}`);
}
},
},
};Q: 向后兼容性如何?
完全向后兼容:
- 不提供
tools参数时,行为与之前完全一致 - 现有的文本生成和推理功能不受影响
- API 签名保持不变
示例代码
完整的使用示例请参考:
API 参考
NativeOllamaLanguageModel
原生 Ollama 语言模型实现,完全兼容 AI SDK v2。
构造函数:
new NativeOllamaLanguageModel(modelId: string, config?: {
baseURL?: string;
})参数:
modelId(string): Ollama 模型 ID(例如:'qwen3:0.6b'、'llama3.1:8b')config(可选): 模型配置baseURL(string): Ollama API 基础 URL,默认'http://localhost:11434'
方法:
doStream(options): 流式生成,返回 ReadableStreamdoGenerate(options): 非流式生成,返回完整结果
示例:
const model = new NativeOllamaLanguageModel('qwen3:0.6b', {
baseURL: 'http://localhost:11434',
});
// 流式生成
const streamResult = await model.doStream({
prompt: [
{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }
],
tools: [/* ... */],
});
// 非流式生成
const generateResult = await model.doGenerate({
prompt: [
{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }
],
tools: [/* ... */],
});事件流
本 SDK 生成完整的 AI SDK v2 事件流,包括:
基本事件
- response-metadata - 首个事件,包含模型 ID 和时间戳
- text-start - 在第一个 text-delta 之前发出
- text-delta - 文本内容增量(多次)
- text-end - 在所有 text-delta 之后发出
- finish - 最后一个事件,包含 finishReason 和 usage
工具调用事件
- tool-input-start - 工具调用开始,包含 toolName
- tool-input-delta - 工具参数增量(多次)
- tool-input-end - 工具参数接收完成
- tool-call - 工具调用完成,包含完整参数
推理事件
- reasoning-start - 推理开始( 标签)
- reasoning-delta - 推理内容增量(多次)
- reasoning-end - 推理结束( 标签)
事件流顺序示例
纯文本生成:
response-metadata → text-start → text-delta (多次) → text-end → finish工具调用:
response-metadata → tool-input-start → tool-input-delta (多次) →
tool-input-end → tool-call → finish (finishReason: 'tool-calls')推理 + 文本:
response-metadata → reasoning-start → reasoning-delta (多次) →
reasoning-end → text-start → text-delta (多次) → text-end → finish工具调用 + 推理:
response-metadata → reasoning-start → reasoning-delta (多次) →
reasoning-end → tool-input-start → tool-input-delta (多次) →
tool-input-end → tool-call → finish错误处理
SDK 提供了完整的错误类型:
import {
InvalidToolDefinitionError,
} from '@easbot/ollama-sdk';
try {
const model = new NativeOllamaLanguageModel('qwen3:0.6b');
const result = await generateText({
model,
tools: {
invalid_tool: {
// 缺少 inputSchema 字段
description: '无效的工具',
} as any,
},
prompt: 'Hello',
});
} catch (error) {
if (error instanceof InvalidToolDefinitionError) {
console.error('工具定义无效:', error.toolName, error.missingField);
} else {
console.error('其他错误:', error);
}
}错误事件
在流式处理中,错误会作为事件发出:
const result = await model.doStream({
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
});
for await (const event of result.stream) {
if (event.type === 'error') {
console.error('流式错误:', event.error);
} else if (event.type === 'finish') {
if (event.finishReason === 'error') {
console.error('生成过程出错');
}
}
}架构
本 SDK 是完全原生的 Ollama 实现,直接调用 Ollama HTTP API:
用户代码
↓
@easbot/ollama-sdk
├── NativeOllamaLanguageModel - 语言模型实现
│ ├── doGenerate() - 非流式生成
│ └── doStream() - 流式生成 + 事件流生成
├── NativeOllamaClient - HTTP 客户端
│ ├── chat() - 非流式请求
│ └── streamChat() - 流式请求
├── prepareTools() - 工具定义转换
├── convertToOllamaMessages() - 消息格式转换
└── Log - 结构化日志系统
↓
Ollama HTTP API特点
- 零依赖: 不依赖
ai-sdk-ollama或其他第三方库 - 完整实现: 完全符合 AI SDK v2 规范
- 高性能: 批量事件队列、及时状态清理
- 可调试: 结构化日志、trace ID 追踪
与其他实现的对比
vs ai-sdk-ollama
- ✅ 完整的工具调用支持(ai-sdk-ollama 不支持)
- ✅ 完整的 AI SDK v3 事件流
- ✅ 更好的 TypeScript 类型支持
- ✅ 完整的错误处理
- ✅ 结构化日志和调试支持
- ✅ 零额外依赖
- ✅ 更简洁的 API
vs ollama-ai-provider
- ✅ 原生实现,更稳定
- ✅ 工具调用支持
- ✅ 自动事件流生成
- ✅ 更简洁的 API
开发
# 安装依赖
pnpm install
# 构建
pnpm build
# 测试
pnpm test
# 类型检查
pnpm type-check
# Lint
pnpm lint许可证
MIT
贡献
欢迎提交 Issue 和 Pull Request!
