vibe coding 初體驗!用不熟悉的框架建自己要用的本機 LLM WebUI 心得

LLM網頁服務應用(3)

toys
LLM
RAG
作者

紙魚

發佈於

2026年5月10日

摘要
嘗試用我完全不懂的 Node.js+ Express 連本機已有的從 Ollama 下載離線 LLM ,建用專門來查詢英文用法的簡易 LLM WebUI。

緣起

我的論文是用英文寫的,最近身陷論文不斷來回修改的輪迴中,但我的英文沒到非常好,所以後來摸索出的工作模式是:先用自己的畫寫一段、交給 LLM 確認有沒有文法錯誤或更好的寫法、驗證後再改寫成我自己的語調;想不到單字可以用哪些就請它丟幾個範例給我;懶得看文獻英文時,叫它翻給我。因為這些動作不太需要很好的模型就能處理,所以網路不穩時,我都直接開 ollama 的 GUI 對話介面處理。

雖然這些動作看似簡單,但是我常常要不斷重複下不同的 prompt,然後等 LLM 吐出一大堆其實我也不需要看的文字。 ollama 還會貼心的儲存我的對話記錄,可是我真的不需要,用完還要手動刪除,好麻煩 ==。以上種種的體驗讓我覺得 寫論文好麻煩,間接耽誤寫作進度

有一天,我又寫論文寫到卡住時,突然想到:ㄟˊ我還沒用過之前申請過的 github copilot education 的免費額度開發專案,不如來做個玩具吧應該很快。於是參考之前參加過的講座跟課程,使用新的 workflow:

graph LR
A[寫 spac 文件] --> B[Agent 執行 spac]
B --> C{測試是否達成目標}
C -->|是| D[git 儲存]
C -->|否| E[git 還原並修改 spac 文件]
D --> F[完成]
E --> B

之前都是直接用網頁服務,用把資料去識別化的方式跟溝通產 code,想說這樣比較能學到東西。這次我先跟網頁上的 AI 討論,決定要哪些技術後,再請它寫個給 Vscode 上的 Agent 看的 spac,交由因為 github copilot education 方案所以可以免費使用一下的 Claude Haiku 4.5 執行開發,我再輕鬆驗收,不行就用 git 回到上一版。因為這次的專案完全交給 Agent 開發,細節技術目前沒有要深入鑽研的意思,所以當 AI 說我的需求很適合用輕量級的 Node.js+ Express 開發時我接受了,想說順便體驗看看不同的技術也好。不過網頁部分我還是請它用基本的 HTML/CSS/JS 就好,怕出問題的時候我看不懂問題出在哪 XD。

以下以 spac 為單位,紀錄一下當時我在想甚麼。

開發過程

順利期

spac 1

請 AI 寫的文件長這樣

You are a senior full-stack engineer. Your task is to build a **minimal working Local LLM WebUI**.

# 🎯 Objective

Create a simple web interface that allows users to:

1. Select a local model (via Ollama)
2. Choose a task type (summary / translation / normal Q&A)
3. Input text and receive a response from the model

---

# 🧩 Technical Constraints (MUST FOLLOW)

* Frontend: HTML + Vanilla JavaScript ONLY (no frameworks)
* Backend: Node.js with Express
* No database
* No authentication
* No styling required (keep UI minimal)

---

# 🏗️ Architecture

Browser (HTML + JS)
→ calls backend API (Node.js)
→ backend calls Ollama API at http://localhost:11434

---

# 📡 Backend API Specification

## 1️⃣ GET /models

Purpose: Retrieve available models from Ollama

Implementation:

* Call: GET http://localhost:11434/api/tags
* Return the raw JSON response

---

## 2️⃣ POST /ask

Purpose: Send a request to the model

Request JSON:
{
"model": "llama3:8b",
"type": "summary | translate | normal",
"input": "user input"
}

---

# 🧠 Prompt Processing Logic (IMPORTANT)

Implement a function:

function buildPrompt(type, input)

Rules:

* summary:
  "Summarize the following in bullet points:\n" + input

* translate:
  "Translate the following into English:\n" + input

* normal:
  return input as-is

---

# 🤖 Call Ollama API

POST http://localhost:11434/api/generate

Body:
{
"model": model,
"prompt": prompt,
"stream": false
}

---

# 🖥️ Frontend Requirements

## Initialization

* On page load, call /models
* Populate the model <select> dropdown

---

## UI Elements (REQUIRED)

1. Model selector (<select>)
2. Task type selector (<select>)

   * normal
   * summary
   * translate
3. Text input (<textarea>)
4. Submit button
5. Output display area (<pre> or <div>)

---

