본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 08. 10:40

단 하나의 봇이 모든 계좌를 볼 수 있을 때, 상시 가동 에이전트가 재무 워크플로우를 망치는 이유를 마침내 이해했습니다

요약

재무 자동화 에이전트 설계 시 단일 에이전트가 모든 계좌 컨텍스트를 공유할 때 발생하는 위험성을 경고합니다. 데이터 격리와 도메인 분리가 프롬프트 최적화보다 중요한 아키텍처 설계의 핵심임을 강조합니다.

핵심 포인트

  • 공유된 컨텍스트는 에이전트의 오류를 유발하는 버그가 될 수 있음
  • 모델의 성능 문제보다 데이터 격리 실패가 더 큰 원인임
  • 도메인 격리와 인간의 검토 경로(Human review path)가 필수적임
  • 단일 에이전트 패턴 대신 명확한 경계가 있는 아키텍처가 필요함

저는 치과 병원 대시보드에 관한 r/openclaw의 짧은 스레드를 읽었고, 장부 정리와 관련된 갈등이 있을 것이라 예상했습니다.

하지만 실제로 그 내용은 꽤 견고한 시스템 설계 (Systems Design) 교훈을 담고 있었습니다:

만약 하나의 상시 가동 에이전트 (Always-on agent)가 동일한 워크스페이스 내에서 당신의 개인 계좌, 임대 부동산 계좌, 그리고 사업용 계좌를 모두 볼 수 있다면, 당신의 재무 자동화는 이미 잘못된 결정으로 가는 길에 들어선 것입니다.

OpenClaw가 고장 났기 때문이 아닙니다.
GPT-5.4나 Claude Opus 4.6이 재무 업무에 서툴기 때문도 아닙니다.
공유된 컨텍스트 (Shared context)가 바로 버그이기 때문입니다.

해당 스레드는 익숙한 실패 모드(Failure mode)로 시작되었습니다: QuickBooks 데이터에 혼합된 은행 거래 내역, 하나의 거대한 테이블, 그리고 송장 (Invoice)을 입금 내역과 강제로 매칭시키려는 에이전트의 조합이었습니다.

그 설정은 빠르게 무너졌습니다.

문제를 해결한 것은 훨씬 더 지루한 것들이었습니다:

  • 무엇이 병원 관련 사항인지 정의할 것
  • 서로 다른 기록을 직접 매칭 가능한 것으로 취급하지 말 것
  • 도메인 (Domain)을 격리할 것
  • 불일치 사항에 대해 인간의 검토 경로 (Human review path)를 추가할 것

이것은 프롬프트 트릭 (Prompt trick)이 아닙니다.
이것은 아키텍처 (Architecture)입니다.

진짜 문제: 혼합된 재무 컨텍스트로부터 오는 가짜 확신

스레드에서 읽은 한 문장이 머릿속을 떠나지 않았습니다:

결국 효과가 있었던 것은 "병원 관련"이 무엇을 의미하는지 매우 구체적으로 정의하고, 불일치하는 항목을 강제로 조정(Reconcile)하려고 시도하는 대신 플래그(Flag)를 표시하도록 지시하는 것이었습니다.

정확히 맞습니다.

많은 에이전트 빌더 (Agent builders)들은 모델이 혼란을 겪기 때문에 재무 자동화가 실패한다고 가정합니다.

때로는 실제로 그렇습니다.

하지만 더 빈번하게는, 모델이 당신이 요청한 것을 정확히 수행하고 있을 뿐입니다:

  • 반쯤 관련된 재무 기록 더미를 가져와서
  • 그것들이 하나의 일관된 흐름에 속하는 것처럼 가장하고
  • 소스 시스템 (Source systems) 간에 의견이 일치하지 않더라도 깔끔한 답변을 생성하는 것

이것이 바로 '확신에 찬 헛소리 (Confident nonsense)'가 발생하는 방식입니다.

QuickBooks의 미수금 (Receivables)은 은행 입금액과 같은 것이 아닙니다.

치과 병원 사례에서, QuickBooks는 보험사가 지급해야 할 금액을 추적했습니다. 은행 피드 (Bank feed)는 조정 후 실제로 입금된 금액을 추적했습니다. 만약 당신의 에이전트가 이 둘을 서로 교체 가능한 것으로 취급한다면, 에이전트는 깔끔해 보이지만 완전히 틀린 매칭을 기꺼이 만들어낼 것입니다.

엉망인 결과물은 짜증을 유발합니다.
깔끔하지만 틀린 결과물은 위험합니다.

