前一篇我們說明了 llm-wiki 與外層 chaos-agent 的分工,Raw Sources 也已經準備完成。
今天要正式跑第一次 Ingest,看看 AI Agent 怎麼把架構文件整理成 Wiki。Ingest 完成後,再由 chaos-agent 讀取 transaction-service 的程式碼,找出適合拿來做混沌實驗的弱點。
整體流程如下:
這次使用 snapshot-001,建立時間是 2026 年 5 月 20 日,對應 lite-bank-demo commit ed545a14。
第一次 Ingest 在 5 月 23 日完成。後續整理架構、檢查部署設定或讀取程式碼,都要使用這個版本,避免把不同時間的結果混在一起。
第一次 Ingest 讀取的是 sources/architecture/docs/architecture.md。這份文件記錄 lite-bank-demo 的服務分層、相依關係、critical path(核心交易路徑),以及各元件故障後會影響哪些功能。
Agent 讀完架構文件後,產生三項內容:
wiki/source-summaries/ 建立架構文件摘要。manifest.json 的 services_in_scope 建立 10 個 Service 頁面。wiki/index.md,按照業務重要性排列所有 Service。Source Summary 先整理出幾個重要結論:transaction-service 是唯一能修改帳戶餘額的服務,api-gateway 是唯一外部入口。
它也記錄了 PostgreSQL 是共用資料庫,以及所有業務服務目前都只有一個 replica。這些資訊可以幫助 Agent 判斷服務的重要性與可能的故障範圍。
Service 頁面會先填入架構文件能確認的資料。以下節錄並簡化第一次 Ingest 產生的 transaction-service.md:
# transaction-service
## 摘要
Data Layer 服務,也是系統中唯一可以修改帳戶餘額的服務。
轉帳、存款、提款與換匯,最後都會經過這個服務寫入 PostgreSQL。
## 重要性
- 業務重要性:high
- 上游依賴:teller-service、exchange-service
- 下游依賴:PostgreSQL、Kafka
- 爆炸半徑:服務故障時,所有帳戶異動功能都會失敗
## 已知弱點
(尚無)
## 做過的實驗
(尚無)
此時的 Service 頁面比較像系統地圖。Agent 先整理架構文件能確認的資訊,證據不足的欄位會直接標記「資料不足,待下一輪補充」。接下來才會讀取原始碼,找出具體弱點。
第一次 Ingest 也替每個 Service 分配弱點編號前綴,例如 transaction-service 使用 TX、api-gateway 使用 GW、account-service 使用 ACC、teller-service 使用 TEL。因此,transaction-service 找到的第一個弱點會記錄為 TX-W001。後續的實驗、修復與跨服務共通弱點,都能沿著這個 ID 往回追查。
從 10 個 Service 裡,Agent 第一個選擇 transaction-service。它是唯一能修改帳戶餘額的服務,故障影響範圍最大,很適合拿來當第一個弱點掃描目標。
程式碼部分,Agent 只讀跟這次掃描有關的七個檔案:
application.yml
KafkaProducerConfig.java
TransactionService.java
TransactionEventPublisher.java
AccountRepository.java
TransactionRepository.java
pom.xml
這七個檔案涵蓋 connection pool、transaction timeout、Kafka producer、retry 與 circuit breaker。Agent 直接檢查設定檔、核心交易邏輯、Repository、event publisher 與相依套件宣告,減少其他程式碼造成的干擾。
部署相關的判斷則使用 Raw Sources 裡的 Helm snapshot。因此,replica 與 health probe 的結果來自 sources/architecture/helm/litebank/,沒有包含在上面的程式碼清單裡。
執行掃描時,本機 repo 的 HEAD 已經從 ed545a14 前進到 ce8a63c。為了避免混用不同版本的程式碼,Agent 改用 manifest.json 鎖定的 commit 讀取檔案:
git show ed545a14:services/transaction-service/src/main/resources/application.yml
manifest.json裡的 commit hash 是這次分析的結果基準。即使 repo 後續繼續更新,我們仍然可以回頭讀取相同版本,重新檢查當時的弱點判斷。
5 月 27 日,程式碼與設定檔讀完後,Agent 找到 7 條弱點。其中 6 條的可信度是 high;TX-W007 對高負載下 thread 等待 DB connection 的影響仍有部分推論,因此標成 medium。
| ID | 類別 | 發現 | 可信度 |
|---|---|---|---|
TX-W001 |
connection-pool | HikariCP 沒有設定 pool 參數,預設最多 10 條連線 | high |
TX-W002 |
timeout | @Transactional 沒有 timeout,又搭配悲觀鎖,DB 變慢時可能長時間卡住 |
high |
TX-W003 |
missing-circuit-breaker | pom.xml 沒有 Resilience4j 或 Spring Retry,程式裡也找不到對應 annotation |
high |
TX-W004 |
dual-write | 更新 DB 與發送 Kafka event 是兩個分開的動作,其中一個失敗就可能造成資料不一致 | high |
TX-W005 |
timeout | Kafka producer 沒有明確設定 request.timeout.ms、delivery.timeout.ms 與 max.block.ms,目前沿用 Kafka client 預設值 |
high |
TX-W006 |
deployment | replicas: 1,Pod 被終止或重建時沒有其他 instance 接手流量,新 container 啟動 30 秒後 readiness probe 才會開始檢查 |
high |
TX-W007 |
thread-pool | Tomcat 預設 200 threads,HikariCP 只有 10 條連線,高負載時大量 thread 可能卡在等待 DB | medium |
TX-W003 的 high 代表「程式裡確實找不到 Circuit Breaker」。不過,光是沒找到 Circuit Breaker,還不能直接判定這就是弱點。還要先看 transaction-service 會受到哪個外部系統影響,以及 Circuit Breaker 能不能處理這種問題。
其中三條會直接影響核心寫入路徑或資料一致性,特別值得注意:
@Transactional 方法內送出 event,卻沒有等待非同步發送結果。更新 DB 與發送 Kafka event 可能一個成功、另一個失敗,最後讓帳戶資料、報表與通知對不起來。Agent 也會記錄系統已經做好的韌性措施,包含悲觀鎖、依 account ID 排序鎖定、Kafka acks=all、idempotence、producer retries=3、Flyway schema 管理與 OTel manual Span。記下已經具備的措施,可以避免下一次掃描重複提出相同建議。
這 7 條弱點目前都標成 scanned,代表 Agent 從程式碼或設定裡找到可疑的地方,系統還沒有真的被打過。等到實際注入故障,而且觀察到預期的影響,狀態才會更新為 executed-confirmed。
第一次 Ingest 先把 Raw Sources 整理成 10 個 Service 頁面和系統索引。接著,chaos-agent 讀取 transaction-service 這次需要的程式碼與部署設定,找出 7 條有來源可以回查的弱點。
現在系統地圖與第一批混沌實驗候選都準備好了。下一篇,我們來看 AI 如何挑選弱點、提出假設、注入故障,最後整理出完整的觀察報告。
今天就先寫到這,我們明天見!