## User Flow

* User enters text
* Clicks submit
* Frontend calls POST /ask
* Display the response

---

# ⚠️ Constraints & Notes

* Frontend MUST NOT call Ollama directly (avoid CORS issues)
* All Ollama requests must go through backend
* Keep the implementation simple and minimal
* No need for error handling (keep MVP scope)

---

# 📦 Expected Output Files

Provide complete code for:

1. index.html
2. app.js (frontend logic)
3. server.js (backend)

---

# ✅ Success Criteria

The app should:

* Display available Ollama models
* Allow model selection
* Accept user input and return model responses
* Work without CORS errors

---

# 🚀 Bonus (Optional, if easy)

* Ctrl + Enter to submit
* Show "Thinking..." before response arrives

---

Output ONLY the complete code files. Do not include explanations.

因為是第一次做,不是很確定 Claude Haiku 4.5 的能力到哪,想說用英文可能比較不會出錯,所以文件就用英文。連同開發選項也有所調整,以便觀察看看成品如何。不過實際執行起來是我多心了,Claude Haiku 4.5 連同 Bonus 的要求都一併完成,技術限制也有好好遵守,相當厲害。

spac 2

發現用中文下 prompt 也沒差後,這次就用中文寫文件了。

你是一位資深全端工程師,請幫修改本資料夾下的本地 LLM WebUI。

# 🎯 專案目標

將目前的本地 LLM WebUI 改成以繁體中文查詢英文相關的 LLM WebUI 

1. 修改功能:原本的 task (summary / translation / normal Q&A),請改成(查單字/檢查文法/翻譯/其他)

2. 加入 CSS 樣式,可調整 light mode & dark mode

---

# 🧩 技術限制(務必遵守)

* 前端只能使用:HTML + Vanilla JavaScript(不可用框架)
* 後端使用:Node.js + Express
* 不需要資料庫
* 不需要登入系統
* 系統架構請盡量不要更動

---

# 🔌 系統架構(保持不變)