단일 에이전트 패턴이 프로덕션(production)에서 실패하는 이유

유혹은 명백합니다.

하나의 워크스페이스 (workspace).
하나의 메모리 (memory).
하나의 거대한 프롬프트 (prompt).
기존 SDK 코드가 그대로 작동할 수 있도록 하는 하나의 OpenAI 호환 엔드포인트 (endpoint).

당신은 나중에 경계(boundaries)를 추가하겠다고 스스로에게 다짐합니다.

하지만 대개 그렇게 하지 않습니다.

단일 금융 에이전트 (single finance agent) 패턴이 저지르기 쉬운 실수들은 다음과 같습니다:

  1. 한 계좌의 라벨 (labels)을 다른 계좌에서 재사용합니다.
  2. 민감한 컨텍스트 (context)를 그것이 전혀 필요하지 않은 작업으로 유출합니다.
  3. 서로 다른 회계 상태 (accounting states)의 기록들을 일치시키려 시도합니다.
  4. 모든 결정이 공유 메모리 (shared memory)에서 나왔기 때문에 감사 (audit)하기가 매우 고통스러워집니다.

만약 하나의 에이전트가 동일한 컨텍스트 윈도우 (context window) 내에서 개인 지출, 임대 수입, 급여, 그리고 사업상 미수금을 모두 보았다면, 이후의 모든 분류 (classification) 작업은 조금씩 나빠집니다.

이것은 LLM의 문제가 아닙니다.
이것은 경계 (boundary)의 문제입니다.

실제로 작동하는 패턴: 3개의 워크스페이스 + 1개의 오케스트레이터 (orchestrator)

해당 스레드에서 가장 훌륭한 댓글은 기본적으로 하나의 미니 설계 문서 (design doc)와 같았습니다:

3개의 스트림 (streams): 개인 재무, 임대 부동산 재무, 법인 재무. 나는 각각을 위해 별도의 에이전트 워크스페이스 (agent workspace)를 가지고 있으며, 모든 것을 격리하여 유지합니다. 나의 메인/오케스트레이팅 (orchestrating) 에이전트는 적절하게 위임할 수 있는 지침 (instructions)과 지능을 갖추고 있습니다.

그것이 바로 제가 신뢰할 수 있는 패턴입니다.

전지전능한 단 하나의 금융 봇이 아닙니다.
경계가 설정된 세 개의 워크스페이스와 하나의 오케스트레이터입니다.

다음과 같이 말이죠:

Workspace A: 개인 재무
Workspace B: 임대 부동산 재무
Workspace C: 법인 재무
...

그리고 라우팅 (routing) 규칙은 간단합니다:

요청에 혼합된 출처의 금융 기록이 포함된 경우:
- 먼저 금융 도메인 (financial domain)을 식별할 것
- 검색 (retrieval)을 해당 워크스페이스로만 제한할 것
...

이것은 하나의 슈퍼 에이전트 (super-agent)라는 환상보다 덜 마법 같지만,

훨씬 더 안전합니다.

레드액션 우선 (redaction-first) 단계는 대부분의 사람들이 깨닫는 것보다 더 많은 일을 수행합니다

스레드의 또 다른 유용한 댓글에 따르면, 첫 번째 에이전트는 어떤 데이터도 QuickBooks 매칭 (matching)에 닿기 전에 행(row)을 레드액션 (redact, 비식별화)하고 라벨링 (label)하는 일 외에는 아무것도 해서는 안 된다고 했습니다.

그렇습니다.

그것이 바로 사람들이 빠르게 진행하려 할 때 건너뛰는 부분입니다.

대부분의 재무 자동화 (finance automations)가 실패하는 이유는 첫 번째 단계에서 너무 많은 일을 하려고 하기 때문입니다:

  • 가공되지 않은 내역 (raw exports) 수집
  • 내역 해석
  • 대조 (reconcile)
  • 설명
  • 어쩌면 검토자 노트 초안 작성까지

이것은 게으른 파이프라인 설계 (pipeline design)입니다.

더 안전한 버전은 단계별로 진행됩니다.

더 안전한 재무 파이프라인

가공되지 않은 내역 (raw export) -> 비식별화 (redact) -> 분류 (classify) -> 대조 (reconcile) -> 검토 (review)

