Jira AI 生態系 Agent Skill 架構解析
從「一個腳本打天下」的過渡方案,到職責分離、環境隔離、Azure OpenAI 企業部署的 Agent Skills 模組化生態系。
深入剖析四個 Agent Skills 的底層設計邏輯、資料媒體檔設計,以及 TF-IDF + AI 兩段式去重的技術選型。
Tech Stack at a Glance
| Agent Skill | 語言 / Runtime | 核心依賴 | AI 推論 | 狀態儲存 |
|---|---|---|---|---|
| jira-crawler | Python 3.10+ | requests, python-dotenv |
無 | Markdown files |
| jira-duplicate-finder | Python 3.10+ | scikit-learn, jieba, openai |
Azure OpenAI API | JSON report |
| jira-ai-analyst | Python 3.10+ | openai (Azure SDK) |
Azure OpenAI API | Markdown files |
| jira-auto-triage | Python 3.10+ | requests, sqlite3, openai |
Azure OpenAI API | SQLite + JSON snapshot |
技術挑戰:為什麼需要這套 Agent Skill 生態系?
在導入企業 Jira AI 自動化時,我們面臨了三個核心技術瓶頸:
當工單量達到數千筆時,找出重複 Bug 是一個 O(N²) 的暴力比對問題。若全數交由 LLM 處理,API 成本與延遲將呈幾何倍數增長,難以在生產環境落地。
傳統自動化腳本將 Jira API 呼叫、AI Prompt、商業邏輯與狀態管理高度耦合。只要 Jira 欄位異動或 Prompt 需要微調,整個系統就面臨重構風險,且難以進行單元測試與模擬(Dry-run)。引入 Agent Skill 架構能有效解決此問題。
Jira 工單包含敏感的系統架構與業務機密。直接傳輸至公共 AI 服務存在合規性風險。我們需要一套能與企業內網(Private Network)與受控 AI 環境(如 Azure OpenAI)深度整合的 Agent Skill 架構。
設計哲學:為什麼要「職責分離」設計 Agent Skills
大多數 Vibe Coding 出來的 Jira 自動化工具都是一個大腳本包辦一切,從抓資料、分析、寫回 Jira。這種設計短期快,長期災難。
違反軟體工程:God Script
一個腳本負責:抓 Jira API → 去重排查 → 呼叫 AI 分析 → 回寫 Jira。
- 爬蟲邏輯改了,AI Prompt 也要動:耦合度過高,改 A 壞 B。
- 無法單獨測試:每次驗證都要跑完整個流程,打 Jira API + 消耗 AI Token。
- Dry-run 很難實作:資料抓取與寫回混在同一流程,難以中斷插入預覽層。
本系統:Separation of Concerns (Agent Skills)
資料收集、AI 分析、狀態管理、Jira 回寫——四件事,四個專屬 Agent Skill,各自獨立。
- 各自演化互不干擾:換 AI 模型不影響爬蟲 Agent Skill;改 Prompt 不觸碰資料結構。
- 可單獨測試每個環節:爬蟲產生的 Markdown 就是其他 Skill 用的 raw data
- Dry-run 天然支援:分析與回寫跟操作 Jira 分離,中間插入預覽層輕而易舉。
資料媒體檔:Markdown 作為 Agent Skills 之間的介面
Agent Skills 之間唯一的資料交換格式是 Markdown 純文字檔。這個選擇背後有意識的設計考量:
.md 確認資料品質,不需要 schema 文件或特定工具。環境隔離設計:每個 Agent Skill 是自包含的 CLI 模組
每個 Agent Skill 目錄下各自維護一個 .venv/ 虛擬環境,依賴項目完全隔離。
Agent-Skills/ ├── jira-crawler/ │ ├── .venv/ # 獨立虛擬環境 │ ├── scripts/crawl.py │ ├── tickets/ # 輸出目錄(.gitignored) │ ├── requirements.txt │ └── .gitignore │ ├── jira-ai-analyst/ │ ├── .venv/ │ ├── scripts/run_analysis.py │ ├── assets/prompt_template.md # 可自訂 Prompt │ └── requirements.txt │ ├── jira-auto-triage/ │ ├── .venv/ │ ├── scripts/ │ │ ├── fetch_and_prepare.py │ │ ├── update_jira.py # --dry-run 支援 │ │ └── rollback.py # 快照回滾 │ ├── references/custom_rules.md │ ├── jira_triage.db # SQLite 狀態庫 │ └── requirements.txt │ └── jira-duplicate-finder/ ├── .venv/ ├── scripts/find_duplicates.py ├── duplicates.json # 輸出報告 └── requirements.txt
為什麼不用共用 venv?
- Agent Skill A 升級
requests版本,Agent Skill B 跑掉 - 部署到新機器時,難以釐清哪個 Agent Skill 需要哪些套件
scikit-learn等分析套件的 import 時間不應拖累輕量爬蟲的啟動
- 各 Agent Skill 的
requirements.txt即完整說明書 - 新機器只需兩行指令即可初始化任一 Agent Skill
- 可以把單個 Agent Skill 目錄直接複製到其他專案使用
四大 Agent Skills 技術解析
[AGENT-SKILL-01] jira-crawler
Pure ETL · No AI · High Stability設計核心:爬蟲就只做爬蟲的事,不含任何 AI 邏輯。作為最基礎的 Agent Skill,穩定性優先,職責單一。
- Jira REST API v3:支援 JQL 查詢、欄位過濾、分頁抓取(處理大型 Project)
- 抓取 Ticket 詳細欄位:Summary、Description、Comments、Status、Assignee、Priority
- 輸出格式為結構化
.md,包含 YAML Front Matter 方便後續程式解析 - 增量抓取:透過 JQL
updated >= X只拉異動工單,避免全量重跑
爬蟲的主要失敗點是網路、API Rate Limit、Token 過期——與 AI 完全無關。若把 AI 混入同一流程,一旦 AI 服務異常,連資料都抓不到,且 Debug 難以定位問題。
[AGENT-SKILL-02] jira-duplicate-finder
TF-IDF Pre-filter · 2-Stage · Token Efficient海選排查重複 Ticket 的 Agent Skill。解決一個棘手的問題:如何在 N 個 Ticket 中,以最低成本找出所有重複配對?
如果有 N 個 Ticket,暴力兩兩比對需要 N*(N-1)/2 次 AI 呼叫。
用 sklearn 計算所有 Ticket 的 TF-IDF 向量,計算 Cosine Similarity,只保留超過閾值的可疑配對。計算成本趨近於零。
只將 Stage 1 篩選出的少數配對送給 AI 判斷,AI 呼叫次數從 O(N²) 降至 O(k),k 遠小於 N²。
提供 --date、--start、--end 三種日期參數,讓使用者精準限制「基準 Ticket」的建立日期範圍。這樣做有兩個好處:一是大幅縮小比對空間;二是避免把半年前的舊 Ticket 誤判為與今天的新 Ticket 重複。
JSON 報告包含每個重複配對的:原始 Ticket Keys、相似度分數、AI 的判定理由、建議合併方向(哪張是原始、哪張是重複)。格式設計上考慮了可接入其他自動化 pipeline 自動標記的擴充性。
[AGENT-SKILL-03] jira-ai-analyst
Azure OpenAI · Enterprise · Prompt Versioning企業部署的 AI 分析引擎。作為核心的分析 Agent Skill,讀取本機 Markdown 檔案,透過 Azure OpenAI 企業 API 執行推論,且資料在客戶專屬 Azure 租戶中處理,合約保障不用於模型訓練。
來源:Microsoft Learn – Data, privacy, and security for Azure OpenAI
- Azure OpenAI SDK:使用
openai.AzureOpenAIclient,透過環境變數注入 endpoint、API key 與 deployment name - Prompt 模板外部化:分析邏輯存於
assets/prompt_template.txt,修改分析角度不需改程式碼 - 批次處理:掃描
../jira-crawler/tickets/目錄,自動略過已分析的 Ticket(避免重複消耗) - 輸出
[TicketKey]-analysis.md,與原始 Ticket 並排存放,方便對照
將 Prompt 從程式碼中解耦,並在每份輸出加上版本指紋:
- 非工程師可直接修改
.md調整分析維度,不需改 Python Code - 每份
-analysis.md的 Front Matter 記錄 Prompt 的 MD5 hash,可追蹤「哪個版本的 Prompt 產出了哪份分析」 - A/B 測試不同 Prompt 效果時,差異一目了然
[AGENT-SKILL-04] jira-auto-triage
E2E Pipeline · SQLite State · Dry-run · Rollback最複雜的 Agent Skill,端對端自動化管線,含完整的狀態管理、AI 判定、Jira 回寫,以及不可或缺的防呆與回滾機制。
- Phase 1 抓取爬蟲的的所有 Ticket 資料寫入
jira_triage.db - Phase 2 的 AI 判定結果也寫回同一個 DB
- 每個步驟的狀態可被獨立查詢,中途失敗可從任何 Phase 重新開始
- 自動產生 JSON 快照備份,確保即使 DB 損毀也有救援路徑
- Prompt 要求 AI 以 JSON structured output 回傳判定結果,欄位含
verdict與confidence(0–1 浮點數,由 AI 自評) - 低於門檻的判定結果標記為
REVIEW_NEEDED,不自動回寫 - 門檻值可在 config 中調整,達成「自動化程度」與「準確率」的平衡
- 確保高影響力的狀態變更(如關閉 Ticket)有更嚴格的信心要求
--dry-run:執行全部邏輯但不實際呼叫 Jira 寫入 API,僅輸出預覽報告- 正式執行前自動建立狀態快照
rollback.py讀取快照,透過 Jira API 還原所有被修改的 Ticket 到原始狀態- 回滾有完整 log,可追蹤每筆還原操作
Lessons Learned 設計決策筆記
為什麼選 SQLite 而不是 JSON 檔?
最初版本的 auto-triage Agent Skill 用 JSON 儲存狀態,結果遇到兩個問題:並行寫入會損毀檔案;Agent 分析中途失敗時,很難知道「從哪裡繼續」。
改用 SQLite 後:每個 Ticket 的處理狀態都有獨立的 row,失敗後可以用 WHERE status = 'pending' 精確撈出未完成項目重新執行,也支援 ROLLBACK 的 Transaction 語義。
AI 自動回寫 Jira 的信任問題
第一版直接讓 AI 決定狀態後立刻寫回,測試階段就出現誤判,將不該關閉的 Bug 錯誤調為 Closed。
修正後的設計:強制 Dry-run 先行,把「AI 判定」與「Jira 寫入」切成兩個獨立的 script。所有寫入前自動快照,讓 rollback 成本降到接近零,團隊才真的敢授權 Agent Skill 自動操作生產環境。
TF-IDF 閾值的調校過程
初始閾值設太高(0.85),漏掉了很多「描述方式不同但是同一個 Bug」的配對。設太低(0.3),又讓大量不相干的 Ticket 進入 Stage 2,Token 消耗暴增。
最終策略:針對 Jira 工單的文字特性(標題短、描述有大量術語),調整到 0.55–0.65 作為預設區間,並在 config 中暴露此參數讓使用者針對不同專案微調。
Prompt 模板版本管理
prompt_template.txt 被改過太多次,後來難以追蹤「哪個版本的 Prompt 產出了哪份分析報告」,出現了結果不一致但原因不明的問題。
改進:在每份 -analysis.md 的 Front Matter 中加入 Prompt 的 MD5 hash,讓每份報告都帶有自己的「分析條件指紋」,方便日後比對 Prompt 版本與分析品質的相關性。