Local LLM 구축하기 · 15/30 · API와 문서 검색
답변을 다음 프로그램에 넘기려면 사람이 읽기 좋은 문장만으로는 부족합니다. JSON 앞에 인사말이 붙어도 파서는 멈출 수 있어요. 형식을 지켰는지와 안에 담긴 값이 맞는지를 나눠 확인해 보겠습니다.
13편의 공용 함수를 사용합니다. JSON 문법, 필드의 자료형, 원문과의 일치 여부를 차례로 검사합니다.
JSON Schema 정의
Ollama의 format 필드에 JSON Schema를 전달하면 필요한 필드와 자료형을 지정할 수 있습니다. 프로그램이 읽을 형태를 얻는 데 도움이 돼요. 다만 원문에 없는 담당자나 날짜를 만들어 냈는지는 스키마만으로 판단할 수 없습니다.
찾지 못한 항목은 이 예제에서 null로 표시합니다. 빈 문자열과 구분해 두면 미기재 항목을 처리하기 편해요. 실제 업무 데이터에는 단위와 시간대, 날짜를 해석하는 기준도 함께 정의합니다.
추출값과 원문 대조
import json
from llm_http import post, MODEL
schema = {
"type": "object",
"properties": {
"time": {"type": ["string", "null"]},
"retention_days": {"type": ["integer", "null"]},
"owner": {"type": ["string", "null"]}
},
"required": ["time", "retention_days", "owner"],
"additionalProperties": False
}
response = post("/api/chat", {
"model": MODEL,
"messages": [{"role": "user", "content":
"메모: 백업은 매일 02시에 실행하고 14일 보관한다. "
"스키마에 맞춰 추출하라. 없는 값은 null. 스키마: " + json.dumps(schema)}],
"format": schema, "stream": False,
"options": {"temperature": 0, "num_ctx": 4096, "num_predict": 256}
})
data = json.loads(response["message"]["content"])
if set(data) != {"time", "retention_days", "owner"}:
raise ValueError("Unexpected fields")
if data["time"] != "02시" or type(data["retention_days"]) is not int:
raise ValueError("Check time format and number type")
if data["retention_days"] != 14 or data["owner"] is not None:
raise ValueError("Extracted facts do not match this sample")
print(json.dumps(data, ensure_ascii=False, indent=2))
.\.venv\Scripts\python.exe .\structured_demo.py
샘플의 “02시”는 형식까지 맞춰 보기 위해 정한 값입니다. 02:00이 나왔다면 사실이 틀린 경우와 표기만 다른 경우를 구분합니다. 운영 코드에서는 시간을 정규화한 뒤 비교할 수 있습니다. json.loads는 JSON 문법을 읽는 함수이며 JSON Schema 전체를 검증하지는 않습니다.
문법·스키마·업무 규칙 검사
| 검사 | 잡아낼 수 있는 문제 |
|---|---|
| JSON 파싱 | 닫히지 않은 괄호·설명문 혼입 |
| 스키마 검증 | 누락 필드·틀린 자료형·예상 밖 항목 |
| 업무 규칙 | 보관 기간이 음수·허용 범위 초과 |
| 원문 대조 | 담당자 지어내기·숫자 오독 |
아래 코드는 작은 샘플의 필드와 원문 사실을 직접 검사합니다. 복잡한 앱이라면 jsonschema 같은 라이브러리의 검사와 업무 규칙 검사를 분리해 두는 편이 관리하기 좋아요. 모델의 결과를 저장하거나 명령으로 바꾸기 전에 검증을 통과시킵니다.
검증 실패와 재시도 제한
검증이 실패하면 입력이 모호한지, 모델에 너무 많은 일을 맡겼는지 살펴봅니다. 실패 이유를 알려 다시 요청할 수 있지만 횟수와 시간을 제한합니다. 끝까지 확인되지 않은 값은 자동 저장하지 않고 수동 검토 대상으로 남깁니다.
작은 모델에 복잡한 객체를 한 번에 요구하면 누락이 생길 수 있어요. 문서별 항목 추출과 최종 조립을 나누는 방법도 있습니다. 이 경우 문서 ID와 근거 위치를 함께 보관해 서로 다른 원문의 값이 섞이지 않게 합니다.
참고 자료
문서·모델 태그 확인 기준: 2026년 10월 18일. 기본 실습 환경: Windows 11 x64.




답글 남기기