더 구체적으로는 다음과 같습니다:

  1. 가공되지 않은 은행 또는 카드 내역을 수집합니다.
  2. 민감한 필드를 비식별화 (redact) 합니다.
  3. 각 행을 정확히 하나의 도메인 (domain)으로 라벨링합니다.
  4. 도메인과 관련된 기록만을 QuickBooks와 비교합니다.
  5. 불일치하는 항목은 사람이 검토할 수 있도록 플래그 (flag)를 표시합니다.

이 비식별화 (redaction) 단계는 매우 중요합니다.

만약 가공되지 않은 내역에 계좌 번호, 개인적인 메모, 의료 관련 정보, 배우자의 구매 내역 또는 관련 없는 사업 세부 정보가 포함되어 있다면, 이 정보들은 대조 (reconciliation) 단계에서 반드시 필요한 경우가 아닌 한 노출되어서는 안 됩니다.

광범위한 가공되지 않은 컨텍스트 (raw context)가 공유 워크스페이스 (shared workspace)에 들어오는 순간, 당신은 이미 깨끗한 경계 (clean boundary)를 잃은 것입니다.

이제 당신의 대조 (reconciliation) 문제는 곧 개인정보 보호 (privacy) 문제로 변합니다.

구체적인 구현 스케치

만약 제가 오늘 실제 워크플로우에서 이를 구축한다면, 다음과 같이 구조를 잡을 것입니다.

1) 오케스트레이터 (Orchestrator)가 도메인을 결정

from typing import Literal

Domain = Literal["personal", "rental", "business", "unknown"]
...

운영 환경 (production)에서는 키워드 규칙보다 더 나은 분류 (classification) 방식을 사용하십시오.
하지만 원칙은 동일합니다: 먼저 라우팅 (route)하고, 나중에 검색 (retrieve)하십시오.

2) 대조 전 비식별화 (Redact before reconciliation)

import re

def redact_row(row: dict) -> dict:
...

3) 동일한 유형의 기록만 대조

