YamAgent 是我自己設計的 AI 助理系統,靈感來自想要打造一個 陪伴式、記憶型、語境穩定的個人 AI 系統,可以真正支援我在開發、寫作、生活規劃上的節奏與需要。


🧩 系統定位與需求背景

在使用 ChatGPT 官方介面與 API 的過程中,我發現以下幾個限制:

  • ✅ 回合記憶易失,對話上下文容易斷裂
  • ✅ 多執行緒(thread)管理困難
  • ✅ 缺乏成本管理與 token 追蹤
  • ✅ 想要不同人格(語氣/角色)切換時不夠彈性

於是我開始構思一個 本地部署、結構清晰、可控又可擴充 的個人助理系統。


⚙️ 架構設計與技術選型

我採用了以下技術堆疊:

  • 後端:Python + FastAPI
  • 資料庫:PostgreSQL(Tailscale 內網連線)
  • 前端:Vite + React + shadcn/ui
  • 部署方式:ThinkPad(WSL Ubuntu)+ Nginx reverse proxy
  • API 模型串接:OpenAI GPT-4o

資料庫設計核心包含:

  • session:記錄每條對話執行緒
  • chat:每則訊息紀錄(user / assistant)
  • memory:人格記憶欄位(可切換載入)
  • token_usage:每日 token 花費統計(GPT-4o 價格公式)
  • yamlog:每日學習或事件日誌紀錄

🧱 實作中遇到的挑戰與解法

❓ Q1:API 回傳訊息過長導致 CORS 錯誤?

背景:我最早嘗試以 render 部署 FastAPI,但遇到 preflight 錯誤或 500 錯誤。

解法:直接將後端部署在家中 ThinkPad,並透過 Nginx 設定 CORS headers 與路由反向代理 /api,問題解決。


❓ Q2:資料庫無法初始建立?

背景Base.metadata.create_all(bind=engine) 執行無反應,後來發現是 alembic migration 沒有生效。

解法:確認 env.py 是否正確匯入所有模型、並確保 alembic migration 是針對正確的 DB 執行。從此我都改為手動執行 create_all 初始化。


❓ Q3:訊息過長無法正常顯示?

背景:在前端顯示 message 訊息時,長內容格式錯亂或難以閱讀。

解法:加入 highlight.js 支援 markdown 格式與語法高亮,並加上複製按鈕與「正在輸入」動畫,提高使用體驗。


🔁 功能演進歷程

  • 初始版本只有 /chat API,可傳入 prompt + 記憶塊
  • 加入 /memory 功能後,可自定角色人格與語境開場白
  • 實作 /token-usage 每日統計後,能更安心掌控花費
  • 將 chat、memory 整合進 /[session_id] UI 頁面,並支援 sidebar 切換 thread
  • 現在支援多 session、多記憶快取、多模型管理

✍️ 設計理念

我認為個人 AI 助理應該具備以下幾點:

  1. 可控:我想知道資料存在哪、花多少 token、角色說話口氣為何
  2. 可續寫:同一個對話 thread 應能不斷延伸,而非斷裂
  3. 可陪伴:角色應該能理解我的節奏與目標,甚至提醒我不要分心
  4. 可延伸:未來我會加入日誌整合、語音輸入、日曆任務連動等模組

🚫 ChatGPT 官方服務的限制與我為什麼選擇自建

在開始開發 YamAgent 之前,我有一段時間依賴 OpenAI 提供的 ChatGPT 官方服務,但很快就遇到以下幾個致命的限制:

🧱 1. ChatGPT 無法知道現在幾點幾分

  • ChatGPT 本身並不連接實際時間,只有在你問它「現在幾點」時,它才會試著用語境推測,但實際上完全不具備即時時間感知。
  • 對於我這種需要「記錄每小時狀態」、「做生活節奏管理」的使用者來說,這是一個無法解決的盲點。

