구글 LangExtract와 오픈AI로 구축하는 문서 지능 파이프라인
구글의 LangExtract 라이브러리와 오픈AI 모델을 활용하여 비정형 텍스트를 기계가 읽을 수 있는 구조화된 데이터로 변환하는 방법을 다루는 실전 튜토리얼입니다. 계약서, 회의록 등 다양한 문서에서 엔티티와 리스크를 추출하고, 이를 대화형으로 시각화하여 분석 및 업무 자동화 파이프라인에 활용할 수 있는 점이 핵심입니다. 개발자와 데이터 실무자들에게 매우 유용한 가이드라인을 제공합니다.
에디터 추천 | 에이전틱 AI | 기술 | 인공지능 | 언어 모델 | OCR | 스태프 | 튜토리얼
이 튜토리얼에서는 구글의 LangExtract 라이브러리를 사용하여 비정형 텍스트를 기계가 읽을 수 있는 구조화된 정보로 변환하는 방법을 알아봅니다. 먼저, 추출 작업을 위해 강력한 언어 모델을 활용할 수 있도록 필요한 종속성(dependencies)을 설치하고 OpenAI API 키를 안전하게 구성합니다. 또한 계약서, 회의록, 제품 공지사항 및 운영 로그를 포함한 다양한 문서 유형을 처리할 수 있는 재사용 가능한 추출 파이프라인을 구축할 것입니다.
신중하게 설계된 프롬프트와 예시 어노테이션을 통해 LangExtract가 엔티티(Entity), 작업(Action), 마감일(Deadline), 리스크(Risk) 및 기타 구조화된 속성을 식별하고 이를 원본 텍스트의 정확한 위치(Source span)와 매핑하는 방법을 시연합니다. 또한 추출된 정보를 시각화하고 테이블 형태의 데이터셋으로 구성하여 다운스트림 분석, 자동화 워크플로우 및 의사결정 시스템에서 활용할 수 있도록 합니다.
코드 복사 !pip -q install -U "langextract[openai]" pandas IPython
import os import json import textwrap import getpass import pandas as pd
OPENAI_API_KEY = getpass.getpass("OPENAI_API_KEY를 입력하세요: ") os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
import langextract as lx from IPython.display import display, HTML
구조화된 추출 작업을 위해 Colab 환경을 준비하기 위해 LangExtract, Pandas, IPython 등 필요한 라이브러리를 설치합니다. 런타임 중 안전한 액세스를 위해 사용자로부터 OpenAI API 키를 안전하게 요청하고 이를 환경 변수로 저장합니다. 그런 다음 LangExtract를 실행하고, 결과를 표시하며, 구조화된 출력을 처리하는 데 필요한 핵심 라이브러리를 가져옵니다(import).
코드 복사 MODEL_ID = "gpt-4o-mini"
def run_extraction( text_or_documents, prompt_description, examples, output_stem, model_id=MODEL_ID, extraction_passes=1, max_workers=4, max_char_buffer=1800, ): result = lx.extract( text_or_documents=text_or_documents, prompt_description=prompt_description, examples=examples, model_id=model_id, api_key=os.environ["OPENAI_API_KEY"], fence_output=True, use_schema_constraints=False, extraction_passes=extraction_passes, max_workers=max_workers, max_char_buffer=max_char_buffer, )
jsonl_name = f"{output_stem}.jsonl"
html_name = f"{output_stem}.html"
lx.io.save_annotated_documents([result], output_name=jsonl_name, output_dir=".")
html_content = lx.visualize(jsonl_name)
with open(html_name, "w", encoding="utf-8") as f:
if hasattr(html_content, "data"):
f.write(html_content.data)
else:
f.write(html_content)
return result, jsonl_name, html_name
def extraction_rows(result): rows = [] for ex in result.extractions: start_pos = None end_pos = None if getattr(ex, "char_interval", None): start_pos = ex.char_interval.start_pos end_pos = ex.char_interval.end_pos
rows.append({
"class": ex.extraction_class,
"text": ex.extraction_text,
"attributes": json.dumps(ex.attributes or {}, ensure_ascii=False),
"start": start_pos,
"end": end_pos,
})
return pd.DataFrame(rows)
def preview_result(title, result, html_name, max_rows=50): print("=" * 80) print(title) print("=" * 80) print(f"총 추출 수: {len(result.extractions)}")
df = extraction_rows(result)
display(df.head(max_rows))
display(HTML(f'<p><a href="{html_name}" target="_blank">대화형 시각화 열기: {html_name}</a></p>'))
전체 추출 파이프라인을 구동하는 핵심 유틸리티 함수들을 정의합니다. 텍스트를 LangExtract 엔진으로 보내 JSONL 및 HTML 출력을 모두 생성하는 재사용 가능한 run_extraction 함수를 만듭니다. 또한 추출 결과를 테이블 형식의 행으로 변환하고 노트북 환경에서 대화형으로 미리 볼 수 있는 헬퍼 함수도 정의합니다.
코드 복사 contract_prompt = textwrap.dedent(""" 나타나는 순서대로 계약-위험(contract-risk) 정보를 추출합니다. 규칙: 1. 소스의 정확한 텍스트 범위를 사용하세요. extraction_text를 바꾸지 마세요. 2. 존재하는 경우 다음 클래스를 추출하세요: - party (당사자) - obligation (의무) - deadline (마감일) - payme... (결제/지불)