開發人員可透過 Prompt API,使用 Gemini Nano 直接在瀏覽器中執行自然語言處理工作。這種內建 AI 的做法可確保使用者隱私、降低伺服器成本,並啟用離線功能。
1. 入門指南和硬體需求
Prompt API 目前適用於 Chrome 148 以上版本 (電腦版),支援 Windows、macOS、Linux 和 Chromebook Plus。
硬體必要條件
- 儲存空間:22 GB 可用空間 (用於初始設定檔和模型)。
- 記憶體/CPU:16 GB RAM 和 4 個以上的 CPU 核心。
- GPU:4 GB VRAM 以上 (音訊輸入必備)。
- 網路:只有在初次下載模型時才需要。
初始化 API
觸發下載前,請先檢查模型是否可用:
const availability = await LanguageModel.availability();
// Do not call create() when unavailable — the model cannot run on this device.
if (availability !== 'unavailable') {
const session = await LanguageModel.create({
monitor(m) {
// Inform the user while the model downloads so the UI doesn't appear frozen.
m.addEventListener('downloadprogress', (e) => {
console.log(`Downloaded ${e.loaded * 100}%`);
});
},
});
}
2. 核心提示功能
為求簡潔,本節的工作階段範例會省略 session.destroy()。不再需要工作階段時,請務必呼叫 session.destroy(),釋出裝置記憶體 (請參閱第 5 節)。
基本和串流輸出
如果是簡短回覆,請使用 prompt()。如要顯示較長的內容,請使用 promptStreaming() 提供回應更快速的使用者介面。
強制:請勿將模型輸出內容指派給 innerHTML。模型輸出內容不受信任,可能含有插入的標記。請一律使用 textContent 或淨化器。
const session = await LanguageModel.create();
// prompt() accumulates the full response before resolving — use for short, one-shot output.
const result = await session.prompt('Write a haiku about coding.');
// textContent, not innerHTML — model output is untrusted and must not be parsed as markup.
outputEl.textContent = result;
// promptStreaming() yields independent chunks that must be concatenated;
// use for longer content so each chunk can be rendered progressively.
const stream = session.promptStreaming('Write a long story about a robot.');
let completeResult = '';
for await (const chunk of stream) {
completeResult += chunk;
outputEl.append(chunk);
}
console.log('Full story:', completeResult);
多模態輸入
Prompt API 支援文字、音訊和視覺輸入內容 (圖片、畫布、影片影格)。
const session = await LanguageModel.create({
// Declaring expected input types lets the browser optimize model loading.
expectedInputs: [{ type: 'text' }, { type: 'image' }],
expectedOutputs: [{ type: 'text' }],
});
const response = await session.prompt([
{
role: 'user',
content: [
{ type: 'text', value: 'What is in this image?' },
{ type: 'image', value: document.querySelector('canvas') },
],
},
]);
3. 進階工作階段管理
工作階段可讓模型在多次互動中維持脈絡。
背景資訊和配額
每個工作階段都有權杖數量上限。您可以透過 session.contextUsage 和 session.contextWindow 監控用量。如果視窗溢位,系統會捨棄最舊的訊息 (系統提示除外)。
複製工作階段
複製功能可有效率地啟動平行對話,共用相同的初始情境 (例如「系統」角色),不必重新初始化。
const mainSession = await LanguageModel.create({
initialPrompts: [{ role: 'system', content: 'You speak like a pirate.' }],
});
const branchA = await mainSession.clone();
const branchB = await mainSession.clone();
// Destroy the base after cloning — the clones own their own context from here.
mainSession.destroy();
還原過往工作階段
原生「還原」功能仍在開發中,但您可以將先前的記錄提供給 initialPrompts,重新建立工作階段。
注意:localStorage 未加密且會永久保存。儲存的對話記錄可能包含使用者 PII,因此在保留即時通訊記錄前,請考量隱私權影響。
// || '[]' ensures JSON.parse never receives null when the key doesn't exist yet.
const history = JSON.parse(localStorage.getItem('chat_history') || '[]');
const session = await LanguageModel.create({
initialPrompts: history, // Array of {role, content} objects
});
4. 使用 JSON 結構定義輸出結構化內容
為避免模型加入「閒聊」內容 (例如「好的,這是您的 JSON:」),請透過 responseConstraint 欄位使用 JSON 結構定義。這可確保輸出內容是有效的 JSON,能立即剖析。
範例:情緒分類
// Pass the schema as a plain object — do not JSON.stringify() it first.
const schema = {
type: 'object',
properties: {
rating: { type: 'number', minimum: 1, maximum: 5 },
is_positive: { type: 'boolean' },
},
required: ['rating', 'is_positive'],
};
const result = await session.prompt(
"Rate the following feedback: 'The food was great!'",
{ responseConstraint: schema },
);
const data = JSON.parse(result);
console.log(data.rating); // 5
限制和前置字元
您可以使用 prefix: true 預先填入助理的回覆,進一步引導模型。
const character = await session.prompt([
{ role: 'user', content: 'Create a character sheet' },
{ role: 'assistant', content: '```json\n', prefix: true },
]);
5. 最佳做法和安全
- 資源清理:對話結束時,請務必呼叫
session.destroy(),釋出記憶體。 - 輸出內容安全性:模型輸出內容不可信。請一律將結果寫入
textContent,而非innerHTML,以免惡意模型輸出內容注入 XSS。 - 如需允許有限的 HTML,請使用原生 Sanitizer API 或 DOMPurify 等淨化工具。
- 中止工作:使用
AbortController,讓使用者停止長時間執行的生成作業。將signal傳遞至prompt()或promptStreaming(),而非LanguageModel.create()。 - 安全性:使用權限政策控管 iframe 中的存取權:
<iframe src="..." allow="language-model"></iframe>。 - 設計:詳閱 People + AI Guidebook,確保以負責任的方式導入 AI。
結合結構化輸出內容和強大的工作階段管理功能,開發人員就能建構複雜的有狀態 AI 應用程式,完全在使用者裝置上執行。
建議做法
如需完整的注意事項清單,請參閱 https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt。以下是重點摘要:
在合理的時間準備模型
適用對象:所有 API,例如 Summarizer、Translator 和 Writer。
建議做法:一旦明確確認使用者有意使用 AI 功能,就立即初始化工作階段。例如,使用者前往相關 AI 工具介面、將滑鼠游標懸停在 AI 工作區上,或與功能周圍的 UI 互動時。預先暖機工作階段可讓模型在使用者設定工作時,在背景安靜地載入記憶體,避免冷啟動延遲。舉例來說,如果功能設計為反覆使用,請在開始算繪目前結果時,立即啟動下一個最可能的 AI 任務,盡可能提前完成。
不建議:除非必要,否則請勿等到使用者點選「生成」才初始化工作階段。這會導致冷啟動延遲,因為模型必須先載入記憶體,並準備執行管道。
在建立時設定初始提示
適用對象:Prompt API。
建議做法:在工作階段初始化期間提供系統指令,加快第一個提示的處理速度。
不建議:從空白工作階段開始,並在第一次 prompt() 呼叫中傳送系統指令。這會迫使模型在最後一刻處理這些指令,因此會增加延遲時間。
複製工作階段,處理重複性工作
適用對象:Prompt API。
在 Prompt API 中,每個工作階段都會追蹤對話的背景資訊,並考量所有先前的互動。由於複製工作階段會繼承父項工作階段的所有內容,包括初始提示和複製前的所有互動記錄,因此請妥善規劃,僅繼承所需內容。
建議做法:
- 建立基本工作階段:如要有效處理不相關的工作,請建立基本工作階段,其中只包含系統指令,不含先前的對話內容。
- 複製基準:在新任務中使用
clone()複製基準工作階段,省去重新剖析系統指令的負擔。這樣就能建立平行對話,或將工作重設為基準。
錯誤做法:
- 請勿將同一個工作階段重複用於不相關的工作,也避免複製已包含不必要互動記錄的工作階段。這兩種模式都可能導致不相關的先前內容干擾目前的工作。
- 請勿使用相同的系統指令重複呼叫
create()。請改用複製模式,盡可能提高效能。
刪除未使用的工作階段
適用對象:所有 API。
建議做法:在不再需要的功能工作階段中,明確呼叫 destroy(),釋出記憶體。如果使用複製模式,請保留基本工作階段,並刪除不再需要的複製工作階段。
不建議:同時執行多個大型工作階段。每個工作階段都會耗用記憶體,造成不必要的資源用量,並可能成為問題。工作階段會由垃圾收集器自然清除,但呼叫 destroy() 可更快釋出記憶體。
安全有效率地轉譯串流回應
適用對象:所有支援串流的 API (Prompt、Summarizer、Writer、Rewriter 和 Translator)。
建議做法:將所有 LLM 輸出內容視為不可信內容。請清理完整的合併輸出內容,而非僅清理部分內容,因為惡意程式碼可能會分散在不同更新中。在轉譯前,請盡可能使用 Sanitizer API。為避免效能降低,請使用串流 Markdown 剖析器,例如 streaming-markdown。
不建議:在每次更新區塊時直接設定 innerHTML。這種做法速度緩慢,尤其是語法醒目顯示等複雜格式,而且容易受到插入攻擊。
最佳化輸入速度
適用對象:所有 API。
建議做法:只將絕對必要的資訊傳遞給模型。去除與手邊任務無關的所有內容。如果是大型資料集,請提供簡短總覽和一小部分相關項目。
不建議:將未經處理的原始文字、不必要的中繼資料、HTML 代碼或未經篩選的大型清單傳送至 API。延遲時間會隨著輸入內容大小而大幅增加,這可能會讓 AI 功能在許多裝置上看起來像是故障。
使用結構化輸出內容,取得可預測的結果
適用對象:Prompt API。
建議做法:如需模型以特定格式傳回資料,請提供 responseConstraint 欄位來提供 JSON 結構定義,使用結構化輸出。這可確保輸出內容符合預期,避免需要複雜的後續處理或手動剖析。
不建議:僅仰賴自然語言指令 (例如「僅輸出 JSON」)。模型可能會加入對話填充詞,導致剖析器中斷。
生成內容不受長度限制
適用對象:Prompt API,因為這是唯一支援結構化輸出結構定義的 API。
建議做法:讓模型自然生成回覆,然後使用用戶端邏輯截斷文字,以符合 UI。
不建議:使用結構化輸出結構定義,強制執行 maxLength: 125 等嚴格的字元限制。如果模型的回覆長度超過設定的限制,模型可能會切換至高密度詞元 (例如外語或表情符號) 來壓縮含義,導致輸出內容不合理。
確保使用者知情
適用對象:所有 API。
建議做法:視工作的複雜度和預期時間長度,使用動畫、視覺提示和進度指標,讓使用者瞭解進度。最佳做法取決於您的用途和預期的 API 輸出長度。這裡提供一些想法:
- 串流長篇內容:如果是摘要或對話,串流預設會建立逐詞打字機效果。這種方式感覺自然,且能立即提供意見回饋。
- 非串流模式適合短任務 (或長時間非同步任務):如果輸出內容較短 (例如替代文字),非串流模式可提供更精緻的使用者介面。此外,在算繪目前 AI 任務時,也有時間預先準備下一個 AI 任務。這種做法也適用於較長的非同步或背景工作。如果使用者不必等待輸出內容,就能繼續操作,則不必在輸出內容產生時立即提供。在 UI 中顯示程序正在進行。
- 更新時的視覺轉場效果:翻譯或重寫文字時,請使用動畫,例如文字變形。
不建議:更新 UI 時不提供視覺提示。
符合使用者對時間和工作的心理模型
適用對象:所有 API。
建議做法:如果回覆幾乎是即時,請考慮人工延遲一或兩秒。矛盾的是,如果使用者認為生成過程與他們認知的任務難度相符,可能會覺得結果更值得信賴。使用動畫表示 AI 處理中。
不建議:突然更換 UI,讓使用者措手不及。
允許使用者快速瀏覽及復原 AI 編輯內容
適用對象:所有 API。
建議做法:在 UI 中加入步進器或導覽記錄,讓使用者能放心探索不同結果,並快速復原 AI 編輯內容。這樣一來,您仍可輕鬆取得不同版本。
不建議:覆寫使用者先前的草稿,或他們可能喜歡的 AI 結果,卻無法返回、還原或比較版本。
賦予使用者控制權和覆寫權
適用對象:所有 API。
建議做法:讓使用者成為所有生成內容的最終編輯者。提供直覺式的覆寫功能,讓使用者能完全掌控最終輸出內容。API 可能會產生不正確的結果。
不建議:強制將 AI 生成結果設為唯一選項。
快取週期性工作的結果
適用對象:所有 API。
建議做法:針對重複的輸入內容或查詢,導入本機結果快取 (例如使用 sessionStorage 或 IndexedDB)。修剪空白字元並轉換為小寫,將輸入內容正規化,提高快取命中率。如果是耗用大量資源的輸入內容 (例如圖片),請產生雜湊做為快取鍵。為快取設定保守的存留時間 (TTL),或在背景更新快取結果時提供快取結果。如果結果不盡人意,請讓使用者觸發新的推論。
不建議:針對重複的搜尋查詢或相同的資料輸入,重新執行相同的推論,例如使用者在搜尋結果之間來回瀏覽時。 這能盡量提升回應速度,並有效運用本機運算資源。
6. 備用策略
使用前,請檢查 LanguageModel 物件是否可在全域範圍內使用:
if ('LanguageModel' in self) {
// The Prompt API is supported.
} else {
// Execute fallback strategy
}
如果系統不支援 Prompt API,或可用性檢查傳回「無法使用」,請採取適當的備用方案:
- 遠端 API 備用方案:將偵測要求重新導向至伺服器端點或雲端 API (例如 Vertex AI Gemini API)。
- 本機 API 備用方案:將偵測要求重新導向至本機端點,例如使用 Transformers.js。