# skill.md - AI Nurse Chatbot 工具驅動開發技能 > **目的**:讓 LLM 以標準化工具介面開發與調試本專案(app.js, index.html, server_qwen.py),可在 Ubuntu 終端啟動服務、自動化瀏覽器測試、讀取 F12 Console/Network 錯誤、模擬 UI 互動、自動修復 Bug 並記錄開發進度。 --- ## 📁 檔案結構 ``` ai_nurse_chatbot/ ├── skill.md # 本文件(開發技能定義) ├── DEVELOPMENT_PROGRESS.md # 開發進度追蹤(LLM 必讀) ├── index.html # 前端主頁 ├── static/ │ ├── app.js # 前端邏輯 │ ├── styles.css # 樣式表 │ └── ... ├── server_qwen.py # 後端服務器 ├── requirements.txt # Python 依賴 ├── .env # 環境變數(API Keys) ├── tests/ │ ├── test_browser.py # 瀏覽器自動化測試 │ ├── bug_tracker.py # Bug 掃描工具 │ └── auto_debug.sh # 一鍵調試腳本 ├── artifacts/ │ ├── screenshots/ # 測試截圖 │ ├── console.log # Console 日誌 │ └── network.json # Network 日誌 └── reports/ ├── BUGLIST.md # Bug 清單 └── test_results.log # 測試結果 ``` --- ## 🛠️ 1. 工具介面定義(Tools API) LLM 可調用以下標準化工具介面: ### 1.1 Shell 執行器 ```json { "tool": "shell.run", "params": { "cmd": "string (完整 shell 指令)", "cwd": "string (工作目錄,默認為 repo 根目錄)", "env": {"KEY": "VALUE"}, "timeout_sec": 600 }, "returns": { "stdout": "string", "stderr": "string", "exit_code": "int" } } ``` **安全閘門(CRITICAL)**: - ❌ 禁止:`rm -rf /`, `mkfs`, `:(){ :|:& };:` (fork bomb) - ❌ 禁止:無目錄限制的 `sudo` - ✅ 只能在 `repo 根目錄` 內操作 - ✅ 刪除操作需明確目標路徑 ### 1.2 檔案系統 ```json { "tool": "fs.read", "params": {"path": "相對路徑"}, "returns": {"content": "string", "size": "int"} } { "tool": "fs.write", "params": {"path": "相對路徑", "content": "string"}, "returns": {"success": "bool", "bytes_written": "int"} } { "tool": "fs.list", "params": {"path": "目錄路徑", "include_hidden": false}, "returns": {"files": ["array of filenames"]} } { "tool": "fs.exists", "params": {"path": "相對路徑"}, "returns": {"exists": "bool"} } ``` ### 1.3 瀏覽器自動化(基於 Playwright) ```json { "tool": "browser.open", "params": { "url": "http://localhost:8000", "headless": false, "viewport": {"width": 1280, "height": 720} }, "returns": {"page_id": "uuid"} } { "tool": "browser.console_logs", "params": {"page_id": "uuid", "since_timestamp": "optional"}, "returns": { "logs": [ {"level": "error|warn|info", "text": "string", "timestamp": "iso8601"} ] } } { "tool": "browser.network_logs", "params": {"page_id": "uuid", "filter": "failed|4xx|5xx"}, "returns": { "requests": [ {"url": "string", "status": "int", "method": "string", "error": "string"} ] } } { "tool": "browser.click", "params": {"page_id": "uuid", "selector": "#elementId"}, "returns": {"success": "bool"} } { "tool": "browser.fill", "params": {"page_id": "uuid", "selector": "#input", "text": "content"}, "returns": {"success": "bool"} } { "tool": "browser.screenshot", "params": {"page_id": "uuid", "path": "artifacts/screenshots/error.png"}, "returns": {"path": "string"} } { "tool": "browser.evaluate", "params": {"page_id": "uuid", "script": "console.log(window.location)"}, "returns": {"result": "any"} } ``` ### 1.4 進度追蹤 ```json { "tool": "progress.update", "params": { "task": "string (任務描述)", "status": "pending|in_progress|completed|failed", "details": "string (詳細說明)", "evidence": ["artifacts/screenshots/test.png"] } } { "tool": "progress.read", "returns": { "current_phase": "string", "completed_tasks": ["array"], "pending_tasks": ["array"], "blockers": ["array"] } } ``` --- ## 🔄 2. 標準工作流程(Workflows) ### 2.1 初始化開發環境 ```python # 1. 檢查專案結構 files = tool.fs.list("./") # 2. 檢查必要檔案 required_files = ["index.html", "server_qwen.py", "requirements.txt"] for file in required_files: if not tool.fs.exists(file): tool.progress.update(f"缺少檔案: {file}", "failed") # 建立檔案骨架(見 5.1 節) # 3. 安裝 Python 依賴 result = tool.shell.run("pip install -r requirements.txt", timeout_sec=300) if result.exit_code != 0: tool.progress.update("依賴安裝失敗", "failed", result.stderr) # 4. 檢查環境變數 env_check = tool.fs.exists(".env") if not env_check: tool.progress.update("缺少 .env 文件", "failed") ``` ### 2.2 啟動服務與測試 ```python # 1. 啟動後端 result = tool.shell.run( "python server_qwen.py > artifacts/server.log 2>&1 &", cwd="." ) tool.progress.update("後端啟動", "in_progress", f"PID: {result.stdout}") # 等待服務就緒 time.sleep(3) # 2. 健康檢查 health = tool.shell.run("curl -s http://localhost:8000/health") if "healthy" in health.stdout: tool.progress.update("後端啟動", "completed") else: tool.progress.update("後端啟動", "failed", health.stderr) # 讀取日誌排查錯誤 logs = tool.fs.read("artifacts/server.log") # 3. 啟動瀏覽器 page_id = tool.browser.open("http://localhost:8000", headless=False) # 4. 收集 Console 錯誤 time.sleep(2) # 等待頁面載入 console_logs = tool.browser.console_logs(page_id) errors = [log for log in console_logs if log['level'] == 'error'] if errors: tool.progress.update( "發現 Console 錯誤", "failed", f"共 {len(errors)} 個錯誤" ) # 截圖證據 tool.browser.screenshot(page_id, "artifacts/screenshots/console_error.png") ``` ### 2.3 自動化 UI 測試 ```python # 模擬用戶操作 test_cases = [ { "name": "發送消息測試", "actions": [ {"type": "fill", "selector": "#userInput", "text": "你好"}, {"type": "click", "selector": "#sendBtn"}, {"type": "wait", "duration": 2} ], "verify": { "selector": "#messagesArea", "contains": "你好" } } ] for test in test_cases: tool.progress.update(f"執行測試: {test['name']}", "in_progress") for action in test['actions']: if action['type'] == 'fill': tool.browser.fill(page_id, action['selector'], action['text']) elif action['type'] == 'click': tool.browser.click(page_id, action['selector']) elif action['type'] == 'wait': time.sleep(action['duration']) # 驗證結果 result = tool.browser.evaluate( page_id, f"document.querySelector('{test['verify']['selector']}').textContent" ) if test['verify']['contains'] in result: tool.progress.update(f"測試: {test['name']}", "completed") else: tool.progress.update(f"測試: {test['name']}", "failed") tool.browser.screenshot(page_id, f"artifacts/screenshots/{test['name']}_failed.png") ``` --- ## 🎯 3. 決策樹(Debugging Decision Tree) ### 當遇到問題時,LLM 應按此流程處理: ``` ┌─────────────────────────────────────────┐ │ 1. 後端無法啟動 │ │ → tool.fs.read("artifacts/server.log")│ │ → 解析 traceback │ │ → 定位錯誤行數 │ │ → tool.fs.read(錯誤文件) │ │ → 修正代碼 │ │ → tool.fs.write(文件, 修正後代碼) │ │ → 重新啟動 │ └─────────────────────────────────────────┘ ┌─────────────────────────────────────────┐ │ 2. 前端白屏 / JS 錯誤 │ │ → tool.browser.console_logs() │ │ → 識別錯誤類型: │ │ - Uncaught ReferenceError │ │ → 檢查變數是否定義 │ │ - TypeError: Cannot read property │ │ → 檢查物件是否存在 │ │ - CORS error │ │ → 檢查 server_qwen.py CORS 配置 │ │ → tool.fs.read("static/app.js") │ │ → 修正錯誤 │ │ → 重新載入頁面驗證 │ └─────────────────────────────────────────┘ ┌─────────────────────────────────────────┐ │ 3. API 請求失敗 │ │ → tool.browser.network_logs(filter="failed")│ │ → 檢查: │ │ - 404: 端點不存在 │ │ → 檢查 server_qwen.py 路由 │ │ - 500: 服務器錯誤 │ │ → 讀取 server.log │ │ - CORS: 跨域問題 │ │ → 檢查 CORSMiddleware 配置 │ │ - Timeout: 超時 │ │ → 檢查後端處理邏輯 │ │ → 修正對應問題 │ └─────────────────────────────────────────┘ ┌─────────────────────────────────────────┐ │ 4. 資源載入 404 │ │ → tool.browser.network_logs(filter="404")│ │ → 檢查路徑: │ │ - /static/app.js → 確認文件存在 │ │ - /static/styles.css → 檢查路徑 │ │ → tool.fs.read("index.html") │ │ → 修正