前幾天已完成 PM、Research、Creative 與 Finance Agent。不過,產生結果和檢查結果是兩件事:草案可能缺少研究依據、執行方式不清楚,或把待查證資訊寫成事實。
今天建立 Review Agent,先處理輸入格式、結構化審查結果與單元測試。它目前仍是獨立類別,尚未接進 Discord,也不會自動呼叫其他 Agent。
ReviewAgent
| 欄位 | 檢查內容 |
|---|---|
completeness |
草案內容是否齊全 |
creativity |
方案是否有明確做法 |
credibility |
研究依據與待查證資訊是否分清楚 |
feasibility |
執行方式、成本與風險是否合理 |
每項都要回傳通過狀態與原因,Python 不必再從一大段評論中猜測審查結果。
ReviewAgent.respond() 不接受任意文字,而是要求固定 JSON:
class ReviewRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
project_id: NonEmptyText
draft: NonEmptyText
revision_count: RevisionCount = 0
project_id:草案所屬專案draft:要檢查的內容revision_count:已修改次數,預設為 0
修改次數只能是 0 或 1:
RevisionCount = Annotated[
int,
Field(strict=True, ge=0, le=1),
]
0 表示初稿還能修改一次,1 表示已修改過。輸入 2 時會在呼叫 LLM 前被拒絕。
每個檢查項目包含結果與原因:
class ChecklistItem(BaseModel):
passed: bool
reason: NonEmptyText
需要修改時,不能只說「內容不完整」,還要指出問題、修改方式與優先順序:
class ReviewIssue(BaseModel):
problem: NonEmptyText
required_change: NonEmptyText
priority: Literal["高", "中", "低"]
完整輸出由 ReviewAnalysis 組合:
class ReviewAnalysis(BaseModel):
status: Literal["通過", "需要修改"]
checklist: ReviewChecklist
issues: list[ReviewIssue]
revision_allowed: bool
固定選項能避免同一個優先順序同時出現「重要」、「緊急」與 High 等不同寫法。
JSON 格式正確,不代表內容一致。例如 status 寫「通過」,Checklist 卻有一項失敗;或狀態是「需要修改」,卻沒有列出問題。
ReviewAnalysis 使用 @model_validator(mode="after") 檢查整份資料:
| 狀態 | Checklist | Issues |
|---|---|---|
通過 |
四項都必須通過 | 必須是空陣列 |
需要修改 |
至少一項未通過 | 至少一個問題 |
這些條件由 Python 強制檢查,不只依賴 Prompt。
Review Agent 沿用 StructuredAgent[ReviewAnalysis],主要設定如下:
role = 專案品質審查員
temperature = 0.0
seed = 42
max_output_tokens = 700
審查需要較收斂的回答,因此使用 temperature=0.0。ReviewAnalysis.model_json_schema() 會把 Checklist、Issue 與固定選項轉成 JSON Schema,再交給 LLM Service。
respond()?Review 比其他結構化 Agent 多兩個步驟:呼叫模型前先驗證 ReviewRequest,回覆後再重新計算 revision_allowed。
輸入錯在 revision_count 時,會回覆「修改次數只能是 0 或 1」;其他缺欄位、空字串或多餘欄位,統一視為 Review 輸入格式錯誤。驗證成功後,再把標準 JSON 交給 StructuredAgent。
模型回覆後,程式不直接採信它提供的 revision_allowed,而是重新計算:
revision_allowed = (
result.status == "需要修改"
and request.revision_count == 0
)
return result.model_copy(
update={"revision_allowed": revision_allowed}
)
只有「審查需要修改」而且「目前仍是初稿」時,才允許修改一次。這是流程控制資料,交給 Python 判斷比讓模型決定更清楚。
tests/test_review_agent.py 使用固定 JSON,不會啟動 Ollama。DAY 14 加入四種測試:
revision_count=1 時,即使仍需修改,也不能再退修。revision_count=2 會在呼叫 LLM 前被拒絕。其中第二種案例讓 credibility 不通過,原因是成本數字缺少資料來源。因為仍是初稿,所以 revision_allowed=True。
python -m unittest discover -s tests -v
Ran 40 tests in 0.093s
OK
完整測試共 40 項,其中 4 項直接測試 Review Agent。這是 Python 搭配 Fake Response 的結果,真實模型回覆的穩定度仍要等整合後驗證。
DAY 14 完成 Review Agent 的輸入格式與結構化審查結果。草案會從完整度、創意、可信度與可行性接受檢查;跨欄位驗證會擋下矛盾資料,修改機會則由 Python 控制,最多一次。
下一篇開始處理五位 Agent 的執行順序與資料傳遞。