iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
AI Engineering

從 Prompt 到自主決策:用 Python × Agentic Workflow 實作生活助理系列 第 27 篇

生活助理專案(一):需求拆解與系統設計

  • 分享至 

  • xImage
  •  

前面 26 天,我們把零件一個一個做出來了。接下來三天要把它們組裝成一個真的可以每天用的東西。

今天不寫太多程式碼,先做一件更重要的事:想清楚要做什麼。


一、先定義「完成」

這是我做專案時最重要的習慣:在動手之前,先寫下「什麼叫做完成」。

不然很容易陷入「好像還可以再加一個功能」的無限迴圈,最後什麼都做不完。

這個專案的定義

一個命令列的生活助理,我每天早上打開它,它能告訴我今天該注意什麼;
我可以用自然語言跟它記事情、問天氣;它記得我的習慣。

就這樣。不做網頁介面、不做語音、不接 Google Calendar。

驗收標準

用具體的場景來驗收,而不是模糊的「能用」:

# 情境 期望行為
1 輸入 早安 30 秒內產生今日簡報:天氣重點 + 優先待辦 + 一個提醒
2 「明天要不要帶傘?」 自動查日期與天氣,用具體數字回答
3 「提醒我禮拜五交報告」 正確解析成日期,存進待辦
4 「我有什麼事要做?」 列出未完成事項,依優先度排序
5 「我不吃牛肉」 記進長期記憶,下次重啟還記得
6 天氣 API 掛掉 不崩潰,回覆其他資訊並說明天氣拿不到
7 「把第 3 筆刪掉」 先詢問確認,拒絕後不執行且不重試
8 問一個做不到的事 誠實說做不到,不編造
9 連續對話 10 輪 記得前面說過的內容,成本不失控
10 quit 後重新啟動 記得長期偏好,對話歷史重新開始

**這十條就是 Day 29 要測的東西。**先寫下來,才知道做到哪裡算完。


二、使用情境(先想清楚再寫)

我把自己實際會用的狀況寫下來:

情境 A:早上七點半,起床後

$ python main.py
> 早安

小幫:早安!今天 10/12 星期日,台北多雲偶陣雨,
     下午三點後降雨機率 70%,出門記得帶傘。
     氣溫 24-29 度,早晚微涼。

     今天最該處理的是「交鐵人賽 Day 27」,今天就到期。
     另外「繳停車費」還有兩天,可以一起處理掉。

     下午有雨,如果要出門辦事建議排在中午前。

需求:一個指令就能拿到整合過的資訊。

情境 B:通勤路上想到一件事

> 提醒我這禮拜要去修機車

小幫:好,記下來了(中優先,期限 10/18)。

需求:自然語言輸入,自動解析時間。

情境 C:查東西

> 明天下午要去信義區,會下雨嗎?

小幫:明天台北下午降雨機率 40%,不算太高但還是有可能,
     建議帶把折傘。氣溫 26-30 度,短袖就夠。

需求:AI 自己決定要查什麼。

情境 D:告訴它一件事

> 我禮拜三晚上固定有課,那天不要排事情

小幫:了解,我記下來了。之後安排行程時會避開禮拜三晚上。

需求:長期記憶。


三、系統架構

把前 26 天的東西畫成一張圖:

                       ┌──────────────┐
                       │   main.py    │  CLI 介面
                       └──────┬───────┘
                              │
                       ┌──────▼───────┐
                       │  Assistant   │  整合層
                       │  ・組裝 prompt │
                       │  ・路由        │
                       └──────┬───────┘
              ┌───────────────┼───────────────┐
              │               │               │
       ┌──────▼─────┐  ┌──────▼─────┐  ┌──────▼─────┐
       │   Memory   │  │  Workflow  │  │   Agent    │
       │  ・對話歷史  │  │ ・今日簡報  │  │  ・工具迴圈 │
       │  ・使用者檔案│  │ ・新增待辦  │  │  ・預算     │
       └────────────┘  └──────┬─────┘  └──────┬─────┘
                              │               │
                       ┌──────▼───────────────▼─────┐
                       │        ToolBox              │
                       │ 時間/天氣/待辦/記憶/計算      │
                       └──────┬──────────────────────┘
                              │
              ┌───────────────┼───────────────┐
       ┌──────▼─────┐  ┌──────▼─────┐  ┌──────▼─────┐
       │ 氣象署 API │  │  本地 JSON  │  │ Claude API │
       └────────────┘  └────────────┘  └────────────┘

        橫切關注點:config / logging / tracer

