CrewAI 에이전트가 중복 작업을 실행하지 않도록 하는 방법: 실용적인 중복 제거 가이드
CrewAI 에이전트가 작업을 반복하지 않도록 하려면 작업 소유권, 종속성, 위임, 재시도, Flow 트리거, 상태 지속성, 캐싱 및 멱등성을 수정하십시오.
가장 신뢰할 수 있는 로컬 PDF 추출 워크플로우는 일반적으로 단일 AI 프롬프트가 아닌 파이프라인입니다: 먼저 PDF에서 신뢰할 수 있는 텍스트와 레이아웃을 복원한 다음, 로컬 모델에게 해당 내용을 엄격한 스키마로 매핑하도록 요청하고, 마지막으로 저장하기 전에 필드를 검증합니다. 모든 PDF 페이지를 직접 비전 모델로 보내는 것은 작동할 수 있지만, 네이티브 PDF 텍스트나 OCR로 충분할 경우보다 종종 더 느리고, 하드웨어 집약적이며, 감사하기가 더 어렵습니다.
이 구분이 중요한 이유는 당신의 목표가 “클라우드 API 없음”이기 때문입니다. 문서 내용을 호스팅된 서비스로 보내지 않고도 자체 머신에서 로컬 API를 사용할 수 있습니다. 예를 들어, localhost의 Ollama HTTP 엔드포인트를 사용할 수 있습니다. Ollama는 모델이 로컬에서 실행될 때 프롬프트와 응답이 Ollama로 다시 전송되지 않는다고 명시하며, 클라우드 기능을 비활성화하는 로컬 전용 모드를 제공합니다. Docling 역시 기본적으로 원격 서비스를 비활성화하지만, 오프라인 사용을 위해 사전에 가져오지 않는 한 설정 중에 모델 파일이 다운로드될 수 있습니다.
적절한 스택은 PDF에 따라 다릅니다. 선택 가능한 텍스트가 포함된 태생 디지털(born-digital) 인보이스는 스캔된 영수증, 복잡한 재무 표 또는 이미지 중심의 양식과 다른 접근 방식이 필요합니다. 이 가이드는 이러한 옵션들을 비교하고 인보이스, 계약서, 구매 주문서, 신청서, 보고서 및 기타 반복적인 문서에 적용할 수 있는 4단계 자동화 패턴을 제공합니다.
| PDF 유형 | 실용적인 로컬 파이프라인 | 주요 이점 | 주요 트레이드오프 |
|---|---|---|---|
| 깨끗한 선택 가능한 텍스트가 있는 태생 디지털 PDF | PyMuPDF → 로컬 텍스트 LLM → JSON 검증 | 빠르고 상대적으로 하드웨어 부하가 적음 | 단순 추출은 읽기 순서나 표 관계를 손실할 수 있음 |
| 단순 페이지가 있는 스캔된 PDF | OCRmyPDF/Tesseract → PyMuPDF → 로컬 텍스트 LLM | AI 추출 전에 페이지 이미지를 검색 가능한 텍스트로 변환 | OCR 오류가 모델 입력 오류가 됨 |
| 텍스트, 스캔 및 표가 혼합된 PDF | skip/redo 모드의 Docling 또는 OCRmyPDF → 로컬 LLM | 혼합 콘텐츠 및 문서 구조에 대한 더 나은 제어 | 더 많은 의존성 및 처리 시간 |
| 레이아웃 중심의 양식, 표, 다이어그램 또는 시각적으로 의미 있는 페이지 | Docling 로컬 파이프라인 또는 로컬 비전 모델 → 구조화된 출력 | 더 많은 시각/레이아웃 컨텍스트 보존 | 일반적으로 더 많은 컴퓨팅 자원과 더 강력한 검증이 필요함 |
보편적인 승자는 없습니다. 문서가 예측 가능하고 임베디드 텍스트를 포함하는 경우, 파서와 작은 로컬 언어 모델이 비용, 속도 및 재현성 측면에서 훨씬 큰 비전 워크플로우보다 성능이 좋을 수 있습니다. 텍스트의 위치가 의미의 일부인 경우(예: 병합된 셀이 있는 표나 레이블과 값이 공간적으로 짝을 이루는 양식) 레이아웃 인식 처리가 더 가치 있게 됩니다.
문서에 이미 사용 가능한 텍스트가 포함되어 있는지 확인하는 것부터 시작하세요. 태생 디지털(Born-digital)은 PDF가 소프트웨어에서 생성되었으며 일반적으로 선택하고 복사할 수 있는 텍스트 객체를 포함함을 의미합니다. 스캔된 PDF는 페이지 이미지만 포함할 수 있으므로 일반 텍스트 파서는 거의 또는 전혀 반환하지 않습니다.
PyMuPDF의 공식 문서는 page.get_text()를 사용한 직접 텍스트 추출을 보여줍니다. 최소한의 로컬 테스트는 다음과 같습니다:
import pymupdf
def extract_native_text(pdf_path: str) -> str:
pages = []
with pymupdf.open(pdf_path) as doc:
for page in doc:
pages.append(page.get_text())
return "\f".join(pages)
text = extract_native_text("invoice.pdf")
print(text[:1000])
공식 PyMuPDF 기본 사항을 참조하세요. PyMuPDF는 또한 일반 PDF 텍스트가 자연스러운 읽기 순서로 나타나지 않거나 예상치 못한 줄 바꿈을 포함할 수 있다고 경고합니다. 이는 파서의 제한 사항이며 반드시 AI 문제는 아닙니다.
최적의 적합성: 텍스트 복사/붙여넣기가 이미 작동하고 인접한 레이블에서 필드를 쉽게 식별할 수 있는 인보이스, 명세서, 보고서 및 양식.
주의할 점: 페이지에는 작은 텍스트 레이어와 큰 스캔된 이미지가 모두 포함될 수 있습니다. 따라서 “일부 텍스트가 존재하는지” 단순히 확인하는 것은 완벽한 스캔 감지기가 아닙니다. 프로덕션 자동화를 위해 하나의 보편적인 문자 수 임계값에 의존하는 대신 대표 문서를 검사하세요.
조치: 20~50개의 대표 PDF를 가져와 태생 디지털, 스캔, 혼합 및 레이아웃 중심 그룹으로 분류하세요. 파이프라인은 파일 확장자뿐만 아니라 문서 동작에 따라 라우팅해야 합니다.
텍스트 레이어가 신뢰할 수 있다면 직접 추출이 일반적으로 가장 간단한 경로입니다. 이는 OCR 지연을 피하고 이미 올바르게 인코딩된 텍스트에 OCR 문자 오류를 도입하지 않습니다. 긴 문서의 경우 페이지 구분자를 유지하고 전체 문서를 한 번에 모델에 전달하는 대신 페이지 그룹이나 논리적 섹션을 처리할 수 있습니다.
트레이드오프: 일반 텍스트는 저렴하고 빠르지만, 표, 다중 열 페이지, 헤더, 푸터 및 읽기 순서는 추가 처리가 필요할 수 있습니다. 이러한 관계가 대상 필드에 중요하다면, 빈약한 소스 텍스트에 프롬프트 지시를 쌓는 대신 레이아웃 인식 표현으로 이동하세요.
Tesseract는 오픈 소스 OCR 엔진입니다. 현재 사용자 매뉴얼은 5.x 시리즈와 별도의 학습된 데이터 파일을 통한 많은 언어 지원을 문서화합니다. OCRmyPDF는 PDF 특정 처리를 둘러싸 OCR을 래핑하여 스캔된 페이지가 검색 가능한 텍스트 레이어를 얻을 수 있도록 합니다.
일부 페이지에 이미 텍스트가 포함된 혼합 문서의 경우, 현재 OCRmyPDF 버전은 skip 모드를 지원합니다:
ocrmypdf --mode skip input.pdf searchable.pdf
공식 OCRmyPDF 고급 문서는 --mode skip이 기존 텍스트가 있는 페이지는 그대로 두고 필요한 페이지에만 OCR을 적용한다고 설명합니다. 동일한 문서는 이전에 감지된 OCR을 대체하기 위한 redo와 모든 콘텐츠를 래스터화하고 OCR하기 위한 force를 설명합니다. 래스터화는 벡터 이점을 폐기하고 대화형 콘텐츠를 평면화할 수 있으므로 force는 신중하게 사용하세요.
Tesseract 설치, 언어 및 명령줄 동작의 경우 공식 Tesseract 사용자 매뉴얼을 사용하세요. OCR 언어가 중요합니다. 예를 들어 인보이스에 영어와 독일어가 포함되어 있다면, 기본 영어 모델이 둘 다 동일하게 잘 처리할 것이라고 가정하는 대신 적절한 언어 데이터를 설치하고 구성하세요.
Docling은 레이아웃, 표, OCR 및 로컬 비전-언어 처리 옵션을 사용하여 문서 변환을 위해 설계되었습니다. 프로젝트 문서는 민감하고 공기 갭(air-gapped) 워크플로우를 위한 로컬 실행을 염두에 두고 고급 PDF 이해, 표 구조, OCR 및 무손실 JSON/Markdown 스타일 출력을 나열합니다.
기본 Python 변환은 다음과 같이 작을 수 있습니다:
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
doc = converter.convert("input.pdf").document
markdown = doc.export_to_markdown()
structured = doc.export_to_dict()
공식 Docling 빠른 시작을 참조하세요. Docling은 또한 로컬 VLM 파이프라인과 여러 OCR 백엔드를 지원합니다. 고급 옵션은 원격 서비스 호출이 명시적인 옵트인을 필요로 하는 반면, 모델 아티팩트는 오프라인 사용을 위해 사전 가져올 수 있다고 설명합니다.
최적의 적합성: 복잡한 표, 제목, 다중 열 보고서, 혼합 스캔 또는 일반 텍스트 덤프 대신 재사용 가능한 문서 표현을 원하는 경우.
트레이드오프: 파이프라인은 간단한 PDF 파서보다 무겁습니다. 더 많은 구성 요소를 가지고 있기 때문이 아니라, 추가 구조가 추출 정확도를 향상시키기 때문에 사용하세요.
조치: 대상 스키마가 필요로 하는 정보를 보존하는 가장 가벼운 추출 방법을 선택하세요. 깨끗한 임베디드 텍스트에 OCR을 적용하지 말고, 레이아웃이 의미를 결정할 때 레이아웃을 버리지 마세요.
신뢰할 수 있는 소스 콘텐츠를 확보했으면, 로컬 모델을 잘하는 데 사용하세요: 의미적 매핑. “이 인보이스에서 모든 것을 추출하세요”라고 묻는 대신, 실제로 필요한 필드를 정의하세요.
예를 들어:
from pydantic import BaseModel
from typing import Optional
class LineItem(BaseModel):
description: str
quantity: Optional[float]
unit_price: Optional[float]
amount: Optional[float]
class Invoice(BaseModel):
invoice_number: Optional[str]
invoice_date: Optional[str]
vendor_name: Optional[str]
currency: Optional[str]
subtotal: Optional[float]
tax: Optional[float]
total: Optional[float]
items: list[LineItem]
Ollama의 현재 구조화된 출력 문서는 format 필드를 통해 JSON 스키마를 전달하고 Pydantic으로 응답을 검증하는 것을 지원합니다. 로컬 호출은 다음과 같이 보일 수 있습니다:
from ollama import chat
schema = Invoice.model_json_schema()
prompt = f"""
Extract the invoice into the supplied schema.
Rules:
- Use only information present in the source.
- Use null when a field is not found.
- Do not infer missing invoice numbers, dates, tax, or totals.
- Preserve line items individually.
SOURCE:
{text}
"""
response = chat(
model="gpt-oss",
messages=[{"role": "user", "content": prompt}],
format=schema,
options={"temperature": 0},
)
invoice = Invoice.model_validate_json(response.message.content)
이것은 더 결정적인 구조화된 완성을 위해 재사용 가능한 스키마와 0과 같은 낮은 온도를 권장하는 Ollama의 공식 구조화된 출력 문서의 패턴을 따릅니다.
위의 모델 이름은 Ollama 자체 구조화된 출력 문서의 예시이며, 모든 추출 작업에 대해 최상의 모델이라는 주장이 아닙니다. 레이블이 명확한 반복적인 인보이스의 경우 더 작은 모델이 충분할 수 있습니다. 모호한 계약서나 일관되지 않은 레이아웃의 경우 더 강력한 모델이 도움이 될 수 있지만 일반적으로 더 많은 메모리와 처리 시간이 필요합니다.
파서/OCR 출력이 이미 필요한 필드 관계를 보존하는 경우 텍스트 모델을 사용하세요. 시각적 위치가 필수적이거나 텍스트 변환이 일관되게 구조를 손실하는 경우 비전 지원 로컬 모델을 사용하세요. Ollama의 공식 비전 문서는 로컬 비전 모델에 대한 이미지 입력을 지원하며, 구조화된 출력 기능은 비전 지원 모델과 결합할 수 있습니다.
그러나 모든 페이지를 이미지로 렌더링하는 것은 트레이드오프를 변경합니다:
조치: 파서/OCR 텍스트와 스키마 제약이 있는 로컬 LLM으로 시작하세요. 모든 페이지에 비전 비용을 지불하는 대신 어려운 페이지 유형만 로컬 VLM으로 에스컬레이션하세요.
스키마가 유효한 JSON은 자동으로 사실적으로 정확하지는 않습니다. 모델은 잘못된 값으로 유효한 필드를 생성할 수 있습니다. 따라서 마지막 단계에서는 가능한 한 결정적인 검사를 사용해야 합니다.
인보이스의 경우 유용한 검사에는 다음이 포함됩니다:
03/04/26과 같은 모호한 문자열을 신뢰하는 대신 고정된 정책으로 날짜를 파싱하세요.기본적인 배치 구조는 추출과 검증을 분리할 수 있습니다:
from pathlib import Path
import json
for pdf_path in Path("inbox").glob("*.pdf"):
source_text = extract_native_text(str(pdf_path))
# If text is unusable, run your OCR or Docling branch here.
record = extract_with_local_model(source_text)
errors = validate_record(record)
if errors:
save_for_review(pdf_path, record, errors)
else:
output = Path("processed") / f"{pdf_path.stem}.json"
output.write_text(
json.dumps(record, ensure_ascii=False, indent=2),
encoding="utf-8"
)
헬퍼 함수는 인보이스, 계약서, 세금 양식, 실험실 보고서 및 구매 주문서 간에 검증 규칙이 극적으로 다르기 때문에 의도적으로 애플리케이션별로 남겨두었습니다. 보편적인 검증기는 잘못된 확신을 생성할 것입니다.
CSV 또는 Excel이 필요한 경우, 실제로 행과 열에 속하는 필드만 평탄화하세요. 반복되는 항목이 있는 문서의 경우, 모든 필드를 하나의 넓은 스프레드시트 행에 강제로 넣는 것보다 문서 ID로 연결된 문서 수준 표와 두 번째 항목 표를 만드는 것이 종종 더 깔끔합니다.
조치: 수천 개의 파일을 처리하기 전에 검증 규칙을 정의하세요. 레이블이 지정된 샘플 세트에 대해 테스트하고 “성공적으로 처리된 문서”뿐만 아니라 필드 수준 정확도를 기록하세요.
많은 소규모 및 중규모 자동화 작업의 경우, 이 책임 분리는 올인원 모델보다 유지 관리가 더 쉽습니다:
PDF inbox
|
+-- born-digital --> PyMuPDF -------------------+
| |
+-- scanned/mixed --> OCRmyPDF/Tesseract -------+--> normalized text/layout
| |
+-- layout-heavy --> Docling -------------------+
|
v
local LLM / VLM
|
JSON Schema
|
v
deterministic validation
|
+----------------------+----------------+
| | |
JSON CSV database
이 설계는 구성 요소를 독립적으로 교체할 수 있게 합니다. OCR 품질이 약하면 LLM을 재학습하지 않고 OCR 레이어를 개선하세요. 로컬 모델이 너무 느리면 PDF 파서를 변경하지 않고 더 작은 모델을 사용하세요. 한 공급업체의 인보이스에 특별한 표 처리가 필요한 경우, 해당 파일만 Docling 또는 비전 분기를 통해 라우팅하세요.
| 옵션 | 사용 시점 | 장점 | 트레이드오프 |
|---|---|---|---|
| Ollama | 가장 쉬운 로컬 모델 API와 스키마 제약 출력을 원할 때 | 간단한 localhost API, 구조화된 JSON, 호환 모델에 대한 비전 지원 | 추상화는 맨 추론 엔진보다 낮은 수준의 런타임 제어를 덜 제공합니다 |
| llama.cpp | 직접적인 GGUF 제어, 명령줄 배포 또는 가벼운 로컬 서버를 원할 때 | 로컬 CLI/서버 및 문법/JSON 스키마 제약 생성 | 더 많은 모델/런타임 세부 사항이 당신의 책임입니다 |
| Docling VLM | 주요 과제가 일반적인 채팅 스타일 추출이 아닌 문서 레이아웃 변환일 때 | Markdown/HTML/DocTags 스타일 출력이 있는 문서 중심 로컬 VLM 파이프라인 | 모든 비즈니스 규칙 추출 단계를 대체하는 것이 아니라 문서 변환 구성 요소로 생각하는 것이 가장 좋습니다 |
공식 llama.cpp 저장소는 로컬 llama-server와 문법 제약 생성을 문서화합니다. 현재 서버 코드는 또한 JSON 스키마 제약을 허용합니다. Docling의 비전 모델 문서는 문서 변환을 위한 로컬 VLM 옵션을 나열합니다.
모델 리더보드에만 기반하여 런타임을 선택하지 마세요. PDF 추출의 경우, 실용적인 측정 기준은 필드 정확도, 문서당 처리량, 머신의 메모리 사용량, 레이아웃에서의 실패율, 시작 복잡성 및 잘못된 결과를 쉽게 검사할 수 있는 능력입니다.
“클라우드 API 없음”은 마케팅 라벨이 아니라 검증할 수 있는 배포 속성이어야 합니다.
Ollama의 공식 FAQ는 로컬 프롬프트와 답변이 Ollama로 다시 전송되지 않는다고 말합니다. 또한 클라우드 비활성화 설정을 문서화합니다:
OLLAMA_NO_CLOUD=1
또는 동등한 disable_ollama_cloud 서버 설정입니다. Ollama의 로컬 API는 http://localhost:11434에서 실행되며, 인증 문서에 따르면 로컬 접근을 위해 인증이 필요하지 않습니다.
localhost에 바인딩된 서비스는 LAN에 노출된 서비스와 다르다는 점을 기억하세요. 바인딩 주소를 변경하거나 다른 서버 뒤에 배치하는 경우, 접근 제어는 당신의 책임입니다.
Docling은 기본적으로 원격 서비스 사용을 비활성화합니다. 문서화에서는 처리 프라이버시와 모델 획득을 구분합니다: 사전 다운로드하지 않는 한 모델은 첫 사용 시 가져올 수 있습니다. 공기 갭 시스템의 경우, 연결된 스테이징 머신에서 docling-tools models download를 사용하거나 승인된 모델 아티팩트를 사전에 준비한 다음 오프라인 환경을 해당 로컬 아티팩트 디렉토리로 지정하세요.
조치: 민감한 문서를 처리하기 전에 운영 체제 또는 네트워크 레이어에서 아웃바운드 네트워크 접근을 차단하고 연결을 모니터링하면서 테스트를 실행하세요. 애플리케이션 설정은 유용하지만, 네트워크 제어는 독립적인 검증 레이어를 제공합니다.
로컬에서 실행하면 데이터 제어 옵션이 개선되지만, 추출이 자동으로 정확하거나, 컴플라이언스를 준수하거나, 안전해지지는 않습니다. 로컬 파일은 여전히 디버그 로그, 임시 디렉토리, 백업, 공유 폴더, 과도하게 허용적인 서비스 또는 복사된 내보내기를 통해 유출될 수 있습니다. 로컬 모델은 호스팅 모델과 마찬가지로 값을 환각할 수도 있습니다.
은행 계좌 번호, 결제 지침, 계약 날짜, 의료 값 또는 규제 식별자와 같은 고영향 필드에 대해 모델을 유일한 검증자로 사용하지 마세요. 이러한 경우 소스 텍스트와 비교하고, 결정적 검증을 적용하며, 신뢰도가 불충분할 경우 인간 검토를 요구하세요.
실제로 받는 사례를 포함하는 작은 레이블이 지정된 평가 세트를 만드세요:
각 대상 필드에 대해 추출된 값을 정답(ground truth)과 비교하세요. 식별자에 대한 정확한 일치, 금액에 대한 숫자 허용 오차 및 항목에 대한 행 수준 정확도를 측정하세요. 또한 처리 시간과 수동 검토로 보내진 문서의 백분율을 기록하세요.
더 간단한 PyMuPDF-plus-LLM 경로가 필요한 정확도에 도달하면 그것을 유지하세요. 스캔이 주요 실패 원인이라면 OCR을 개선하세요. 표 관계가 문제라면 Docling을 테스트하세요. 시각적으로 배치된 필드가 여전히 어렵다면 해당 하위 집합을 로컬 비전 모델을 통해 라우팅하세요. 이 단계적 에스컬레이션은 일반적으로 모든 페이지에 가장 무거운 모델을 적용하는 것보다 속도와 하드웨어 사용에 대한 더 나은 제어를 제공합니다.
좋은 로컬 PDF 추출 시스템은 문서 읽기와 의미적 추출을 분리합니다. PDF에 이미 좋은 텍스트가 포함된 경우 PyMuPDF를 사용하세요. 페이지가 스캔된 경우 OCRmyPDF/Tesseract를 사용하세요. 구조와 표가 중요한 경우 Docling을 사용하세요. 비즈니스 스키마로 유연한 매핑이 필요한 경우 로컬 Ollama 또는 llama.cpp 모델을 사용하세요. 텍스트 파이프라인이 신뢰할 수 있게 보존할 수 없는 정보를 시각적 레이아웃이 추가하는 경우에만 로컬 비전을 사용하세요.
최종 요구 사항은 검증입니다. JSON 스키마는 모델 응답의 형태를 제약할 수 있지만, 금액, 날짜, 이름 또는 계좌 번호가 소스와 일치함을 증명할 수는 없습니다. 불확실한 문서가 보이고 검토 가능하도록 파이프라인을 설계하면, 문서를 클라우드 API에 넘기지 않고도 PDF 데이터 추출의 상당 부분을 자동화할 수 있으며, 로컬 AI가 품질 관리의 필요성을 제거한다고 가장하지 않을 수 있습니다.
CrewAI 에이전트가 작업을 반복하지 않도록 하려면 작업 소유권, 종속성, 위임, 재시도, Flow 트리거, 상태 지속성, 캐싱 및 멱등성을 수정하십시오.
미국 프리랜서 업무를 위한 독립 계약자 경비 추적기를 구축하세요. IRS 기준 카테고리, 영수증 기록, 2026년 마일리지 요율, 세무 검토 플래그를 포함합니다.
시간 계산기, 야간 근무 수식, 주간 합계, 품질 점검 및 명확한 한계를 갖춘 무료 직원 근무 일정표를 엑셀로 만들어 보세요.
테이블, 드롭다운, 후속 조치 알림, 간단한 파이프라인 요약 기능을 갖춘 실용적인 엑셀 리드 트래커를 구축하고, CRM으로 전환해야 할 시기를 판단하는 명확한 신호를 확인하세요.
서비스 이력, 마감일, 가동 중단 시간, 비용, 점검 기록 및 명확한 안전 경계를 포함하여 작업장 자산용 실용적인 엑셀 장비 유지보수 로그를 구축하세요.
개인 부동산 중개인을 위한 HubSpot 무료 CRM과 Zoho CRM 무료를 연락처 제한, 파이프라인, 이메일, 자동화, 모바일 도구 및 업그레이드 장단점 등을 기준으로 비교해 보세요.
LM Studio를 통해 Windows 11에서 DeepSeek을 로컬로 실행하세요. 일반 PC에 적합한 모델 선택법, 다운로드 및 로드 방법, 오프라인 사용 확인 및 일반적인 문제 해결 방법을 알아보세요.
4가지 실용적인 프롬프트 압축 기법, 캐시 친화적 레이아웃, 구조화된 출력, 품질 보존 평가 계획을 통해 LLM API 비용을 절감하세요.
셀프 호스팅 n8n과 Claude를 사용하여 무료 호스팅이 가능한 AI 콘텐츠 재활용 파이프라인을 구축하세요. 구조화된 출력, 검토 게이트 및 현실적인 API 비용 가이드를 포함합니다.
타임라인, 벤더 추적, 예상 비용 대 실제 비용, 결제 및 당일 작업을 포함한 Word용 실용적인 인쇄 가능한 이벤트 기획 체크리스트 및 예산 템플릿을 사용하세요.