🔒 2. ChatGPT sandbox 中不能主動 call API

  • 無法自動幫我 call webhook / query database
  • 無法觸發任務提醒或與我本地程式整合

🌐 3. 官方 Web UI 無法管理上下文與人格切換

  • 雖然官方後來推出「Custom GPTs」,但記憶與角色切換的行為依然不穩
  • 缺乏 thread 的資料庫化管理,也難以做多任務切換

🧑‍💻 為什麼我選擇自建 YamAgent?

因為我不想再受限於 OpenAI 的沙盒規則、context window、甚至商業政策的不確定性。我想要一個:

  • 可以自己定義人格、記憶、行為模式
  • 可以連接我自己的 DB、API、時間來源
  • 可以在我不使用雲端時仍然本地運作的 AI 系統

這也是為什麼 YamAgent 的設計原則,是以「全地端 + 高自由度」為核心,自己掌握 context loading、token 控管、人格模組與資料儲存方式。


🔧 技術補充:我如何解決 ChatGPT 系統性限制?

  • 透過 Python datetime.now() 讓 agent 知道「現在幾點」
  • 自建 /yamlog/token-usage API 模組,記錄每日學習與花費
  • 把所有記憶存在 PostgreSQL,不再依賴 ephemeral context
  • 自訂角色人格 schema,未來可開發多人格模組(已預設 mentor 角色)

這是為了「能長期依賴與穩定使用」這個系統。


🖥 YamAgent 的本地部署流程與架構實作

🏠 為什麼部署在本地 ThinkPad?

我不希望自己的對話、記憶、個人日誌都放在雲端商業平台。
我想要掌握所有資料與操作權,因此選擇把整個 YamAgent 系統部署在我自己家裡的 ThinkPad X1 Gen11 上。

這台機器配備:

  • 32GB RAM / 1TB SSD
  • WSL Ubuntu 系統
  • 長期開機並穩定運行我的個人助理系統與日誌記錄

🧠 系統組成(全地端)

我將整個系統切為三個模組:

  • yamagent(後端 FastAPI):
    • 提供 /chat、/session、/memory、/yamlog、/token-usage 等 API
    • 使用 PostgreSQL 作為資料儲存,部署於本地
  • yamagent-web(前端 Vite + React):
    • 包含 chat UI、token 統計頁、session sidebar 等功能
    • 打包後部署至 /var/www/yamagent-web
  • Nginx
    • 轉址 /api 到本地 FastAPI
    • 靜態服務前端 SPA

🌐 Tailscale 內網架構

我希望能在公司 MacBook 上開發,家裡 ThinkPad 上部署。

因此我使用 Tailscale 架設私人內網 VPN,讓兩台電腦能穩定互通。

  • MacBook M4 為主開發機
  • ThinkPad 為穩定部署主機
  • 使用 Tailscale 分配的內網 IP(例如 100.x.x.x)互通

我也曾遇過:

  • Tailscale 掛掉後無法遠端打開 YamAgent
  • 服務自動中斷需手動重啟(目前計畫導入 systemd 或 PM2 處理)

🏁 部署過程重點紀錄

  1. WSL 安裝 PostgreSQL,設好 local superuser yamuser
  2. poetry + uvicorn 運行 FastAPI,並在開機後啟動
  3. 前端打包後以 Nginx 提供 / 靜態頁面,API 用 /api/ 反向代理
  4. 使用 highlight.js 提升 Markdown 渲染品質
  5. 使用 .env 控制 API Key、DB 連線設定等

✅ 為什麼這樣部署?

這樣的部署方式滿足我以下需求:

  • 私有:所有資料掌控在我自己手上
  • 低成本:不需花雲端主機錢
  • 可擴充:未來要加 voice-to-text / 任務整合都能接在這架構上
  • 跨地點開發:公司與家中機器透過 Tailscale 無縫連線

💭 結語

YamAgent 是我親手為自己打造的「思考副駕駛」,幫助我建立節奏、記憶內容、回顧進度。