為什麼 Workflow 和 Agent 並存

這是整個設計最關鍵的決定,呼應 Day 23 和 Day 25 的討論:

請求類型 走哪條路 理由
早安 / 今日簡報 Workflow 每天都一樣,固定流程最快最便宜
查天氣 Workflow 步驟明確:查 → 分析 → 回答
看待辦清單 純程式 連 AI 都不用
其他任何事 Agent 處理長尾情況

80% 的常用請求走固定流程,20% 交給 Agent。


四、專案結構

life-assistant/
├── .env                      # API keys(不進 git)
├── .env.example
├── .gitignore
├── requirements.txt
├── README.md
│
├── config.py                 # 設定管理          (Day 12)
├── logger_setup.py           # 日誌              (Day 17)
├── tracer.py                 # 決策追蹤          (Day 17)
├── prompts.py                # Prompt 模板       (Day 19)
├── main.py                   # CLI 進入點        (Day 29)
├── assistant.py              # 整合層            (Day 29)
│
├── agent/
│   ├── __init__.py
│   ├── core.py               # Agent 迴圈        (Day 22)
│   ├── budget.py             # 預算控制          (Day 25)
│   └── confirm.py            # 確認機制          (Day 25)
│
├── tools/
│   ├── __init__.py           # 自動註冊          (Day 22)
│   ├── base.py               # Tool / ToolBox    (Day 15, 22)
│   ├── weather.py            # 氣象署 API        (Day 14)
│   ├── weather_tool.py
│   ├── datetime_tool.py
│   ├── todo_tool.py
│   ├── memory_tool.py        # remember/recall   (Day 26)
│   └── calculator_tool.py
│
├── workflows/
│   ├── __init__.py
│   ├── state.py              # WorkflowState     (Day 24)
│   ├── engine.py             # Step / Workflow   (Day 24)
│   ├── router.py             # 意圖路由          (Day 23)
│   ├── daily_brief.py        # 今日簡報          (Day 24)
│   └── add_todo.py           # 新增待辦          (Day 23)
│
├── analysis/
│   ├── __init__.py
│   ├── weather_insight.py    # 天氣分析          (Day 16)
│   └── todo_insight.py       # 待辦分析          (Day 16)
│
├── memory/
│   ├── __init__.py
│   ├── conversation.py       # 對話歷史          (Day 26)
│   └── profile.py            # 使用者檔案        (Day 26)
│
├── storage/
│   ├── __init__.py
│   └── todo_store.py         # 待辦資料存取      (Day 10)
│
├── data/                     # 執行時產生(不進 git)
│   ├── todos.json
│   ├── user_profile.json
│   └── cache/
│
├── logs/                     # 執行時產生(不進 git)
│   ├── assistant.log
│   └── traces/
│
└── tests/                    # Day 29
    ├── test_tools.py
    ├── test_workflows.py
    └── scenarios.py

分層原則

這個結構有一條規則:依賴只能往下,不能往上。

main / assistant          ← 可以用下面所有的
  ↓
agent / workflows         ← 可以用 tools, analysis, memory, storage
  ↓
tools                     ← 可以用 analysis, storage
  ↓
analysis / storage        ← 只能用標準函式庫和 config
  ↓
config / logger / tracer  ← 誰都可以用

如果 storage/todo_store.py 去 import agent/core.py,那就是設計出問題了——會造成循環依賴,而且測試變得很難。


五、關鍵設計決策

把重要的選擇和理由寫下來。這對三個月後的自己很有幫助。

決策 1:用 JSON 檔案而不是資料庫

