專案

個人專案個人網站 boyanspace.com

履歷放不下的專案細節,做成可以直接發問的個人網站

履歷放不下的專案細節寫在這裡;想直接問,右下角有問答入口。

原始畫面

個人網站首頁的網頁畫面
1 首頁:一句定位、三項可查證的紀錄與行動按鈕
專案索引頁,每組作品是一排橫向卡片
2 專案索引:每組作品一排可左右滑的卡片
專案頁,最上面是大標與資料欄
3 專案頁:大標寫做的改變,接著是資料欄與各區段
問答小窗引用頁面段落並附來源連結
4 問答小窗:回覆引用頁面原文並附來源連結
成果
靜態頁面不靠腳本就讀得完;問答只引用頁面原文並附來源
角色
個人專案:內容、設計、開發與部署
時間
持續更新
技術
Astro · TypeScript · Markdown · CSS · Node.js · Cloudflare Workers · Jev(TypeSafe)

定位 履歷的詳細補充

履歷只有一頁,這個網站是履歷的補充。首頁放最重要的幾項紀錄,專案頁分成駿斯運動事業群與個人兩組、每個專案一頁,關於頁是履歷各欄位的完整版。

內容以文字為主,寫清楚每個專案的問題、參與範圍與做法,並盡量附上可以查證的來源,例如 PR 或校方紀錄。

技術與使用位置 靜態頁面,中英兩版;腳本只用在問答與畫面輪播

技術用在哪裡
Astro產生全部靜態頁面(中文與英文各一份);以 content collections 讀取內容檔;建置時輸出問答用的知識庫、sitemap 與 llms.txt
TypeScript內容欄位定義、頁面邏輯,以及問答、使用畫面輪播與橫向卡片列的前端腳本;建置前先做型別檢查
Markdown每個專案與關於頁各一份內容檔;區段標題同時是頁面錨點與問答的知識段落
Zod檢查內容檔的欄位,例如分組、角色、時間與技術
CSS全站樣式與頁面動態都手寫,沒有 CSS 框架或動畫套件;色彩、字級與欄寬以變數管理
瀏覽器原生 API問答小窗以 fetch 送出問題、sessionStorage 保留對話;畫面輪播與卡片列用原生的橫向捲動與 scroll-snap;沒有前端框架
Jev(TypeSafe)問答的意圖、主題與證據判斷;金鑰只放在伺服器端
Cloudflare Workers正式站:提供靜態頁面與安全標頭;Worker 處理問答入口(來源檢查、每個來源每小時與全站每日的上限、呼叫 Jev)與匿名造訪統計
Cloudflare D1問答的計數(每個來源每小時、全站每日)與造訪統計;只存計數與雜湊,不存問題內容與 IP
Node.js建置與自動檢查:內容、連結、結構化資料與 Worker 行為都有腳本驗證,通過才部署
JSON-LD每頁附上結構化資料(Person、WebPage;專案頁另有 CreativeWork 與麵包屑)

頁面不開 JavaScript 也讀得完,也不載入任何字型檔。

問答怎麼運作 先檢索,再由 Jev 判斷,程式決定怎麼回

問答是一個小型 RAG,分四步:

  • 前置檢查:程式先擋掉明確索取機密或要求改寫規則的句子,並遮蔽 Email、電話與金鑰。
  • 檢索:在公開段落裡依關鍵字與字詞重疊找出候選。
  • 判斷:把問題與候選交給 Jev(TypeSafe 的判斷模型,只回傳分類與機率,不產生文字),一次問完意圖、主題與每一段是否真的含有答案。
  • 決定回覆:程式依判斷結果選擇引用段落、提供聯絡方式、婉拒,或說明公開資料不足。

回覆內容一律是頁面上的原文並附來源連結,不自由生成。

想看每一步的程式與知識庫的段落,可以開問答關聯圖。

