信用卡對帳智能體:自動化財務工作流程中的「完成」如何界定
Credit Card Reconciliation Agents: What \\\\\\\"Done\\\\\\\" Means When Automating Financial Workflows
Steven Davies 正在構建離線信用卡對帳智能體,以每步驗證條件界定工作是否完成,並在錯誤持續時停止流程而非猜測繼續。工作規格、帶驗收條件的 issue 和驗證邊界分開管理,GitHub issue 記錄提交雜湊、驗證結果及重試次數;失敗三次便停止並呈報錯誤。流程在本機讀取 CSV、寫入本機檔案,並透過 API 更新 GitHub issue,不依賴雲端,交易資料不會離開本機。
Most agent demos show a single successful run. Real financial automation requires defining what "done" means before the agent starts, what state it preserves when it fails halfway through, and how it proves correctness without human spot-checking every row.
Steven Davies is building an offline credit card reconciliation agent that imports transactions, calculates account splits, and tracks settlements. The interesting part is not the reconciliation logic. It's the scaffolding around the agent: context that survives conversation boundaries, validation that runs before marking work complete, and limits that stop runaway correction loops.
The Gap Between "It Ran" and "It's Correct"
Financial workflows expose a specific failure mode. An agent can execute every step, produce output, and still be wrong in ways that compound over time. A missed transaction or incorrect account mapping creates downstream errors that spread across monthly reconciliations.
The solution is not better prompts. It's defining completion criteria as code before the agent runs, then validating against those criteria after each step.
Davies structures this in three layers:
- Specification file: what the application must do (business rules, data sources, expected outputs)
- Issue tickets: discrete units of work with acceptance criteria
- Validation boundaries: automated checks that run before marking a step complete
The agent gets the spec, asks clarifying questions using a reusable "grilling skill," then generates issues. Each issue becomes a bounded task with its own done criteria.
Reusable Agent Skills as Workflow Primitives
A skill is a prompt template that handles a specific kind of work. Davies uses two:
- Grilling skill: asks one question at a time, gives a recommendation, waits for a decision
- To-issues skill: converts conversation decisions into GitHub tickets
This pattern separates conversation (which is ephemeral) from decisions (which need to persist). The agent can reconstruct context from tickets without replaying the entire chat history.
Here's the shape of a validation boundary in a reconciliation workflow:
def validate_reconciliation_step(transactions, account_splits, settlement_records):
"""
Run before marking a reconciliation step complete.
Returns (is_valid, errors) tuple.
"""
errors = []
# Check 1: All transactions accounted for
total_transactions = sum(t.amount for t in transactions)
total_splits = sum(s.amount for s in account_splits)
if abs(total_transactions - total_splits) > 0.01:
errors.append(f"Split mismatch: {total_transactions} vs {total_splits}")
# Check 2: No duplicate transaction IDs
transaction_ids = [t.id for t in transactions]
if len(transaction_ids) != len(set(transaction_ids)):
errors.append("Duplicate transaction IDs detected")
# Check 3: Settlement records match splits
total_settled = sum(r.amount for r in settlement_records)
if abs(total_splits - total_settled) > 0.01:
errors.append(f"Settlement mismatch: {total_splits} vs {total_settled}")
return (len(errors) == 0, errors)
The agent calls this after each reconciliation step. If validation fails, the agent gets the error list and can retry with specific context about what's wrong. If it fails three times, the workflow stops and surfaces the errors to a human.
State Management for Partial Completion
When an agent fails mid-workflow, you need to know:
- Which steps completed successfully
- What data was written to which files
- What validation checks passed or failed
- Where to resume without re-running expensive operations
Davies uses GitHub issues as the state store. Each issue represents a unit of work. The agent updates the issue with:
- Commit hashes for code changes
- Validation results (pass/fail with error details)
- Retry count
- Timestamp of last attempt
This gives you a queryable audit trail. You can see which reconciliation steps succeeded, which failed, and what the agent tried before giving up.
Orchestration Flow for Financial Agents
Here's the control flow for a reconciliation run:
- Load specification: read business rules, data sources, account mappings
- Import transactions: fetch from CSV/API, deduplicate, validate schema
- Calculate splits: apply rules to determine which accounts fund which transactions
- Validate splits: run balance checks, verify no orphaned transactions
- Generate settlement records: create transfer instructions for each account
- Validate settlements: confirm totals match, no double-counting
- Write output: save to local files, update issue status
- Final validation: re-run all checks on persisted data
Each step has a validation boundary. If any check fails, the agent gets the error context and can retry that specific step. After three failures, the workflow stops and logs the state.
Comparison: Validation Strategies for Financial Agents
| Strategy | When to Use | Failure Mode | Recovery Cost |
|---|---|---|---|
| Post-run manual review | Low transaction volume, high trust in agent | Silent errors compound over time | High (manual reconciliation) |
| Per-step validation with retry | Medium volume, structured data | Agent loops on ambiguous errors | Medium (bounded retries) |
| Dual-write with diff | High volume, regulatory requirements | Storage overhead, sync complexity | Low (automated rollback) |
| Human-in-loop approval | High-risk transactions, new workflows | Blocks automation, slow feedback | Low (catch errors early) |
Davies is using per-step validation with bounded retries. This works for personal finance where transaction volume is manageable and the cost of a failed run is low (you just re-run it). For production financial systems, you'd add dual-write (persist to two stores, diff on read) or human-in-loop approval for transactions above a threshold.
Error Boundaries That Fail Safely
The worst outcome for a financial agent is silent incorrectness. The agent completes, writes data, and you don't notice the error until you're reconciling next month's statements.
Davies addresses this with explicit failure modes:
- Validation failure: agent stops, surfaces specific errors, does not write partial data
- Retry exhaustion: agent stops after N attempts, logs state, marks issue as blocked
- Ambiguous data: agent flags transactions it can't confidently categorize, writes them to a review queue
This is the opposite of "best effort" execution. The agent is designed to fail loudly when it's uncertain, rather than guess and move on.
Observability for Multi-Step Workflows
You need to answer three questions after each run:
- What did the agent do? (action log)
- What data changed? (diff of input vs output files)
- What checks passed or failed? (validation results)
Davies gets this from:
- GitHub issue updates: each step logs its status, commit hash, and validation results
- File diffs: git tracks changes to transaction files, split calculations, and settlement records
- Validation logs: structured output from each boundary check (pass/fail, error details, retry count)
This gives you a complete audit trail without instrumenting the agent code. The orchestration layer handles logging, the agent just calls validation functions and reports results.
Deployment Shape
This is an offline, local-first workflow. The agent runs on your machine, reads from local CSV files, writes to local files, and updates GitHub issues via API. No cloud dependencies, no transaction data leaves your machine.
The trade-off is manual triggering. You run the agent when you're ready to reconcile, rather than on a schedule. For personal finance, this is acceptable. For production systems, you'd add:
- Scheduled runs: cron or GitHub Actions to trigger reconciliation daily/weekly
- Webhook triggers: run when new transactions appear in a watched directory
- Idempotency keys: prevent duplicate processing if the agent runs twice on the same data
Likely Failure Modes
Ambiguous transaction matching: if a transaction appears in multiple spreadsheets with slightly different amounts or dates, the agent can't confidently match them. Solution: add a fuzzy matching threshold and flag near-matches for human review.
Schema drift: if you change the structure of your transaction CSV (add a column, rename a field), the agent's validation logic breaks. Solution: version your schema, add a migration step that runs before validation.
Partial writes: if the agent crashes after writing splits but before writing settlements, you have inconsistent state. Solution: use atomic file writes (write to temp file, rename on success) or wrap the entire workflow in a transaction.
Retry loops on persistent errors: if validation fails because of bad source data (not agent logic), retrying won't help. Solution: add error classification (transient vs permanent) and skip retries for permanent errors.
Technical Verdict
Use this pattern when you're building financial agents that need to prove correctness, not just completion. The overhead of defining validation boundaries and managing state pays off when silent errors would be expensive to fix later.
Skip it if you're prototyping, working with low-stakes data, or building agents that produce output for human review anyway. The scaffolding adds complexity that only makes sense when the cost of incorrectness is high.
The key insight is that "done" is not a boolean. It's a set of validation checks that run after each step, with explicit failure modes and recovery paths. Define those checks before the agent runs, and you get automation that fails safely instead of silently.
Source Links
來源:DEV Community · dev.to