適用:使用者想要「客服機器人」「問答機器人」,而問題其實是一群固定的常見問題——
檢查前要空腹多久、探病時間、某個表單去哪裡拿、單位內的作業規定。
做法是事先寫好的問答+選單+關鍵字比對,不用 AI,所以:
- 可以設成公開(病人、家屬掃 QR 就能用),也可以只給院內同仁。
- 答案每一句都是負責的科別審過的,不會「自己編」。
先講清楚
- 平台目前沒有 AI 服務(llms.txt §4.6)。使用者說「機器人」時,先用白話確認:
「平台現在不能用 AI。我可以做一個用選單和關鍵字找答案的問答頁,答案是你們事先寫好的。這樣可以嗎?」
- 給病人用的 AI 機器人,平台開放 AI 之後也不行:公開的應用不能用 AI(llms.txt §4.55)。不要承諾「之後換成 AI」。
- 不能記錄大家問了什麼:公開的應用不能存資料。想知道哪些問題常被問,請同仁在現場記下,再來更新題庫。
- 找不到答案時,畫面要給真人管道(單位、分機、服務台位置)。聯絡資料問使用者,不要自己用帳號資料填(llms.txt §2)。
做法
archetype: A,data.collects: [],skills_used: [faq-bot];開放程度照使用者的回答(病人家屬要用就public)。- 題庫是資料,不是程式:放在頁面裡的一個陣列(或同資料夾的
faq.json,用fetch('faq.json')讀)。每一題:
```js
{ id: 'fasting', category: '檢查前準備', q: '抽血前要空腹多久?',
keywords: ['空腹', '禁食', '吃東西', '喝水', '抽血'], a: '一般抽血不用空腹;…', source: '檢驗科', reviewed: '2026-10-01' }
```
- 答案的內容由使用者提供,你只排版。要上網找資料當參考,照 llms.txt §2 先問他、查到的先唸給他確認。
- 每題都要有
source(哪個單位審的)與reviewed(審閱日期),顯示在答案下面。 - 畫面:
- 最上面一句說明:「這是常見問題查詢,答案由○○科整理;不是真人、也不是 AI。」
- 先給分類按鈕(多數人用點的,不用打字),點進去列出題目,點題目看答案。
- 再給一個搜尋框:把使用者打的字和每題的
q、keywords比對,列出最相關的 3–5 題(骨架的search())。 - 找不到時顯示真人管道。緊急狀況(胸痛、呼吸困難…)在頁面最上面寫「請立即就醫或撥 119」。
- 比對的小技巧(骨架已含):全形轉半形、去掉空白與標點、英文轉小寫;同義詞放進
keywords(「禁食」「空腹」「不能吃」)。
不用裝搜尋套件;題目上百題、需要錯字容忍時,用平台提供的 Fuse.js(ES module,llms.txt §4.9):
```html
<script type="module">
import Fuse from 'https://platform.wanfangai.tw/lib/fuse.js@7.5.0/fuse.min.mjs';
const fuse = new Fuse(FAQ, { keys: ['q', 'keywords'], threshold: 0.4 });
const hits = fuse.search('要空腹嗎').slice(0, 5).map((r) => r.item);
</script>
```
- 使用者打的字只用來比對,不要用
innerHTML放回畫面;顯示答案也用textContent。答案要分段就把文字切成多個<p>。
骨架
<!doctype html>
<html lang="zh-Hant">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>檢查前準備常見問題</title>
<style>
body { font-family: system-ui, sans-serif; margin: 0; padding: 16px; line-height: 1.7; max-width: 720px; }
button, input { min-height: 44px; font-size: 16px; }
.cats button { margin: 4px; }
.answer { border-left: 4px solid #2a7; padding: 8px 12px; background: #f5fbf8; }
.meta { color: #666; font-size: 14px; }
</style>
</head>
<body>
<p><strong>緊急狀況請立即就醫或撥 119。</strong></p>
<h1>檢查前準備常見問題</h1>
<p>這是常見問題查詢,答案由檢驗科整理;不是真人,也不是 AI。</p>
<div class="cats" id="cats"></div>
<label>找問題 <input id="q" type="search" placeholder="例如:要空腹嗎"></label>
<ul id="hits"></ul>
<div id="answer"></div>
<p class="meta">找不到答案?請洽檢驗科櫃台,分機 0000。</p>
<script>
const FAQ = [
{ id: 'fasting', category: '抽血', q: '抽血前要空腹多久?', keywords: ['空腹', '禁食', '吃東西', '喝水'],
a: '(由檢驗科提供的答案)', source: '檢驗科', reviewed: '2026-10-01' },
];
const norm = (s) => s.normalize('NFKC').toLowerCase().replace(/[\s\p{P}]/gu, '');
function search(text) {
const t = norm(text);
if (!t) return [];
return FAQ.map((f) => {
let score = norm(f.q).includes(t) ? 3 : 0;
for (const k of f.keywords) if (t.includes(norm(k)) || norm(k).includes(t)) score += 2;
return { f, score };
}).filter((x) => x.score > 0).sort((a, b) => b.score - a.score).slice(0, 5).map((x) => x.f);
}
function show(f) {
const box = document.getElementById('answer');
box.replaceChildren();
box.className = 'answer';
const h = document.createElement('h2');
h.textContent = f.q;
box.append(h);
for (const para of f.a.split('\n')) {
const p = document.createElement('p');
p.textContent = para;
box.append(p);
}
const meta = document.createElement('p');
meta.className = 'meta';
meta.textContent = `資料來源:${f.source}|最後審閱:${f.reviewed}`;
box.append(meta);
}
function list(items) {
const ul = document.getElementById('hits');
ul.replaceChildren();
for (const f of items) {
const li = document.createElement('li');
const b = document.createElement('button');
b.textContent = f.q;
b.addEventListener('click', () => show(f));
li.append(b);
ul.append(li);
}
}
for (const cat of [...new Set(FAQ.map((f) => f.category))]) {
const b = document.createElement('button');
b.textContent = cat;
b.addEventListener('click', () => list(FAQ.filter((f) => f.category === cat)));
document.getElementById('cats').append(b);
}
document.getElementById('q').addEventListener('input', (e) => list(search(e.target.value)));
</script>
</body>
</html>發佈前檢查
- 每一題都有
source與reviewed;答案是使用者給的或他確認過的。 - 頁面寫清楚「不是真人、也不是 AI」,有緊急狀況提示與真人管道。
data.collects是空的;開放程度照他的回答(公開的話,正式版會被搜尋引擎收錄)。- 告訴他:題庫要更新時,跟你說「新增一題/改一題」,再發佈一次就好。