Browser (HTML + JS)
→ 呼叫 backend API (Node.js)
→ backend 呼叫 Ollama API (http://localhost:11434)



# 🧠 Prompt 處理邏輯(非常重要)

請將以下函式規則修改為:

function buildPrompt(type, input)

規則如下:

* find-word:
  "查出具有以下意思的英文單字1-5個,並用繁體中文解釋用法:\n" + input

* check-grammar:
  "Check if there is any grammar mistake:\n" + input

* translate:
  "請翻譯成繁體中文:\n" + input

* normal:
  直接使用 input



# ⚠️ 限制與注意事項

* 程式碼需簡單清楚,不要過度設計
* 不需要錯誤處理(保持最小可行)

---

# 📦 最終輸出要求

請修改以下檔案:

1. index.html
2. app.js(前端)
3. server.js(後端)

---

# 🎯 成功標準

完成後應可:

* 正確顯示 Ollama 模型列表
* 可選擇模型
* 可輸入文字並取得回應
* 不出現 CORS 錯誤



---

請直接輸出完整程式碼,不需要解釋。

因為上一個 space 的最低要求只是生出大概的架構,這版的目標是進一步按照我的需求做調整。所以我盡量把會用到的核心功能都寫出來。結果功能部份產出順利,但是網頁排版因為一開始就沒有特別下,結果排版超怪,開始進入撞牆期了 XD

微撞牆期

這裡開始感覺下 prompt 熟練許多,要改動的地方也只有一個檔案而已,所以我直接跳過跟 AI 討論,自己改之前的 spac 來寫。

spac 3

你是一位資深全端工程師,請幫忙修改本資料夾下的本地 LLM WebUI。

# 🎯 專案目標

將目前的以繁體中文查詢英文相關的 LLM WebUI 的前端介面做以下修改:

1. 切換淺色模式移到更右上角,與標題平行

2. "查詢類型"與"輸入文字"區域並排,輸入文字區域在"輸入文字"右邊,輸入框可以比現在小一點。

3. 整體版面配置縮成筆電不須滑動的格式

# 🧩 技術限制(務必遵守)

* 前端只能使用:HTML + Vanilla JavaScript(不可用框架)
* 只更動前端,其他不要作任何更動


---

請直接輸出完整程式碼,不需要解釋。

結果這版的指示太不具體了,根本沒有辦法改出我要的版面 QQ

spac 4

記取了上一個 space 的教訓,這次我嘗試另一種寫法:

你是一位資深全端工程師,請幫忙修改本資料夾下的本地 LLM WebUI。

# 🎯 專案目標

將目前的以繁體中文查詢英文相關的 LLM WebUI 的前端介面做以下修改:

1. "選擇模型"與"查詢類型"區域並排,比例 8:2

2. "輸入文字"與送出按鈕並排,比例 8:2。

3. 送出按鈕顯示字串改為"送出( Ctrl + Enter)"

4. 整體版面配置保持縮成筆電不須滑動的格式


# 🚀 Optional

如果簡單可以再加入:

* 預設背景為自動記憶本機設定,若之前已設定暗色則下次載入時為暗色背景

* 回應渲染markdown語法成對應 html 格式



# 🧩 技術限制(務必遵守)

* 前端只能使用:HTML + Vanilla JavaScript(不可用框架)
* 只更動前端,其他不要作任何更動


---

請直接輸出完整程式碼,不需要解釋。

結果比剛才好一點,不過「“輸入文字”與送出按鈕並排」被理解成按鈕的上邊框跟寫”輸入文字”的文字區域平行,但我其實是希望按鈕是跟”輸入文字”下方的輸入區域並排,恩,如果是真正的工程師大概也會誤解我的意思,My bad。還好追加要求後順利解決!

感覺要收尾但其實沒有期

這裡我當時覺得能收尾了,於是進入寫文件 & 包 docker 的階段。

spac 5

你是一位資深系統分析師,請分析本資料夾下的程式檔案結構,並撰寫系統文件


# 目標

分析系統架構與檔案規格,撰寫 markdown ,內容必須要涵蓋以下:

1. 整體系統架構,包含當使用者操作時的正常流程圖、程式腳本互動。

2. 逐檔案解釋用途、程式架構

3. 本機系統規格、測試方式建議

# 輸出文件

1 個說明文件在本資料夾下:

1. 說明文件.md

結果可能是我下得不夠具體,一開始 Claude 寫的文件很簡單,流程圖還是我後面要求它補上的。

spac 6

這版動了包 docker 丟到 github 上的念頭,但我對包 docker 但模型連本機的 ollama 的設定還不是很熟練,所以還是請 AI 寫了 spac。

You are a senior DevOps engineer.

Your task is to design and implement **only the Docker-related setup** for a Local LLM WebUI project using Ollama.

---

# 🎯 Goal

Provide Docker support for a web application that connects to:

Ollama

The system must support TWO deployment modes:

---

# 🟢 Mode 1: docker run (Quick Start)

A single-container setup where:

* Web UI (HTML + JS)
* Backend (Node.js + Express)

run inside one container.

Ollama is assumed to run externally on the host machine.

---

## Requirements for docker run mode

* Expose port 3000
* Backend must connect to Ollama via configurable environment variable:

OLLAMA_BASE=http://host.docker.internal:11434


* Must include a Dockerfile that builds the full app

---

# 🔵 Mode 2: docker compose (Full Stack)

Provide a docker-compose.yml that runs:

### Services:

1. webui (your app)
2. ollama (official ollama image)

---

## Requirements for docker compose mode

* WebUI service must connect to Ollama via:


http://ollama:11434


* Ollama service must persist models using volume
* Both services must be in same Docker network
* WebUI depends on Ollama (depends_on)

---

# 📦 Required Files to Generate

You MUST output:

## 1️⃣ Dockerfile

* Node.js based
* installs dependencies
* builds WebUI + backend
* exposes port 3001
* starts server

---

## 2️⃣ docker-compose.yml

Must include:

* webui service
* ollama service (official image)
* volume for Ollama models
* correct networking

---

## 3️⃣ .env.example (optional but preferred)

Include:

OLLAMA_BASE=http://localhost:11434


for run mode compatibility

---

# ⚠️ Important Rules

* Do NOT include frontend code or backend logic
* ONLY Docker-related files
* Keep configuration minimal and production-friendly
* Ensure compatibility between both modes
* No unnecessary complexity

---

# 🎯 Success Criteria

The setup is correct if:

✔ docker run works with external Ollama
✔ docker compose starts full system
✔ WebUI can communicate with Ollama in both modes
✔ No hardcoded localhost inside containers

---

# 📘 Output Format

Return ONLY:

1. Dockerfile
2. docker-compose.yml
3. (optional) .env.example

No explanations.

順利產出檔案,但測試時突然發現怪怪的。點開 local host 會先觸發 500: Internal Error,雖然重新整理後就沒事了,但一定有地方出問題。

撞牆期

本來以為只是簡單的小問題,也許多一條 if 判斷就好了,殊不知這是痛苦找問題的開始。

spac 7

你是一位資深全端工程師,請幫忙檢查本資料夾下的本地 LLM WebUI。

# 專案目標

目前本系統檔案在專案資料夾下,請調查以下問題原因

1. 首次開啟 Local Host 網頁時,不會立刻進入網站,而是先顯示 "500: Internal Error",網址顯示"http://localhost:3000/error"。

目前初步觀察

- 重新整理後可以進入網站,但網址仍維持"http://localhost:3000/error"

- Chrome Devtool Console 錯誤顯示

Manifest: Line: 1, column: 1, Syntax error.Understand this error
loader.js:1 Uncaught SyntaxError: Unexpected token '<'Understand this error
BlockingPageContent.js:2  action SET_STORAGE_DATA @ 22:37:54.574
BlockingPageContent.js:2  prev state Object
BlockingPageContent.js:2  action     Object
BlockingPageContent.js:2  next state Object
NotificationContent.js:2  action SET_LOCALE @ 22:37:54.595
NotificationContent.js:2  prev state Object
NotificationContent.js:2  action     Object
NotificationContent.js:2  next state Object
NotificationContent.js:2  action SET_STORAGE_DATA @ 22:37:54.606
NotificationContent.js:2  prev state Object
NotificationContent.js:2  action     Object
NotificationContent.js:2  next state Object
manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.Understand this error
48.BnLRXdVV.js:1 Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.Understand this error


- 發生問題的`manifest.json`裡面內容是類似 `index.html` 的html 原始碼,但沒有完全一樣。



# 輸出文件

請將上述問題原因調查清楚,寫入 "reason.md" 在本資料夾下。


# 🧩 包含段落(務必遵守)

- 問題原因

- 如何排解


# 🚀 Optional

1. 嘗試直接解決此問題

2. 將解決方法與步驟寫入"reason.md" 裡的"執行步驟"

為了讓 Claude 可以順利找到問題,我努力的把能從 google chrome dev tool 中得到的錯誤訊息餵給它。結果它沒有真正解決問題,最後寫進 reason.md的錯誤實際上不是真正的原因,解決方式也只有在 app 端多寫了一段 if 連接不到 ollama 模型的判斷,居然在選單仿造一個假的模型名單,虫合==

因為實在是查不出原因,反覆在修改 space 跟回到上一個狀態輪迴的我做出最壞的選擇:逼它修復,然後觀察它用甚麼方法。結果發現它一下 killer local host 的其他服務,一下在改 port ,然後測試後跟我說 OK 了。感覺不太對勁的我打開 docker desktop 才發現,我的容器有之前裝的 Open WebUI 服務,每次開啟電腦它都會自動跑在 local host 3000,跟我現在 llm 服務設定的 port 位置一樣,所以才需要改 port!至於其他之前有 build 過但是剛好當時沒開的容器全沒了,喔不==,本來我想說這個選擇再怎麼壞僅限在專案資料夾下,大錯特錯==。

這個慘劇告訴我以後最好還是仔細檢查每個生成 shell 指令的效果,大概看過去會出事 == 。還有我發現貼錯誤訊息不見得可以幫助 claude 找出問題,不管有沒有貼它的解法都一樣,這點感覺跟真人工程師不同,不過目前想不出更好的做法協助它 debug ,也只能多多嘗試了QQ

spac 8

付出極大的代價學了一課的我這次決定改 port

你是一位資深全端工程師,請幫忙調整本資料夾下的本地 LLM WebUI。

# 專案目標

1. 將 local host 的 port 從 3000 改成 3001

2. 將 ollama model 與 web 的連接跟著 port 的改變而調整,使它可以順利連接新的 local host 仍可以連接

3. docker 設定也要將 port 設定從 3000 改成 3001

# 🧩 技術限制(務必遵守)

* 前端只能使用:HTML + Vanilla JavaScript(不可用框架)

# 📦 最終輸出要求

請修改本資料夾下,可能有 port 設定與 ollama model 連接相關的檔案

# 🎯 成功標準

完成後應可:

* 正確顯示 Ollama 模型列表
* 可選擇模型
* 可輸入文字並取得回應
* 不出現 CORS 錯誤

---

請直接輸出完整程式碼,不需要解釋。

結果大部分是好的,用 npm start 可以正常載入,但 docker 那邊沒有改好,最後我乾脆刪除舊的檔案,然後修改 spac 6 上的 port 編號,解決。

心得

雖然用 claude 生專案速度比起我之前邊做邊學的方式要快很多,不過我覺得它需要更高的資工知識,才能更好的排解問題。此外,因為我不懂 Node.js 跟 Express 的相關知識,這個專案要是將來繼續加功能我可能無法 handle,算是另一個可惜的地方。

最後的成品,目前滿好用的,生成的內容簡單。如果之後不好用的話再改一下 prompt 就好~

無符合的項目