理由:單一使用者、資料量小(幾百筆)、人可以直接打開看。
代價:不支援多人、沒有交易保證、資料一大就會慢。
什麼時候該換:資料超過幾千筆,或需要多人使用時,換成 SQLite。

決策 2:CLI 而不是網頁

理由:30 天的時間有限,CLI 可以專注在 Agent 邏輯本身。
代價:只有我自己會用。
好處:邏輯和介面是分離的——Assistant 類別不知道 CLI 的存在,以後要加網頁或 LINE Bot,只要換掉 main.py。

決策 3:預設走 Workflow,Agent 當 fallback

理由:便宜、快、可預測(Day 23、25 的結論)。
代價:要維護意圖分類器。
驗證方式:Day 29 測試時記錄各路徑的命中率和成本。

決策 4:長期記憶存明文 JSON

理由:透明,使用者隨時可以打開看、自己改、自己刪。
代價:不加密。
界線:所以不記錄任何敏感資訊。這不是技術限制,是設計原則。

決策 5:危險操作一律確認

理由:Day 25 的結論——不可逆的動作,責任不能外包。
代價:多一步互動。
例外:沒有例外。就算使用者說「不用問我」,我也保留這個機制(最多提供 --yes 參數讓他自己承擔)。


六、我決定不做的事

這份清單跟「要做什麼」一樣重要:

不做 為什麼
串接 Google Calendar OAuth 流程會吃掉兩天,而且核心概念已經用天氣 API 示範過了
語音輸入 跟 Agent 主題無關
多使用者 需要帳號系統,超出範圍
向量資料庫記憶(RAG) 幾十筆記憶用 JSON 就夠,導入向量庫是過度設計
網頁介面 時間不夠,而且架構已經預留了擴充空間
自動排程執行 可以用系統的排程工具解決,不需要自己做

對 30 天的專案來說,會砍需求比會寫程式重要。

我一開始的野心是串行事曆、做網頁、加通知。實際做下來發現,把核心的 Agent 迴圈做穩,比多接三個 API 有價值得多。


七、風險清單

哪些地方最可能出問題:

風險 影響 對策 對應
氣象署 API 掛掉 簡報缺資訊 required=False + 快取 Day 24
模型回傳格式不符 程式崩潰 結構化輸出 + 防禦性解析 Day 20
Agent 無限迴圈 燒錢 Budget + 重複偵測 Day 22, 25
成本失控 帳單爆炸 預設走 Workflow + 成本上限 Day 23, 25
日期解析錯誤 待辦記錯時間 強制先查目前時間 Day 15
模型假裝完成 使用者被誤導 System prompt 明確禁止 Day 25
記憶膨脹 每次對話變貴 max_facts 限制 Day 26

每一項都在前面的某一天解決過了。這就是為什麼要先打基礎再做專案。


八、明天要做的事

Day 28 的工作清單:

  1. 把散落在各天的程式碼整理進上面的資料夾結構
  2. 補上缺的工具(complete_todo、calculate)
  3. 把 daily_brief Workflow 補完
  4. 寫 router.py 的意圖分類與分派
  5. 統一錯誤處理與 logging

Day 29 的工作清單:

  1. 寫 assistant.py 整合層
  2. 寫 main.py CLI 介面
  3. 跑完十條驗收標準
  4. 記錄成本與延遲
  5. 修 bug、寫 README

小結

  • 動手之前先定義「完成」,用具體的驗收情境,不要用模糊的「能用」
  • 先寫使用情境,再設計架構
  • 分層架構的核心規則:依賴只能往下
  • Workflow 處理 80% 的常見請求,Agent 處理 20% 的長尾
  • 把關鍵決策和理由寫下來,包含「代價」和「什麼時候該換」
  • 「不做什麼」的清單跟「要做什麼」一樣重要
  • 先列風險清單,確認每一項都有對策

明天開始寫程式,把這些零件真的接起來。


上一篇
Agent 的記憶:從對話歷史到長期偏好
下一篇
生活助理專案(二):工具層與流程層實作
系列文
從 Prompt 到自主決策:用 Python × Agentic Workflow 實作生活助理 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言