# TobiichiGPT - 人工回覆系統 將 AI 對話系統改造成由真人管理員回覆的極簡方案。 ## 🎯 特色 - ✅ **零修改** - 不需要修改 Open WebUI 程式碼 - ✅ **極簡化** - 4 個容器完成所有功能 - ✅ **共享資料庫** - Open WebUI 和管理後台使用同一個 PostgreSQL - ✅ **視覺化後台** - NocoDB 提供專業的資料庫管理介面 - ✅ **可編輯代碼** - API 程式碼透過 bind mount 可直接修改 ## 🏗️ 架構 ### 主要服務(必須) ``` ┌─────────────────┐ │ PostgreSQL │ ← 共享資料庫 └────────┬────────┘ │ ┌────┴─────┬─────────────┬─────────────┐ │ │ │ │ ┌───▼────┐ ┌──▼─────┐ ┌────▼─────┐ ┌───▼────┐ │ API │ │ Open │ │ NocoDB │ │ 用戶 │ │ 中間層 │ │ WebUI │ │ 管理介面 │ │ 瀏覽器 │ └────────┘ └────────┘ └──────────┘ └────────┘ ``` ### 代理服務(選用) ``` ┌───────────┐ │ 用戶 │ └─────┬─────┘ │ 公網 ┌─────▼──────────────┐ │ Cloudflare Tunnel │ └─────┬──────────────┘ │ 內網 ┌─────▼──────────────┐ │ Nginx Proxy Mgr │ └─────┬──────────────┘ │ ┌─────▼──────────────┐ │ 主要服務 (上方) │ └────────────────────┘ ``` ## 🚀 快速開始 ### 1. 準備環境檔案 ```powershell # 複製主服務環境變數 Copy-Item .env.example .env notepad .env # 設定 DB_PASSWORD 和 CHATWOOT_SECRET_KEY # 生成 Chatwoot Secret Key (在 Linux/macOS) openssl rand -hex 64 # 或在 PowerShell 生成 -join ((1..128) | ForEach-Object { '{0:x}' -f (Get-Random -Maximum 16) }) ``` ### 2. 啟動主要服務 ```powershell # 啟動 PostgreSQL + API + Open WebUI + NocoDB docker-compose up -d # 查看狀態 docker-compose ps # 查看日誌 docker-compose logs -f ``` ### 3. 啟動代理服務(選用) ```powershell # 啟動 Cloudflare Tunnel + NPM docker-compose -f docker-compose.proxy.yml --env-file .env.proxy up -d # 查看狀態 docker-compose -f docker-compose.proxy.yml ps ``` ## 🌐 服務訪問 ### 主要服務 | 服務 | 網址 | 說明 | |------|------|------| | **Open WebUI** | http://localhost:10060 | 用戶對話介面 | | **API 伺服器** | http://localhost:18000 | OpenAI API 相容端點 | | **Chatwoot** | http://localhost:13500 | 管理員對話介面 | | **PostgreSQL** | localhost:5432 | 資料庫 | ### 代理服務(如已啟動) | 服務 | 網址 | 說明 | |------|------|------| | **NPM 管理面板** | http://localhost:81 | Nginx Proxy Manager | | **HTTP 代理** | Port 80 | HTTP 流量 | | **HTTPS 代理** | Port 443 | HTTPS 流量 | **NPM 預設帳號**: - Email: `admin@example.com` - Password: `changeme` ## 📋 使用流程 ### 首次設定 Chatwoot 1. 訪問 http://localhost:13500 2. 建立管理員帳號 3. 建立新的 Inbox(收件匣): - 名稱: TobiichiGPT - 類型: API 4. 取得 Inbox ID(稍後需要) ### 設定 Open WebUI 1. 開啟 http://localhost:10060 2. 進入 **Settings** → **Connections** 3. 新增 OpenAI Connection: - **API Base URL**: `http://tobiichiGPT-api:8000/v1` - **API Key**: `sk-human` (任意值) 4. 模型列表會出現 **human-admin** ### 管理員回覆流程 1. 登入 Chatwoot: http://localhost:13500 2. 在對話列表查看新訊息 3. 直接回覆即可,用戶會在 3 秒內收到 ## 🔧 技術架構 ### 主要服務 - **PostgreSQL 15**: 共享關聯式資料庫 - **FastAPI**: Python Web 框架,提供 OpenAI API 相容端點 - **Open WebUI**: 對話前端介面 - **NocoDB**: 視覺化資料庫管理工具 ### 代理服務 - **Nginx Proxy Manager**: 反向代理 + SSL 憑證管理 - **Cloudflare Tunnel**: 安全的公網訪問通道 ### API 端點 - `/v1/models` - 模型列表(回傳 human-admin) - `/v1/chat/completions` - 聊天完成端點(OpenAI 相容) ## 🌍 Cloudflare Tunnel 設定 ### 1. 建立 Tunnel 1. 登入 [Cloudflare Zero Trust](https://one.dash.cloudflare.com/) 2. 前往 **Networks** → **Tunnels** 3. 點擊 **Create a tunnel** 4. 選擇 **Cloudflared** 5. 輸入 Tunnel 名稱(例如: `tobiichi-tunnel`) 6. 複製顯示的 Token 7. 將 Token 貼到 `.env.proxy` 的 `CLOUDFLARE_TUNNEL_TOKEN` ### 2. 設定 Public Hostname #### 選項 A: 透過 NPM 代理(推薦) 在 Cloudflare Tunnel 設定: - **Public hostname**: `chat.yourdomain.com` - **Service Type**: HTTP - **URL**: `http://npm:80` 然後在 NPM (http://localhost:81) 設定: - **Domain**: `chat.yourdomain.com` - **Forward to**: `openwebui:3000` #### 選項 B: 直接指向服務 在 Cloudflare Tunnel 設定: - **Public hostname**: `chat.yourdomain.com` - **Service Type**: HTTP - **URL**: `http://openwebui:3000` ### 3. 啟動 Tunnel ```powershell docker-compose -f docker-compose.proxy.yml --env-file .env.proxy up -d ``` 訪問你設定的網域即可從公網訪問服務。 ## 📦 資料持久化 所有服務資料都會持久化保存: ```yaml volumes: postgres-data: # PostgreSQL 資料 openwebui-data: # Open WebUI 配置和對話記錄 nocodb-data: # NocoDB 配置 npm-data: # NPM 配置(代理服務) npm-letsencrypt: # SSL 憑證(代理服務) ``` ## 🛠️ 修改 API 程式碼 API 程式碼位於 `./api/` 目錄,透過 bind mount 掛載到容器: ```powershell # 編輯 API 程式碼 notepad api\server.py # 重啟 API 服務套用修改 docker-compose restart api # 查看 API 日誌 docker-compose logs -f api ``` ## 🐳 檔案結構 ``` tobiichiGPT/ ├── api/ # API 服務程式碼 │ ├── server.py # FastAPI 主程式 │ └── requirements.txt # Python 依賴 ├── docker-compose.yml # 主要服務編排 ├── docker-compose.proxy.yml # 代理服務編排 ├── .env.example # 主服務環境變數範例 ├── .env.proxy # 代理服務環境變數範例 └── README.md # 本文件 ``` ## 🔍 故障排除 ### API 無法連接資料庫 ```powershell # 檢查資料庫是否啟動 docker-compose ps postgres # 查看資料庫日誌 docker-compose logs postgres # 檢查網路連接 docker network inspect tobiichi-network ``` ### Open WebUI 無法連接 API 1. 確認 API URL 使用容器名稱: `http://api:8000/v1` 2. 檢查兩個容器是否在同一網路: ```powershell docker network inspect tobiichi-network ``` ### NocoDB 無法連接資料庫 1. 檢查 PostgreSQL 是否健康: ```powershell docker-compose ps ``` 2. 確認資料庫密碼正確(`.env` 檔案) ### 代理服務無法啟動 ```powershell # 檢查主網路是否已建立 docker network ls | Select-String "tobiichi-network" # 先啟動主服務 docker-compose up -d # 再啟動代理服務 docker-compose -f docker-compose.proxy.yml up -d ``` ## 📝 開發筆記 ### 資料庫 Schema `reply_queue` 表格結構: ```sql CREATE TABLE reply_queue ( id SERIAL PRIMARY KEY, user_message TEXT NOT NULL, admin_reply TEXT, status VARCHAR(20) DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, replied_at TIMESTAMP ); CREATE INDEX idx_status ON reply_queue(status); CREATE INDEX idx_created_at ON reply_queue(created_at); ``` ### 環境變數 **主服務** (`.env`): - `DB_PASSWORD`: PostgreSQL 密碼 **代理服務** (`.env.proxy`): - `CLOUDFLARE_TUNNEL_TOKEN`: Cloudflare Tunnel 認證 Token ### Port 映射 **主服務**: - 3000: Open WebUI - 5432: PostgreSQL - 8000: API - 8080: NocoDB **代理服務**: - 80: HTTP - 443: HTTPS - 81: NPM 管理介面 ## 📄 授權 MIT License build: . container_name: tobiichi-gpt ports: - "8000:8000" networks: - tobiichi-network open-webui: image: ghcr.io/open-webui/open-webui:main container_name: open-webui ports: - "3000:8080" volumes: - open-webui:/app/backend/data networks: - tobiichi-network networks: tobiichi-network: driver: bridge volumes: open-webui: ``` 然後在 Open WebUI 中使用: - **API Base URL**: `http://human-reply-server:8000/v1` ## 📝 進階設定 ### 修改等待超時時間 編輯 `docker/human_reply_server.py` 第 79 行: ```python timeout = 600 # 預設 10 分鐘,可改為其他秒數 ``` ### 修改伺服器埠號 **方法 1: 修改 docker-compose.yml** ```yaml # 編輯 docker-stack/docker-compose.yml ports: - "9000:8000" # 本機 9000 對應容器 8000 ``` **方法 2: 修改程式碼** ```python # 編輯 docker/human_reply_server.py uvicorn.run(app, host="0.0.0.0", port=8000) # 改為其他埠號 ``` ### 設定 Cloudflare Tunnel 詳細設定步驟請參考專案根目錄的說明文件,或參考 `docker-stack/.env.example`: ```powershell cd docker-stack Copy-Item .env.example .env notepad .env # 填入您的 CLOUDFLARE_TUNNEL_TOKEN ``` ### 支援多管理員 目前版本採「先搶先贏」機制,任何管理員都可以回覆任何訊息。若需要分配機制,可以加入: - 管理員登入系統 - 訊息認領機制 - 管理員負載平衡 ## ⚠️ 注意事項 - 此為**最簡化版本**,適合小規模使用 - 訊息儲存在記憶體中,重啟會遺失 - 沒有身份驗證,建議僅在內網使用 - 若需生產環境,建議加入: - 資料庫持久化 - 身份驗證 - WebSocket 即時推送 - 訊息隊列系統 ## 🎨 管理員後台截圖 後台提供: - 待處理訊息列表 - 用戶訊息顯示 - 回覆文字框 - 一鍵送出功能 - 自動刷新