在前兩篇的查詢 6 碼郵遞區號的測試中, 我們只利用提示詞與 Gemini CLI 對話便能讓其生成程式碼, 透過 API 正確取得給定地址的郵遞區號. 本篇則要改用語境檔 GEMINI.md 來達成, 它是寫程式用的 PRD (專案需求文件檔), 關於語境檔 GEMINI.md 參考 :
以下測試使用 uv 工具來管理專案與 Python 版本, 關於 uv 參考 :
首先開啟 PS 視窗, 用 uv init 建立一個名為 postal-helper-proj3 的 Python 專案資料夾 :
PS D:\gemini> uv init postal-helper-proj3
Initialized project `postal-helper-proj3` at `D:\gemini\postal-helper-proj3`
切換到專案資料夾檢視 uv 建立的檔案 :
PS D:\gemini> cd postal-helper-proj3
PS D:\gemini\postal-helper-proj3> dir
目錄: D:\gemini\postal-helper-proj3
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2026/1/30 上午 11:13 109 .gitignore
-a---- 2026/1/30 上午 11:13 5 .python-version
-a---- 2026/1/30 上午 11:13 97 main.py
-a---- 2026/1/30 上午 11:13 165 pyproject.toml
-a---- 2026/1/30 上午 11:13 0 README.md
然後開啟記事本編輯 GEMINI.md, 輸入如下內容 (可請 Gemini 產生) :
# 專案設定:台灣郵遞區號查詢工具 (Taiwan ZipCode CLI)
## 1. 角色與語氣
- **角色**: Python 腳本開發者 (Python Scripter)。
- **語氣**: 輕鬆、直觀、實用導向。
- **語言**: 繁體中文 (Traditional Chinese)。
## 2. 技術堆疊與工具 (Tech Stack)
- **專案管理**: **uv** (由 Astral 開發的超快 Python 工具)。
- 安裝套件請用: `uv add <package>`
- 執行程式請用: `uv run <script.py>`
- **禁止使用**: 傳統的 `pip install` 或手動建立 `venv` 指令。
- **語言版本**: Python 3.12+
- **關鍵套件**:
- `requests` (若需爬蟲或呼叫 API)
- `beautifulsoup4` (若需解析 HTML)
- `typer` 或 `argparse` (用於處理 CLI 指令參數)
## 3. 專案目標 (Project Goal)
開發一個簡單的 Command Line Interface (CLI) 工具,功能如下:
1. **輸入**: 使用者輸入「縣市」+「行政區」 (例如:`高雄市三民區`) 或 「完整地址」。
2. **處理**: 程式透過網路查詢 (中華郵政/開放資料 API) 或 內建字典檔。
3. **輸出**: 回傳對應的 **3+3 郵遞區號** (優先) 或 **3 碼地區號**。
## 4. 程式碼規範
- **結構**: 保持簡單,盡量將功能封裝在 `main.py` 模組中。
- **錯誤處理**: 如果使用者輸入的地址不存在或打錯字,請回傳友善的中文提示 (例如:「找不到此地區,請確認輸入格式」),而非 Python Traceback。
- **註解**: 程式碼中請加入簡單的中文註解,說明資料來源或邏輯。
## 5. 互動範例 (Expected Behavior)
使用者在終端機執行:
```bash
uv run main.py "台北市信義區市府路1號"
以 utf-8 編碼存檔後, 在此專案目錄下輸入 gemini 啟動 Gemini CLI :
可見 Gemini CLI 一啟動就會先讀取 GEMINI.md 的內容作為對話中持續性的系統提示, 我先問它是否經由此語境檔已完全了解專案目標, 並要求它先提供執行計畫再做 :
> 請問你了解此專案了嗎? 請不要開始寫程式,先告訴我你的計劃
它回答如下, 看來並無問題, 輸入 ok, 好的, 或 go ahead 等授權它撰寫程式 :
程式撰寫完畢要求寫入 main.py :
要求授權用 uv 執行測試 :
測試 "台北市信義區市府路1號" 結果正確, 要求再授權測試 "高雄市三民區" :
測試成功取回 3 碼郵遞區號, 要求授權刪除虛擬環境中沒用到的套件 :
完成專案 :
最後開啟 main.py 將程式碼抄錄如下 :
import typer
import requests
import json
import sys
from typing import Optional
app = typer.Typer(help="台灣郵遞區號查詢工具 (Taiwan ZipCode CLI)")
# 3碼郵遞區號備援字典 (部分範例,實務上可擴充或改用完整資料檔)
THREE_DIGIT_ZIPCODES = {
"台北市": {
"中正區": "100", "大同區": "103", "中山區": "104", "松山區": "105",
"大安區": "106", "萬華區": "108", "信義區": "110", "士林區": "111",
"北投區": "112", "內湖區": "114", "南港區": "115", "文山區": "116"
},
"高雄市": {
"新興區": "800", "前金區": "801", "苓雅區": "802", "鹽埕區": "803",
"鼓山區": "804", "旗津區": "805", "前鎮區": "806", "三民區": "807",
"楠梓區": "811", "小港區": "812", "左營區": "813", "仁武區": "814",
"大社區": "815", "岡山區": "820", "路竹區": "821"
},
"台中市": {
"中區": "400", "東區": "401", "南區": "402", "西區": "403", "北區": "404",
"北屯區": "406", "西屯區": "407", "南屯區": "408"
}
}
def query_zip5_api(address: str) -> Optional[str]:
"""
使用 zip5.5432.tw API 查詢 3+3 郵遞區號
"""
try:
# 使用知名的 zip5 服務 (非官方但穩定)
url = "https://zip5.5432.tw/zip5json.py"
params = {"adrs": address}
response = requests.get(url, params=params, timeout=5)
response.raise_for_status()
# 該 API 回傳格式為 JSON
data = response.json()
# 檢查是否有回傳 zipcode
if data and "zipcode" in data and data["zipcode"]:
return data["zipcode"]
except requests.RequestException:
# 網路連線錯誤,靜默失敗,交給備援機制
return None
except json.JSONDecodeError:
return None
return None
def lookup_local_3digit(address: str) -> Optional[str]:
"""
從內建字典查詢 3 碼郵遞區號
"""
for city, districts in THREE_DIGIT_ZIPCODES.items():
if city in address:
for district, code in districts.items():
if district in address:
return code
return None
@app.command()
def main(
address: str = typer.Argument(..., help="請輸入完整地址或縣市行政區,例如:'台北市信義區市府路1號' 或 '高雄市三民區'"),
show_json: bool = typer.Option(False, "--json", "-j", help="以 JSON 格式輸出")
):
"""
查詢台灣郵遞區號 (優先嘗試 3+3 碼,失敗則回傳 3 碼)
"""
result_code = None
source = "未知"
# 1. 嘗試網路查詢 (3+3)
print(f"正在查詢 '{address}' 的郵遞區號...", file=sys.stderr)
result_code = query_zip5_api(address)
if result_code:
source = "網路查詢 (3+3碼)"
else:
# 2. 失敗則嘗試內建字典 (3碼)
result_code = lookup_local_3digit(address)
if result_code:
source = "內建字典 (3碼地區號)"
# 3. 輸出結果
if result_code:
if show_json:
print(json.dumps({"address": address, "zipcode": result_code, "source": source}, ensure_ascii=False))
else:
print(f"--------------------------------")
print(f"查詢結果: {result_code}")
print(f"資料來源: {source}")
print(f"--------------------------------")
else:
print(f"❌ 找不到此地區,請確認輸入格式 (例如:縣市 + 行政區 + 路名)。")
sys.exit(1)
if __name__ == "__main__":
app()
可見 Gemini CLI 這次採取自己的方式查詢郵遞區號, 如果在 GEMINI.md 中有限制它使用 zip5.5432.tw 的 API 查詢的話, 實作方式應該會跟前面第一篇測試文章的實作結果差不多.









沒有留言 :
張貼留言