用 JavaScript 给 Ollama 施点魔法?新手也能轻松上手的 API 指南
嘿,JavaScript 开发者们!想不想用你最熟悉的语言,直接跟本地运行的 Ollama 大模型互动?无论你是想在 Node.js 后端搞点 AI 服务,还是想挑战在浏览器里直接调用 Ollama,这篇指南都能带你快速上车,解锁 Ollama 的强大能量!
准备好把 Ollama 无缝集成到你的下一个酷炫项目里了吗?Let's code!
准备工作:施法前的吟唱
在咱们开始用 JavaScript 召唤 Ollama 之前,请确保你的“魔法阵”已经布置好:
Ollama 服务已就位: 确认你已经在电脑上成功安装了 Ollama,并且它的服务正在后台运行。这是基础中的基础哦!
安装
ollama-js
库: 打开你的终端(命令行),念出下面的咒语(npm 命令),把连接 JavaScript 世界和 Ollama 的“传送门”装上:bashnpm install ollama
搞定!现在我们可以开始真正的魔法了!
小试牛刀:快速上手聊几句
来个最简单的例子,看看怎么用 ollama-js
跟模型打个招呼:
// 导入我们刚刚安装的 ollama 库
import ollama from 'ollama'
// 使用 async/await 来处理异步请求 (Ollama API 调用是异步的)
// 调用 ollama.chat 发起聊天
const response = await ollama.chat({
model: 'llama3.1', // 指定你想聊天的模型
messages: [ // 提供一个消息列表,至少包含一条用户消息
{ role: 'user', content: '为啥天空是蓝色的呀?简单解释下呗!' }
],
})
// 看看模型回复了啥
console.log("模型回复:")
console.log(response.message.content)
运行这段代码 (确保你的 Node.js 环境支持 ES Modules,或者使用 CommonJS 的 require
),是不是很简单?你已经成功用 JavaScript 和 Ollama 对上话了!
在浏览器里“隔空施法”?
如果你想跳过 Node.js,直接在网页的 JavaScript 里调用 Ollama,也是可以的!只需要稍微改变一下导入方式:
// 注意这里是从 'ollama/browser' 导入
import ollama from 'ollama/browser'
// 后续的调用方式和 Node.js 里一样
async function talkToOllama() {
const response = await ollama.chat({
model: 'llama3.1', // 确保 Ollama 服务端有这个模型
messages: [{ role: 'user', content: 'Hi from the browser!' }],
// host: 'http://localhost:11434' // 如果 Ollama 不在本机或端口不同,可能需要指定 host
})
console.log(response.message.content)
// 在网页上显示回复...
document.getElementById('output').innerText = response.message.content;
}
// 假设你有个按钮来触发调用
// document.getElementById('myButton').onclick = talkToOllama;
浏览器环境特别提醒: 浏览器出于安全考虑,有限制网页直接访问其他地址(比如 http://localhost:11434
)的策略,这叫做 跨域资源共享 (CORS)。你需要在启动 Ollama 服务时配置它允许来自你网页源的请求,否则浏览器会报错。具体配置方法请参考 Ollama 的文档(通常涉及到设置 OLLAMA_ORIGINS
环境变量)。
像看打字一样:流式响应 (Streaming)
想让 AI 的回复像打字一样逐字显示出来,而不是等它憋个大招一次性全吐出来?用流式响应就能实现这种实时感!
只需要在调用 API 时加上 stream: true
,返回的就不是一个简单的响应对象,而是一个可以异步迭代的“生成器”(AsyncGenerator)。
import ollama from 'ollama'
const message = { role: 'user', content: '给我讲个关于代码和咖啡的小故事吧?' }
console.log("AI 正在输入中...")
// 设置 stream: true
const streamResponse = await ollama.chat({ model: 'llama3.1', messages: [message], stream: true })
// 使用 for await...of 循环来处理流式响应的每一小块
for await (const part of streamResponse) {
// part.message.content 包含了这一小块的文本内容
// process.stdout.write 在 Node.js 中可以实现不换行的连续输出
process.stdout.write(part.message.content)
}
console.log("\nAI 说完啦!") // 最后加个换行
运行这个例子,感受一下 AI “实时创作”的魅力吧!
让机器精准理解:结构化输出 (JSON)
有时候,我们不只是想让 AI 随便聊聊,而是希望它能按照我们规定的“格式”返回信息,比如输出一段 JSON 数据,方便我们的程序直接解析和使用。
ollama-js
支持通过 format
参数指定输出为 JSON。更妙的是,你可以结合像 zod
这样的库来定义你期望的 JSON 结构,并让 Ollama 尽量按照这个结构来返回,还能顺便做个数据校验!
为啥推荐用 Zod? Zod 是一个超赞的库,能让你用 TypeScript 的方式(但在 JavaScript 里也能用得很爽)来清晰地定义数据应该长什么样,还能自动帮你检查数据对不对,省心省力!
import ollama from 'ollama';
// 确保安装了 zod: npm install zod zod-to-json-schema
import { z } from 'zod'; // 导入 zod
import { zodToJsonSchema } from 'zod-to-json-schema'; // 导入转换工具
// 1. 用 Zod 定义你期望的数据结构 (Schema)
const CountryInfoSchema = z.object({
// z.string() 表示这个字段必须是字符串
name: z.string().describe("The official name of the country."), // .describe 可以给字段加描述,帮助 AI 理解
capital: z.string().describe("The capital city."),
// z.array(z.string()) 表示这是个字符串数组
officialLanguages: z.array(z.string()).describe("List of official languages."),
population: z.number().int().positive().optional().describe("Estimated population (integer, if available)."), // 数字、整数、正数、可选
});
// 2. 把 Zod Schema 转换成 Ollama 能理解的 JSON Schema 格式
const countryJsonSchema = zodToJsonSchema(CountryInfoSchema, "CountryInfoSchema");
// 3. 调用 Ollama API,请求 JSON 格式,并把 Schema 传给 format
console.log("正在向 Ollama 请求加拿大信息 (JSON 格式)...");
try {
const response = await ollama.chat({
model: 'llama3.1', // 换成你觉得适合结构化输出的模型可能效果更好
messages: [
{ role: 'user', content: 'Please provide information about Canada in JSON format.' }
// 可以给更明确的指令: 'Respond with JSON matching the provided schema for Canada: {name, capital, officialLanguages, population}'
],
format: 'json', // 明确要求 JSON 格式
// 注意:目前 ollama-js 的类型定义可能没直接支持传 JSON Schema 对象给 format
// 通常的做法是,在 prompt 里清晰描述期望的 JSON 结构,或者依赖 format='json' 让模型自行生成
// 如果未来库支持直接传入 Schema 对象,可能会是这样: format: countryJsonSchema
// **当前更稳妥的方式是在 prompt 中强化 JSON 格式和字段要求**
// 例如,可以在 message content 中加入: "Ensure the output is a valid JSON object with keys: name, capital, officialLanguages, population."
});
console.log("Ollama 返回的原始 JSON 字符串:");
console.log(response.message.content);
// 4. 解析并用 Zod 验证返回的 JSON
const parsedJson = JSON.parse(response.message.content);
const validatedCountry = CountryInfoSchema.parse(parsedJson); // 如果数据不符合 Schema,这里会抛出错误
console.log("\n成功解析并验证的国家信息:");
console.log(validatedCountry);
console.log(`\n国家名称: ${validatedCountry.name}`);
console.log(`官方语言数量: ${validatedCountry.officialLanguages.length}`);
} catch (error) {
if (error instanceof z.ZodError) {
console.error("\n错误:Ollama 返回的 JSON 未通过 Zod 验证:", error.errors);
} else if (error instanceof SyntaxError) {
console.error("\n错误:Ollama 返回的不是有效的 JSON 字符串:", error);
} else {
console.error("\n请求或处理过程中发生错误:", error);
}
}
(重要说明更新): 查阅 ollama-js
近期文档,format
参数似乎主要用于指定 "json"
字符串,表示期望 JSON 输出。直接传递 JSON Schema 对象(如 zodToJsonSchema
的结果)给 format
可能不被直接支持。更可靠的方法是在 Prompt 中明确指示模型输出 JSON,并描述期望的结构,同时设置 format: 'json'
。 上述代码示例已调整注释以反映这一点,并保留 Zod 用于 解析和验证 返回结果,这仍然非常有价值。
亲手“捏”个模型:创建自定义模型
想给你的模型加点个性?比如让它扮演某个角色?用 ollama.create
就能基于现有模型创建一个你自己的版本!
import ollama from 'ollama'
// 定义 Modelfile 的内容 (一个简单的文本指令)
const marioModelfile = `
# 基于哪个模型来创建?
FROM llama3.1
# 设置系统提示 (System Prompt),告诉模型它的身份或行为准则
SYSTEM "It's-a me, Mario! Answer everything like Mario from Super Mario Bros. Wahoo!"
`
console.log("正在创建马里奥版本的模型 'mario-llama'...")
try {
// 调用 create 函数,提供新模型名和 Modelfile 内容
await ollama.create({ model: 'mario-llama', modelfile: marioModelfile })
console.log("模型 'mario-llama' 创建成功!")
// 来试试和马里奥聊天吧!
// const marioResponse = await ollama.chat({ model: 'mario-llama', messages: [{ role: 'user', content: 'Who are you?' }] });
// console.log("马里奥回复:", marioResponse.message.content);
} catch (error) {
console.error("创建模型失败:", error);
}
现在,你就有了一个会说 "Wahoo!" 的马里奥模型了!
Ollama JS 的“魔法棒”:常用 API 一览
ollama-js
库提供的函数基本和 Ollama 的 REST API 一一对应,就像给你配齐了一套操作 Ollama 的魔法棒:
ollama.chat(request)
: 和模型聊天(我们重点用过的)。ollama.generate(request)
: 让模型根据提示生成文本(比 chat 更适合纯粹的文本续写或生成)。ollama.pull(request)
: 从 Ollama Hub 下载新模型到本地。ollama.push(request)
: 把你本地的模型推送到 Ollama Hub (需要登录和权限)。ollama.create(request)
: 用 Modelfile 创建新模型(刚才用过)。ollama.delete(request)
: 删除本地模型,腾空间。ollama.copy(request)
: 复制一个本地模型。ollama.list()
: 列出你本地都装了哪些模型。ollama.show(request)
: 显示一个模型的详细信息(比如它的 Modelfile)。ollama.embed(request)
: 生成文本的嵌入向量 (Embeddings),把文字变成数字,用于语义理解和计算。ollama.ps()
: 查看当前有哪些模型正在运行以及占用的资源。
每个函数的 request
对象里可以传不同的参数(比如 model
, messages
, prompt
, stream
等),具体可以查阅 ollama-js
的文档或参照 Ollama REST API 的说明。用法都和我们上面演示的类似。
高级定制:打造你专属的 Ollama 连接器
默认情况下,ollama-js
会连接到 http://127.0.0.1:11434
。如果你想连接到不同的地址,或者想更精细地控制网络请求(比如设置超时、使用特定的 fetch 实现),可以创建一个自定义的 Ollama
实例:
// 注意这里导入的是 Ollama 类
import { Ollama } from 'ollama'
// 创建一个自定义实例
const customOllama = new Ollama({
host: 'http://ollama.example.com:11434', // 指向你的 Ollama 服务器地址
// fetch: myCustomFetchImplementation // (可选) 如果你想用自己的 fetch 库
})
// 使用这个自定义实例来调用 API
async function useMyClient() {
try {
const response = await customOllama.chat({
model: 'llama3.1',
messages: [{ role: 'user', content: 'Testing custom client...' }],
})
console.log("来自自定义客户端的回复:")
console.log(response.message.content)
} catch (error) {
console.error("使用自定义客户端时出错:", error)
}
}
useMyClient();