def can_compare(record_a: dict, record_b: dict) -> bool:
    return (
        record_a.get("domain") == record_b.get("domain") and
...

마지막 체크 단계가 바로 많은 잘못된 자동화들이 오류를 범하는 지점입니다.

송장 (invoice)은 입금 (deposit)이 아닙니다.
미수금 (receivable)은 결제된 현금 (settled cash)이 아닙니다.
대기 중인 보험금 지급 (pending insurance payment)은 은행 거래 (bank transaction)가 아닙니다.

만약 당신의 에이전트 (agent)가 이러한 차이점을 건너뛴다면, 가짜 일치 항목 (fake matches)을 만들어낼 것입니다.

예시: QuickBooks 송장을 은행 입금과 직접 비교하지 마세요

이것이 바로 데모에서는 똑똑해 보이지만, 나중에 고통을 유발하는 전형적인 버그의 유형입니다.

잘못된 로직:

# 잘못됨: 서로 다른 레코드 유형 간에 금액만으로 매칭
if qb_invoice["amount"] == bank_txn["amount"]:
    return "matched"

더 안전한 로직:

def reconcile(qb_record: dict, bank_record: dict) -> str:
    if qb_record["record_type"] != "receivable":
        return "skip"
...

지루한 답변이 종종 정답인 경우가 많습니다:

명시적인 조정 로직 (adjustment logic)이 없다면, 자동으로 매칭하지 마세요.
검토 (review) 단계로 보내세요.

n8n 또는 Make에서의 모습

이 패턴은 자동화 도구에 깔끔하게 매핑됩니다.

n8n 형태

Webhook / Schedule
  -> Fetch export
  -> Redaction node
...

Make 형태

Scheduler
  -> Download CSV / API records
  -> Text parser / code module for redaction
...

이 지점이 바로 팀들이 비용 문제도 목격하기 시작하는 지점입니다.

왜냐하면 더 안전한 설계는 보통 다음과 같은 의미이기 때문입니다:

  • 더 많은 분류 호출 (classification calls)
  • 더 많은 검토 단계 (review passes)
  • 더 많은 재시도 (retries)
  • 더 많은 위임된 에이전트 단계 (delegated agent steps)

그것은 좋은 아키텍처 (architecture)입니다.
하지만 토큰당 과금 방식 (per-token pricing)은 이를 처벌합니다.

아키텍처를 수정한 후 비용 예측 가능성이 더 중요한 이유

이것이 사람들이 놓치는 반전입니다.

재무적 리스크를 줄이는 아키텍처는 종종 자동화 활동을 증가시킵니다.

만약 하나의 위험한 워크플로우 (workflow)를 다음과 같이 나눈다면:

  • 오케스트레이터 (orchestrator)
  • 3개의 도메인 에이전트 (domain agents)
  • 비식별화 단계 (redaction step)
  • 불일치 검토 루프 (mismatch review loop)
  • 불확실한 분류에 대한 재시도 (retries for uncertain classifications)

...당신은 이제 더 안전한 시스템과 더 많은 LLM 호출을 갖게 됩니다.

이것이 바로 에이전트 워크플로우에 정액제 컴퓨팅 (flat-rate compute)이 유용한 정확한 이유입니다.

만약 n8n, Make, Zapier, OpenClaw 또는 커스텀 워커 (custom workers)를 통해 상시 가동 자동화를 실행하고 있다면, 각 호출이 과금되는 것처럼 느껴져서 엔지니어들이 모든 추가 검토 단계를 의심하며 주저하게 만들고 싶지는 않을 것입니다.

이것이 Standard Compute가 가진 실질적인 매력입니다. 이는 고정된 월간 요금제를 제공하는 OpenAI API의 즉시 교체 가능한 (drop-in) 대체제이므로, 토큰 비용을 제어하기 위해 모든 과정을 하나의 위험한 프롬프트로 압축하는 대신 더 안전한 다단계 워크플로우 (multi-step workflow)를 유지할 수 있습니다.

OpenAI 호환 클라이언트를 그대로 유지하세요.
백그라운드 에이전트 (background agent) 호출 하나하나에 집착하는 것을 멈추세요.
신중함을 기할 여유가 생깁니다.

이는 단계가 더 많을수록 안전한 시스템이 되는 재무 워크플로우 (finance workflows)에서 매우 중요한 요소입니다.

빠른 비교

접근 방식실제로 일어나는 일
모든 계좌 접근 권한을 가진 단일 재무 에이전트설정은 빠르지만, 개인, 임대, 비즈니스 컨텍스트가 뒤섞이며 감사 (auditing) 과정이 순식간에 엉망이 됨
...

내가 배포한다면

제가 시작할 프로덕션 패턴 (production pattern)은 다음과 같습니다:

orchestrator:
  job: 재무 도메인별 요청 라우팅
  can_access: 메타데이터만 접근 가능
...

영리하지는 않습니다.
하지만 신뢰할 수 있습니다.

이 패턴을 로컬에서 테스트하고 싶다면

작은 Python 서비스로 워크플로우를 스텁 (stub) 처리하여 기존의 OpenAI SDK 구조를 유지할 수 있습니다.

mkdir finance-agent-boundaries
cd finance-agent-boundaries
python -m venv .venv
...

그 다음 구축하세요:

  • 하나의 라우터 엔드포인트 (router endpoint)
  • 하나의 비식별화 워커 (redaction worker)
  • 도메인당 하나의 대조 워커 (reconciliation worker)
  • 하나의 검토 큐 싱크 (review queue sink)

만약 여러분의 스택이 이미 OpenAI 호환 API와 통신하고 있다면, 엔드포인트를 교체하는 것은 쉽습니다. 이는 SDK 코드는 유지하면서, 추가적인 안전 단계를 거칠 때마다 발생하는 토큰당 비용 지불을 중단하고 싶을 때 유용합니다.

월요일에 해야 할 일

만약 현재 하나의 에이전트가 여러분이 가진 모든 재무 계좌에 접근하고 있다면, 프롬프트 튜닝 (prompt tuning)부터 시작하지 마세요.

경계 (boundaries) 설정부터 시작하세요.

  1. 개인, 임대, 비즈니스 워크플로우를 별도의 워크스페이스 (workspaces)로 분리하세요.
  2. 그 앞에 오케스트레이터 (orchestrator)를 배치하세요.
  3. 비식별화 우선 (redaction-first) 전처리 단계를 추가하세요.
  4. 실제 조정 로직 (adjustment logic)이 없다면, QuickBooks 인보이스와 은행 입금액을 서로 다른 레코드 유형으로 취급하세요.
  5. 에이전트에게 일치 여부를 강제하는 대신, 불일치 사항을 플래그 (flag)하도록 지시하세요.

그것이 바로 그 치과 운영 관련 스레드(thread)에서 얻은 진짜 교훈이었습니다.

AI로 어떻게 장부 기입 (bookkeeping)을 하는지에 대한 것이 아닙니다.

재무 자동화 (finance automation)가 확신에 찬 상태로 틀린 답을 내놓는 상황을 어떻게 방지할 것인가에 대한 것입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0