aiFS / index.html
bennylam's picture
Update index.html
0ab6ede verified
Raw
History Blame Contribute Delete
8.2 kB
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 工作坊:風水大師 </title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f4f7f6;
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
max-width: 600px;
width: 100%;
background: white;
padding: 25px;
border-radius: 12px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
h2 { text-align: center; color: #333; margin-top: 0; }
.status {
background: #e1f5fe;
color: #0288d1;
padding: 10px;
border-radius: 6px;
font-size: 14px;
margin-bottom: 15px;
text-align: center;
}
.input-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
input[type="text"] {
flex: 1;
padding: 12px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 16px;
}
button {
padding: 12px 20px;
background: #ff5722;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
}
button:disabled { background: #ccc; }
.box {
border: 1px solid #ddd;
padding: 15px;
border-radius: 8px;
background: #fafafa;
margin-bottom: 15px;
min-height: 50px;
}
.box-title {
font-weight: bold;
color: #666;
font-size: 13px;
text-transform: uppercase;
margin-bottom: 5px;
}
.highlight { background-color: #fff9c4; padding: 2px 5px; border-radius: 3px; }
</style>
</head>
<body>
<div class="container">
<h2>🔮 瀏覽器級:AI 風水大師</h2>
<div id="status" class="status">正在初始化 Transformer.js 及加載 AI 模型... (請稍候)</div>
<div class="input-group">
<input type="text" id="userInput" placeholder="例如:我想催旺事業運 / 今年犯太歲點辦?" disabled>
<button id="askBtn" onclick="askMaster()" disabled>請教大師</button>
</div>
<div class="box">
<div class="box-title">📖 RAG 核心:從「風水秘笈」中檢索到的最相關段落</div>
<div id="retrievedContext">未開始檢索。當你發問時,AI 會自動翻閱秘笈...</div>
</div>
<div class="box" style="border-left: 5px solid #ff5722;">
<div class="box-title">💬 大師開示 (AI 基於秘笈生成的解答)</div>
<div id="aiResponse">等待大師開示...</div>
</div>
</div>
<script type="module">
import { pipeline } from 'https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2';
// 1. 定義本地「風水秘笈」知識庫
const fengShuiKnowledgeBase = [
"關於事業運與辦公室:若想催旺事業財運,可在辦公室正東位擺放四枝富貴竹,大忌座位背後無靠山(如無牆壁),會導致小人作祟。",
"關於犯太歲與化解:今年屬蛇、豬、虎、猴的朋友犯太歲,建議前往太歲廟拜太歲,並隨身佩戴保平安的玉佩或生肖飾物以擋煞。",
"關於桃花運與人緣:想催旺姻緣,可在客房或臥室西南方擺放鮮花(如百合或玫瑰),切忌擺放假花或乾花,否則會招來爛桃花。",
"關於家居健康與病位:今年的二黑病符星飛臨正南方,此方位不宜動土,亦不宜放置紅色或黃色地毯,可掛一個銅葫蘆化解病氣。"
];
let embedder;
// 2. 自定義餘弦相似度計算函數 (Cosine Similarity)
// 這裡可以跟學生順便解釋:這是高中數學會學到的 Vector 點積 (Dot Product) 應用!
function calculateCosineSimilarity(vecA, vecB) {
let dotProduct = 0.0;
let normA = 0.0;
let normB = 0.0;
for (let i = 0; i < vecA.length; i++) {
dotProduct += vecA[i] * vecB[i];
normA += vecA[i] * vecA[i];
normB += vecB[i] * vecB[i];
}
if (normA === 0 || normB === 0) return 0;
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
// 初始化 AI 模型
async function initAI() {
try {
// 使用極輕量(約 45MB)的模型
embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
document.getElementById('status').innerText = "✅ 大師已駕到!模型加載成功。請在下方輸入你的流年問題。";
document.getElementById('userInput').disabled = false;
document.getElementById('askBtn').disabled = false;
} catch (error) {
document.getElementById('status').innerText = "❌ 加載失敗。請確保在線上 IDE(如 CodePen)中以 https 協議運行。";
console.error(error);
}
}
// 將文字轉化為特徵向量
async function getEmbedding(text) {
const output = await embedder(text, { pooling: 'mean', normalize: true });
return Object.values(output.data);
}
// 3. 實作 RAG 核心邏輯
window.askMaster = async function() {
const query = document.getElementById('userInput').value.trim();
if (!query) return alert("請輸入問題!");
document.getElementById('aiResponse').innerText = "大師正在掐指一算,翻閱秘笈中...";
document.getElementById('retrievedContext').innerText = "正在進行語意搜索...";
try {
// Step A: 計算用戶問題的 Embedding
const queryEmbedding = await getEmbedding(query);
let highestScore = -1;
let bestMatchText = "";
// Step B: RAG 檢索 - 對比秘笈中哪一條最符合用戶問題
for (const sentence of fengShuiKnowledgeBase) {
const sentenceEmbedding = await getEmbedding(sentence);
// 使用我們自己寫的相似度函數
const score = calculateCosineSimilarity(queryEmbedding, sentenceEmbedding);
if (score > highestScore) {
highestScore = score;
bestMatchText = sentence;
}
}
// Step C: 顯示檢索結果
document.getElementById('retrievedContext').innerHTML = `
<b>[匹配度: ${(highestScore * 100).toFixed(1)}%]</b> <br>
<span class="highlight">${bestMatchText}</span>
`;
// Step D: 模擬生成回應
setTimeout(() => {
let finalReply = "";
if (highestScore < 0.35) {
finalReply = 【大師解讀】: 施主所問之事,風水秘笈中未有詳細記載。但依大師看來,行善積德自然能逢凶化吉。建議細化你的問題(如提及事業、太歲、桃花)。;
} else {
finalReply = 【大師開示】: 看到施主受此提問困擾。根據本門風水秘笈記載:『${bestMatchText}』。大師建議你照此指引佈局,近期切記心平氣和,自可趨吉避凶。;
}
document.getElementById('aiResponse').innerText = finalReply;
}, 500);
} catch (err) {
document.getElementById('aiResponse').innerText = "運算過程中出錯,請確保使用線上環境打開此網頁。";
console.error(err);
}
}
// 啟動
initAI();
</script>
</body>
</html>