This commit is contained in:
LASTA_DEV01\lasta
2026-05-13 19:57:34 +09:00
parent 2e9204243d
commit 9e88f4c7ad
4310 changed files with 48538 additions and 905279 deletions

View File

@@ -0,0 +1,586 @@
# Instructor 분석 및 범용 온톨로지 구축 플랫폼 기능명세 - 2순위 검토
## 1. 분석 대상
- 원본 경로: `C:\Users\lasta\MyProject\AI\참고\instructor-main`
- 프로젝트명: `instructor`
- 확인 버전: `1.15.1`
- 라이선스: MIT
- 언어/런타임: Python `>=3.9,<4.0`
- 성격: LLM 응답을 Pydantic 모델로 강제 변환하고 검증하는 구조화 출력 라이브러리
- 핵심 가치: 자연어/문서/이미지 입력에서 엔티티, 관계, 속성, 근거를 안정적인 JSON/Pydantic 객체로 추출
Instructor는 크롤러나 온톨로지 저장소가 아니라, LLM 기반 추출 단계의 신뢰성 레이어다. 범용 온톨로지 구축 플랫폼에서는 “웹/문서에서 수집한 비정형 텍스트를 명세된 스키마로 추출하고, 검증 실패 시 자동 재질문하며, 결과를 typed 객체로 돌려주는 모듈”로 거의 원형 그대로 사용할 수 있다.
## 2. 프로젝트 구조 요약
```text
instructor-main/
instructor/
__init__.py # 공개 API export
auto_client.py # provider/model 문자열 기반 자동 클라이언트 생성
mode.py # provider별 응답 처리 모드 enum
core/
client.py # Instructor/AsyncInstructor 래퍼 API
patch.py # provider create() 함수 monkey patch
retry.py # tenacity 기반 재시도 및 reask
hooks.py # 이벤트 훅
exceptions.py # 예외 모델
processing/
response.py # 중앙 dispatcher, mode별 request/response 처리
function_calls.py # OpenAISchema, provider 응답 파싱
schema.py # OpenAI/Anthropic/Gemini schema 생성
multimodal.py # image/audio/pdf 메시지 변환
dsl/
partial.py # streaming partial object
iterable.py # streaming iterable extraction
maybe.py # 추출 실패 가능성을 모델화
parallel.py # 병렬 tool call 모델
citation.py # 원문 근거 quote 검증 mixin
simple_type.py # str/int 등 단순 타입 wrapper
providers/
openai, anthropic, gemini, genai, bedrock, cohere, ...
batch/
processor.py, request.py # 배치 요청 생성/처리
cache/
__init__.py # AutoCache, DiskCache, cache key
validation/
llm_validators.py # LLM 기반 field validator
cli/
batch/files/jobs/usage # CLI 유틸리티
docs/ # 사용자 문서, 통합 가이드, 튜토리얼
examples/ # 추출, 지식그래프, SQL, FastAPI, batch 예제
tests/ # 단위/통합/LLM provider 테스트
```
## 3. 핵심 실행 흐름
Instructor의 기본 동작은 다음 순서다.
1. 사용자가 Pydantic `BaseModel`로 원하는 출력 스키마를 정의한다.
2. `instructor.from_provider("openai/gpt-4o")` 또는 `from_openai()`로 provider client를 래핑한다.
3. `client.chat.completions.create(response_model=MyModel, messages=[...])`를 호출한다.
4. `core.patch.patch()`가 provider의 `create()` 호출을 가로채 `response_model`, `max_retries`, `strict`, `context`, `hooks`, `cache`를 처리한다.
5. `processing.response.handle_response_model()`이 Pydantic 모델을 provider별 tool schema 또는 JSON schema 요청으로 변환한다.
6. `core.retry.retry_sync()` 또는 `retry_async()`가 provider 호출을 실행한다.
7. `processing.response.process_response()`가 raw LLM 응답을 `OpenAISchema.from_response()`로 넘겨 모드별 파서를 선택한다.
8. Pydantic 검증이 성공하면 typed model을 반환하고 `_raw_response`에 원본 provider 응답을 붙인다.
9. JSON 파싱 또는 Pydantic 검증 실패 시 `handle_reask_kwargs()`가 에러 내용을 다음 프롬프트에 반영해 재시도한다.
10. 모든 재시도 실패 시 `InstructorRetryException`에 실패 이력, 마지막 응답, 사용량, 재현 가능한 create kwargs를 담아 예외를 발생시킨다.
이 흐름은 온톨로지 플랫폼에서 `문서 청크 -> 후보 엔티티/관계 추출 -> 스키마 검증 -> 실패 재시도 -> 근거 포함 결과 저장` 파이프라인으로 바로 매핑된다.
## 4. 주요 공개 API
### 4.1 클라이언트 생성
- `instructor.from_provider(model: str, async_client=False, cache=None, mode=None, **kwargs)`
- `"provider/model-name"` 형식으로 provider를 자동 선택한다.
- 지원 provider: `openai`, `azure_openai`, `anthropic`, `google`, `vertexai`, `mistral`, `cohere`, `perplexity`, `groq`, `writer`, `bedrock`, `cerebras`, `deepseek`, `fireworks`, `ollama`, `openrouter`, `xai`, `litellm`.
- 기본 모델명을 `Instructor.default_model`에 저장하고 호출 시 `model` 생략을 허용한다.
- `instructor.from_openai(client, model=None, mode=Mode.TOOLS, **kwargs)`
- 기존 OpenAI 호환 client를 래핑한다.
- OpenAI-compatible endpoint, OpenRouter, Ollama, vLLM류 연동에 유리하다.
- `instructor.patch(client=..., create=..., mode=...)`
- provider client 또는 독립 create 함수를 직접 patch한다.
- 기존 코드 변경을 최소화하면서 `response_model` 기능을 추가할 수 있다.
### 4.2 구조화 호출
- `client.create(response_model, messages, max_retries=3, strict=True, context=None, hooks=None, **kwargs)`
- 가장 중요한 API다.
- 반환값은 raw JSON이 아니라 Pydantic model instance다.
- `response_model=None`이면 provider raw response를 그대로 반환한다.
- `client.create_with_completion(...)`
- `(parsed_model, raw_completion)` tuple을 반환한다.
- 디버깅, 감사로그, 추출 근거 저장에 유용하다.
- `client.create_iterable(response_model, messages, **kwargs)`
- streaming으로 여러 객체를 순차 반환한다.
- 긴 문서에서 엔티티/관계 후보를 점진적으로 받을 때 적합하다.
- `client.create_partial(response_model, messages, **kwargs)`
- streaming 중 불완전한 partial model을 계속 반환한다.
- UI에서 추출 진행 상태를 보여주거나 긴 ontology 생성 작업을 관찰할 때 유용하다.
### 4.3 DSL 타입
- `Partial[T]`
- 스트리밍 중 채워지는 부분 객체.
- 대형 ontology schema 추출의 진행률 표시와 중간 검증에 적합하다.
- `IterableModel[T]`
- 하나의 LLM 응답에서 다수의 typed item을 순차 추출한다.
- `EntityCandidate`, `RelationCandidate` 목록 추출에 적합하다.
- `Maybe(T)`
- `result`, `error`, `message`를 가진 wrapper 모델을 동적으로 만든다.
- “해당 청크에 관계가 없을 수도 있음” 같은 불확실성을 명시적으로 표현한다.
- `CitationMixin`
- `substring_quotes` 필드를 통해 추출 결과의 원문 근거를 검증한다.
- `context={"context": 원문}`을 전달하면 quote가 실제 원문에 존재하는지 fuzzy matching으로 정리한다.
- 온톨로지 신뢰도, human review, provenance 저장에 중요하다.
- `ModelAdapter`, simple type adapter
- `str`, `int`, `list[str]` 같은 단순 타입 응답을 Pydantic 검증 경로로 통합한다.
### 4.4 검증/재시도
- `max_retries`
- int 또는 `tenacity.Retrying`/`AsyncRetrying` 객체를 받을 수 있다.
- 검증 실패, JSON 파싱 실패 시 자동 reask를 수행한다.
- `strict`
- strict JSON/Pydantic validation 여부를 제어한다.
- ontology 저장 전 단계는 `strict=True`를 기본값으로 권장한다.
- `context`
- Pydantic validator에 전달되는 runtime context다.
- 도메인 ontology, 허용 relation type, source document metadata, language 같은 동적 검증 조건을 전달할 수 있다.
- `llm_validator(statement, client, allow_override=False, model=..., temperature=0)`
- 특정 필드를 LLM으로 한 번 더 검증한다.
- “관계명은 ontology relation vocabulary에 맞아야 한다” 같은 semantic validation에 사용할 수 있으나 비용과 지연이 있으므로 핵심 필드에 제한하는 것이 좋다.
### 4.5 캐시
- `AutoCache(maxsize=128)`
- thread-safe in-memory LRU cache.
- schema, model, messages, mode를 기반으로 cache key를 만든다.
- `DiskCache(directory=".instructor_cache")`
- optional `diskcache` 의존성 기반 persistent cache.
- 캐시 key 구성 요소
- provider/model
- messages 또는 contents/chat_history
- mode
- response_model JSON schema
온톨로지 플랫폼에서는 동일 문서 청크와 동일 schema로 재처리할 때 비용 절감을 기대할 수 있다. 단, prompt에 시간/외부 상태가 들어가면 cache 오염을 막기 위해 cache scope를 작업 단위로 제한해야 한다.
### 4.6 Hooks/Observability
지원 이벤트:
- `completion:kwargs`: provider 호출 직전
- `completion:response`: provider 응답 직후
- `parse:error`: JSON/Pydantic parsing 실패
- `completion:last_attempt`: 마지막 시도 직전/시점
- `completion:error`: provider/network 등 일반 오류
온톨로지 플랫폼에서는 이 훅을 사용해 추출 요청 로그, retry 사유, token usage, 실패 샘플, provider별 품질 통계를 저장할 수 있다.
## 5. Provider/Mode 명세
`mode.py`는 provider별 요청 포맷과 응답 파싱 전략을 enum으로 정의한다.
주요 모드:
- OpenAI 계열: `TOOLS`, `TOOLS_STRICT`, `JSON`, `MD_JSON`, `JSON_SCHEMA`, `RESPONSES_TOOLS`
- Anthropic: `ANTHROPIC_TOOLS`, `ANTHROPIC_REASONING_TOOLS`, `ANTHROPIC_JSON`, `ANTHROPIC_PARALLEL_TOOLS`
- Google/Gemini: `GEMINI_JSON`, `GEMINI_TOOLS`, `GENAI_TOOLS`, `GENAI_STRUCTURED_OUTPUTS`, `VERTEXAI_TOOLS`, `VERTEXAI_JSON`
- Mistral/Cohere/Cerebras/Fireworks/Writer/Bedrock/XAI 등 provider 전용 모드
- `PARALLEL_TOOLS`: OpenAI 병렬 tool call
- `OPENROUTER_STRUCTURED_OUTPUTS`: OpenRouter 구조화 출력
플랫폼 적용 권장:
- 기본 OpenAI-compatible provider: `Mode.TOOLS` 또는 provider native structured output
- schema 엄격성이 중요한 ontology extraction: `TOOLS_STRICT` 또는 `JSON_SCHEMA`
- local/open-source 모델: `from_provider("ollama/model")`, OpenAI-compatible base_url 또는 LiteLLM 경유
- 여러 추출 타입을 한 번에 받을 경우: `PARALLEL_TOOLS`는 유용하나 streaming 미지원이므로 대량 처리에는 분리 호출도 고려
## 6. 온톨로지 플랫폼에 필요한 기능 매핑
### 6.1 엔티티 추출
원본 Instructor 기능:
- Pydantic `EntityCandidate` 모델 정의
- `IterableModel[EntityCandidate]` 또는 `list[EntityCandidate]` 추출
- field validator로 label normalization, type validation
- retry/reask로 누락/타입 오류 자동 수정
플랫폼 기능:
- 문서 청크에서 개체명, 표준명, 별칭, 타입, 설명, 근거 quote, confidence 추출
- 기존 ontology vocabulary와 비교해 허용 타입만 통과
- 중복 후보 병합 전 structured candidate pool 생성
권장 모델 예시:
```python
class EntityCandidate(CitationMixin):
name: str
canonical_name: str
entity_type: str
aliases: list[str] = []
description: str | None = None
confidence: float
```
### 6.2 관계 추출
원본 Instructor 기능:
- nested model, enum/literal validation
- `Maybe(RelationCandidate)`로 관계 부재 표현
- `context` 기반 validator에서 허용 relation vocabulary 검사
플랫폼 기능:
- source entity, target entity, predicate, direction, evidence, confidence 추출
- entity 후보와 relation 후보를 분리 추출 후 graph builder에서 연결
- 관계 근거가 없는 경우 저장하지 않고 review queue로 이동
권장 모델 예시:
```python
class RelationCandidate(CitationMixin):
source_name: str
target_name: str
relation_type: str
relation_label: str
confidence: float
```
### 6.3 속성/스키마 추출
원본 Instructor 기능:
- nested Pydantic models
- JSON schema 기반 출력 강제
- `strict=True` validation
플랫폼 기능:
- 엔티티별 속성명, 값, 단위, 데이터 타입, source span 추출
- domain schema 후보 생성
- ontology class/property 자동 제안
### 6.4 근거와 provenance
원본 Instructor 기능:
- `CitationMixin`
- `_raw_response` 보존
- `create_with_completion()`
플랫폼 기능:
- 각 triple 또는 property assertion에 source document id, chunk id, quote, model, prompt hash, raw completion id 저장
- 신뢰도 낮은 결과를 human review로 라우팅
### 6.5 대량 처리
원본 Instructor 기능:
- `batch/` 모듈
- provider별 batch request 생성
- `create_iterable()` streaming
- cache
플랫폼 기능:
- 크롤링된 문서 청크를 batch job으로 변환
- provider batch API 또는 내부 queue worker에서 처리
- 실패한 청크만 재시도
- 같은 schema/prompt 조합 재처리 시 cache 사용
### 6.6 멀티모달 추출
원본 Instructor 기능:
- `processing.multimodal.Image`, `Audio`
- provider별 message conversion
- PDF/image/audio 예제 포함
플랫폼 기능:
- 문서 이미지, 표, 영수증, PDF에서 구조화 정보 추출
- 온톨로지 구축 대상이 제품/인물/기관/문헌 등일 때 이미지 기반 보조 evidence 확보
## 7. 상세 기능명세
### F-INST-001 Provider Client Wrapping
- 목적: 다양한 LLM provider를 동일한 structured output API로 호출한다.
- 입력: provider/model 문자열, API key, base_url, async 여부, mode
- 출력: `Instructor` 또는 `AsyncInstructor`
- 성공 조건: `client.chat.completions.create(response_model=...)` 호출 가능
- 적용 우선도: 필수
- 원본 사용 가능성: 거의 변형 없이 사용
### F-INST-002 Pydantic Response Model Extraction
- 목적: 비정형 LLM 응답을 Pydantic 모델로 검증된 객체로 반환한다.
- 입력: `response_model`, `messages`, provider kwargs
- 출력: Pydantic model instance
- 오류: `ValidationError`, `JSONDecodeError`, `InstructorRetryException`
- 적용 우선도: 필수
- 원본 사용 가능성: 그대로 사용
### F-INST-003 Automatic Reask/Retry
- 목적: 스키마 검증 실패 시 오류 내용을 LLM에 전달해 자동 수정한다.
- 입력: 실패 응답, exception, failed_attempts, mode
- 출력: 수정된 kwargs/messages로 재시도
- 설정: `max_retries`, `timeout`, tenacity policy
- 적용 우선도: 필수
- 원본 사용 가능성: 그대로 사용하되 retry 횟수/timeout 정책은 플랫폼 설정화 필요
### F-INST-004 Strict Schema Validation
- 목적: ontology 저장소에 잘못된 shape의 데이터를 넣지 않는다.
- 입력: Pydantic schema, JSON response, strict flag
- 출력: valid model 또는 validation error
- 적용 우선도: 필수
- 원본 사용 가능성: 그대로 사용
### F-INST-005 Citation/Evidence Validation
- 목적: 추출 결과가 원문에 기반하는지 확인한다.
- 입력: `CitationMixin` 모델, `context={"context": source_text}`
- 출력: 원문에 존재하는 quote로 정리된 `substring_quotes`
- 적용 우선도: 필수
- 원본 사용 가능성: 대부분 사용 가능. 한국어/긴 문서 fuzzy match 성능은 추가 검증 필요
### F-INST-006 Maybe Wrapper
- 목적: 추출 대상이 없을 수 있는 상황을 예외가 아니라 정상 결과로 표현한다.
- 입력: `Maybe(EntityCandidate)` 또는 `Maybe(RelationCandidate)`
- 출력: `{result, error, message}`
- 적용 우선도: 높음
- 원본 사용 가능성: 그대로 사용
### F-INST-007 Iterable Extraction
- 목적: 긴 응답에서 여러 후보 객체를 안정적으로 추출한다.
- 입력: item model, stream response
- 출력: item generator 또는 `ListResponse`
- 적용 우선도: 높음
- 원본 사용 가능성: 그대로 사용
### F-INST-008 Partial Streaming
- 목적: 추출 중간 결과를 UI/로그/작업 상태에 반영한다.
- 입력: `Partial[Model]`, `stream=True`
- 출력: partial model stream
- 적용 우선도: 중간
- 원본 사용 가능성: 그대로 사용
### F-INST-009 Parallel Tool Extraction
- 목적: 한 요청에서 여러 구조화 모델을 동시에 추출한다.
- 입력: model list 또는 parallel wrapper, `Mode.PARALLEL_TOOLS`
- 출력: 여러 typed model
- 제약: streaming 미지원
- 적용 우선도: 중간
- 원본 사용 가능성: 그대로 사용하되 대량 처리에서는 비용/재시도 단위를 고려
### F-INST-010 Cache
- 목적: 동일 청크/동일 schema 추출 요청의 비용을 줄인다.
- 입력: cache backend, messages, model, mode, response_model schema
- 출력: cached model 또는 miss 후 저장
- 적용 우선도: 높음
- 원본 사용 가능성: `AutoCache`는 개발/단일 프로세스용으로 그대로 사용, 운영은 Redis/DB backend 구현 권장
### F-INST-011 Hooks and Audit Logging
- 목적: 추출 호출, 응답, 실패, 재시도, 마지막 실패를 관측한다.
- 입력: hook handler
- 출력: 내부 이벤트
- 적용 우선도: 필수
- 원본 사용 가능성: 그대로 사용하되 플랫폼 audit logger와 연결 필요
### F-INST-012 LLM Semantic Validator
- 목적: Pydantic으로 표현하기 어려운 의미 검증을 LLM에 위임한다.
- 입력: validation statement, value, validator model
- 출력: valid/fixed value 또는 validation error
- 적용 우선도: 선택
- 원본 사용 가능성: 제한적으로 사용. 비용/재현성/지연시간 때문에 핵심 relation 검증에만 권장
### F-INST-013 Batch Processing
- 목적: 많은 문서 청크를 provider batch API 또는 내부 batch 구조로 처리한다.
- 입력: batch requests, provider config
- 출력: batch job, results
- 적용 우선도: 높음
- 원본 사용 가능성: OpenAI/Anthropic 중심으로 재사용 가능. 플랫폼 job queue와 통합 필요
### F-INST-014 Multimodal Input Conversion
- 목적: 이미지, 오디오, PDF 등 비텍스트 입력을 provider 메시지 형식으로 변환한다.
- 입력: path/url/base64/data URI
- 출력: provider-ready content block
- 적용 우선도: 중간
- 원본 사용 가능성: 그대로 사용 가능하나 provider별 비용/지원 범위 검증 필요
### F-INST-015 Raw Response Preservation
- 목적: 추출 결과의 감사 가능성과 재현성을 확보한다.
- 입력: provider raw response
- 출력: parsed model의 `_raw_response`
- 적용 우선도: 필수
- 원본 사용 가능성: 그대로 사용. 저장소에는 필요한 metadata만 선별 저장 권장
## 8. 플랫폼 아키텍처 적용안
권장 구성:
```text
Crawler / Document Loader
-> Chunker
-> InstructorExtractionService
- provider client registry
- response model registry
- prompt template registry
- retry/cache/hooks policy
-> Candidate Normalizer
-> Entity Resolution
-> Ontology Graph Builder
-> Human Review Queue
-> Graph DB / Relational Store
```
`InstructorExtractionService`는 Instructor를 직접 노출하지 말고 플랫폼 내부 adapter로 감싼다.
필수 adapter 책임:
- provider/model 설정 로딩
- domain별 response_model 선택
- prompt/context 생성
- `context`에 ontology vocabulary와 source metadata 주입
- hooks로 audit log 저장
- cache scope 결정
- `InstructorRetryException`을 플랫폼 표준 에러로 변환
- raw response/token usage/provenance 저장
## 9. 기본 소스로 가져올 때의 권장 범위
거의 변형 없이 사용:
- `instructor.core.patch`
- `instructor.core.client`
- `instructor.core.retry`
- `instructor.processing.response`
- `instructor.processing.function_calls`
- `instructor.processing.schema`
- `instructor.mode`
- `instructor.dsl.*`
- `instructor.cache`
- `instructor.validation.llm_validators`
플랫폼에 맞게 감쌀 부분:
- `auto_client.from_provider`: 플랫폼 provider registry와 secret manager에 맞게 thin wrapper 작성
- `hooks`: audit/event bus에 연결
- `cache`: 운영용 Redis/DB cache backend 추가
- `batch`: 플랫폼 job queue, chunk id, dataset id와 매핑
- `CitationMixin`: 한국어/긴 문서/정규화 quote에 대한 보강 validator 추가 가능
굳이 가져오지 않아도 되는 부분:
- `docs/`, `examples/`, `scripts/` 전체
- `cli/`는 운영 필요성이 생기기 전에는 제외 가능
- provider 중 사용하지 않는 optional provider dependency
## 10. 온톨로지 추출용 최소 구현 예시
```python
from pydantic import BaseModel, Field, field_validator
from instructor import CitationMixin, Maybe
class EntityCandidate(CitationMixin):
name: str = Field(description="Surface form found in the source text")
canonical_name: str = Field(description="Normalized canonical entity name")
entity_type: str = Field(description="Ontology class/type")
aliases: list[str] = Field(default_factory=list)
confidence: float = Field(ge=0, le=1)
class RelationCandidate(CitationMixin):
source_name: str
target_name: str
relation_type: str
confidence: float = Field(ge=0, le=1)
@field_validator("relation_type")
@classmethod
def relation_must_be_allowed(cls, value: str, info):
allowed = (info.context or {}).get("allowed_relations", set())
if allowed and value not in allowed:
raise ValueError(f"relation_type must be one of {sorted(allowed)}")
return value
MaybeRelation = Maybe(RelationCandidate)
```
호출 패턴:
```python
client = instructor.from_provider("openai/gpt-4o-mini")
result = client.chat.completions.create(
response_model=MaybeRelation,
messages=[
{"role": "system", "content": "Extract ontology relation candidates only from the provided source."},
{"role": "user", "content": source_chunk},
],
context={
"context": source_chunk,
"allowed_relations": {"is_a", "part_of", "used_for", "located_in"},
},
max_retries=3,
strict=True,
)
```
## 11. 리스크와 보완 필요점
- Instructor는 ontology reasoner가 아니다. OWL/RDF reasoning, graph merge, entity resolution은 별도 모듈이 필요하다.
- Pydantic schema가 너무 크면 LLM 출력 품질이 떨어진다. 추출 단계를 엔티티, 관계, 속성, 검증으로 분리하는 것이 좋다.
- `CitationMixin`은 quote 존재성 검증에 가깝고 “의미적으로 올바른 근거”를 보장하지 않는다. confidence와 human review가 필요하다.
- LLM validator는 강력하지만 비용이 크다. 전체 필드가 아니라 고위험 필드에만 적용해야 한다.
- provider별 mode 동작 차이가 있다. 운영 전 provider별 golden test set이 필요하다.
- local model/Ollama/OpenRouter 사용 시 tool calling 품질이 모델마다 크게 다르다. JSON mode fallback을 준비해야 한다.
- cache는 prompt/schema/source version을 엄격히 key에 포함해야 한다. 원본 cache key는 schema와 messages를 포함하므로 안전한 편이지만, 플랫폼 metadata까지 포함하려면 wrapper 수준에서 messages/context에 명확히 반영해야 한다.
## 12. 테스트 전략
원본 테스트에서 참고할 영역:
- `tests/test_patch.py`: patch 동작
- `tests/test_retry_json_mode.py`: JSON mode retry
- `tests/test_json_extraction.py`: JSON 추출
- `tests/test_process_response.py`: 응답 dispatcher
- `tests/test_schema.py`, `tests/test_schema_utils.py`: schema 생성
- `tests/dsl/test_partial.py`: partial streaming
- `tests/test_list_response.py`: list response
- `tests/test_cache_integration.py`: cache
- `tests/llm/test_core_providers/*`: provider capability 공통 테스트
플랫폼 추가 테스트:
- ontology entity schema validation unit test
- relation vocabulary validator test
- source quote/provenance validation test
- retry 후 수정 성공 golden test
- invalid extraction이 graph DB에 저장되지 않는 integration test
- provider별 동일 chunk extraction 품질 비교 test
- cache hit/miss와 schema 변경 cache busting test
## 13. 결론
Instructor는 범용 온톨로지 구축 플랫폼의 “LLM 구조화 추출 엔진”으로 매우 적합하다. 특히 Pydantic 중심 스키마, provider 추상화, 자동 재시도, streaming DSL, 근거 quote mixin, hooks, cache가 플랫폼 핵심 요구와 잘 맞는다.
기본 소스로 사용할 때는 Instructor 자체를 크게 변형하기보다, 플랫폼 내부에 `InstructorExtractionService` adapter를 두고 provider 설정, prompt, ontology vocabulary, audit log, cache, job queue를 연결하는 방식이 가장 안전하다. 이렇게 하면 원본 업데이트를 따라가기 쉽고, 온톨로지 플랫폼 고유 로직은 adapter와 domain schema 레이어에 깔끔하게 남길 수 있다.