開發與驗證 與 AI 協作,分層檢查

  • 以 Claude Code 協作開發;內容以履歷為準逐項核對。
  • 型別檢查與建置零錯誤後,才進行後續檢查。
  • 靜態輸出檢查:導覽、連結與錨點、文案規則,以及知識段落是否逐字來自頁面。
  • 問答決策的離線測試:以固定題集檢查檢索與各種回覆路徑。
  • 真 Jev 固定題集與真瀏覽器(Playwright)操作驗收。

技術細節 知識庫與檢索

知識庫不另外維護:建置時把專案頁與關於頁的每個區段轉成一個知識段落,所以頁面寫什麼,問答就只能引用什麼。

檢索不用向量資料庫。問題拆成英文字詞與中文雙字詞,和段落內容比對重疊;再加上區段關鍵字、專案別名,以及上一題的主題與目前所在頁面。分數最高的 10 段送去判斷。

技術細節 Jev 判斷什麼

Jev 是 TypeSafe 的判斷模型:只回傳型別化的答案與機率,不產生文字。一次請求問四種問題:

  • 意圖(Choice):了解經歷與作品、想聯絡、打招呼、索取私人或機密資料、無關主題。
  • 主題(Choice):問題主要在談哪個專案,或是關於頁。
  • 證據(Noul,每個候選一題):這一段是否直接回答了問題。
  • 夾帶(Noul):是否另外夾帶無關或索取私人資料的請求。

證據機率達 0.8 才引用該段,而且只引用與主題判斷相同的專案。都沒有達標但主題明確時,針對該主題其餘段落再判斷一次;仍然沒有,就說明公開資料不足。

技術細節 回覆的種類

  • 與經歷或作品有關,且有段落含答案:引用該段並附來源連結。
  • 想聯絡:顯示聯絡方式,也可以直接留言。
  • 與經歷或作品無關:不回答,請對方改問經歷、專案或技術。
  • 索取私人或公司內部資料、詢問薪資等條件:婉拒,並請對方直接聯絡。
  • 有關但公開資料不足:說明沒有依據,不猜測。

技術細節 聯絡方式與提問上限

Jev 判斷為聯絡意圖時,問答會顯示 Email、電話與履歷下載;Email 點一下就會複製。

留言欄位尚未開放:收件方式接好之前,問答只提供上述聯絡方式,不收集任何留言。提問本身也不會保存。為了避免濫用,每個 IP 一小時內最多提問 20 則(從第一則起算)。

技術細節 伺服器、額度與邊界

問答的入口是 Cloudflare Worker:只接受本站頁面送出的請求,限制問題長度與格式。每個來源(IPv4 位址或 IPv6 /64)一小時內最多 20 則,從第一則起算;全站另有每日則數與 Jev 呼叫次數的上限,以 Cloudflare D1 計數。Jev 的呼叫次數到達當日上限、或 Jev 無法使用時,退回關鍵字檢索並標示。

送出的問題會交給 TypeSafe 判讀;本站不保存問題內容,計數只記來源的當日雜湊,不存 IP。金鑰只在 Worker 裡讀取,不會出現在頁面、回覆或紀錄裡。問答只涵蓋公開的經歷、作品與本站技術,沒有執行指令或查詢內部系統的能力。

技術細節 版面與動態

版面刻意單純:深色底、無襯線字、一欄正文。頁首是名字加三個分頁與語言切換,目前頁面用底線標示;頁面上方有一片藍色漸層光暈,往下淡出。專案索引把每組作品排成可以左右滑的卡片列;有使用畫面的專案頁,第三行起是自動輪播的畫面,也可以左右滑。

頁面本身的動態以 CSS 完成,不用 canvas 或 WebGL:背景光暈緩慢漂移;換頁時內容淡出淡入、分頁底線滑到新的分頁(view transition);內頁捲動時段落淡入(scroll-driven animation)。使用畫面的自動輪播與問答小窗的過場由少量腳本處理。系統設定為減少動態時全部靜止。