@heripo/pdf-parser 0.1.28 → 0.1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -20,7 +20,8 @@
20
20
  - [사전 요구사항](#사전-요구사항)
21
21
  - [설치](#설치)
22
22
  - [사용법](#사용법)
23
- - [OCR 전략 시스템](#ocr-전략-시스템)
23
+ - [필수 보정 파이프라인](#필수-보정-파이프라인)
24
+ - [Review Assistance](#review-assistance)
24
25
  - [문서 유형 검증](#문서-유형-검증)
25
26
  - [대용량 PDF 청크 변환](#대용량-pdf-청크-변환)
26
27
  - [이미지 PDF 폴백](#이미지-pdf-폴백)
@@ -30,18 +31,21 @@
30
31
  - [시스템 의존성 상세](#시스템-의존성-상세)
31
32
  - [API 문서](#api-문서)
32
33
  - [문제 해결](#문제-해결)
34
+ - [후원](#후원)
33
35
  - [라이선스](#라이선스)
34
36
 
35
37
  ## 주요 기능
36
38
 
37
- - **고품질 OCR**: Docling SDK를 활용한 문서 인식 (ocrmac / Apple Vision Framework)
38
- - **한국어 보고서 VLM 보정**: 한국어 보고서를 자동 감지하고 모든 페이지에 VLM 텍스트 보정을 적용
39
+ - **ocrmac 고정 OCR**: Docling 변환은 항상 ocrmac / Apple Vision Framework를 사용
40
+ - **필수 VLM 보정**: Docling 이후 텍스트 보정, page gate, 구조 review 모델을 항상 실행
39
41
  - **Apple Silicon 최적화**: M1/M2/M3/M4/M5 칩에서 GPU 가속 지원
40
42
  - **자동 환경 설정**: Python 가상환경 및 docling-serve 자동 설치
41
43
  - **이미지 추출**: PDF 내 이미지 자동 추출 및 저장
42
44
  - **문서 유형 검증**: LLM 기반 고고학 보고서 여부 검증 (선택)
43
45
  - **청크 변환**: 대용량 PDF를 청크로 분할하여 안정적으로 처리
44
46
  - **이미지 PDF 폴백**: 변환 실패 시 이미지 기반 PDF로 자동 재시도
47
+ - **Review Assistance**: page-level VLM review로 audit proposal을 기록하고, 의미 낮은 페이지는 관찰 가능한 사유와 함께 skip하며, 고신뢰도 수정만 자동 적용
48
+ - **표 보정 강화**: 표별 work item으로 셀, span, header, 단위, 각주, 인접 페이지 연속표를 검증
45
49
  - **AbortSignal 지원**: 진행 중인 파싱 작업 취소
46
50
  - **서버 크래시 복구**: ECONNREFUSED 발생 시 docling-serve 자동 재시작
47
51
 
@@ -49,7 +53,7 @@
49
53
 
50
54
  ### 시스템 요구사항
51
55
 
52
- - **macOS** with Apple Silicon (M1/M2/M3) - 최적 성능을 위해 권장
56
+ - **macOS** with Apple Silicon (M1/M2/M3/M4/M5) - 최적 성능을 위해 권장
53
57
  - **macOS** with Intel - 지원되지만 속도가 느림
54
58
  - **Linux/Windows** - 현재 지원하지 않음
55
59
 
@@ -61,7 +65,7 @@
61
65
  brew install node
62
66
  ```
63
67
 
64
- #### 2. pnpm >= 9.0.0
68
+ #### 2. pnpm >= 10.0.0
65
69
 
66
70
  ```bash
67
71
  npm install -g pnpm
@@ -81,7 +85,7 @@ python3.11 --version
81
85
 
82
86
  #### 4. poppler (PDF 텍스트 추출)
83
87
 
84
- PDF 페이지 수 확인(`pdfinfo`)과 텍스트 레이어 추출(`pdftotext`)에 필요하며, OCR 전략 시스템의 텍스트 레이어 사전 검사에 사용됩니다.
88
+ PDF 페이지 수 확인(`pdfinfo`)과 텍스트 레이어 추출(`pdftotext`)에 필요하며, Docling 이후 보정의 참조 텍스트로 사용됩니다.
85
89
 
86
90
  ```bash
87
91
  brew install poppler
@@ -123,13 +127,13 @@ brew install imagemagick ghostscript
123
127
 
124
128
  ```bash
125
129
  # npm으로 설치
126
- npm install @heripo/pdf-parser
130
+ npm install @heripo/pdf-parser @heripo/logger
127
131
 
128
132
  # pnpm으로 설치
129
- pnpm add @heripo/pdf-parser
133
+ pnpm add @heripo/pdf-parser @heripo/logger
130
134
 
131
135
  # yarn으로 설치
132
- yarn add @heripo/pdf-parser
136
+ yarn add @heripo/pdf-parser @heripo/logger
133
137
  ```
134
138
 
135
139
  ## 사용법
@@ -137,10 +141,16 @@ yarn add @heripo/pdf-parser
137
141
  ### 기본 사용법
138
142
 
139
143
  ```typescript
144
+ import { openai } from '@ai-sdk/openai';
140
145
  import { Logger } from '@heripo/logger';
141
146
  import { PDFParser } from '@heripo/pdf-parser';
142
147
 
143
- const logger = Logger(...);
148
+ const logger = new Logger({
149
+ debug: (...args) => console.debug('[heripo]', ...args),
150
+ info: (...args) => console.info('[heripo]', ...args),
151
+ warn: (...args) => console.warn('[heripo]', ...args),
152
+ error: (...args) => console.error('[heripo]', ...args),
153
+ });
144
154
 
145
155
  // PDFParser 인스턴스 생성 (logger는 필수)
146
156
  const pdfParser = new PDFParser({
@@ -148,19 +158,29 @@ const pdfParser = new PDFParser({
148
158
  logger,
149
159
  });
150
160
 
161
+ const correctionModel = openai('gpt-5.1');
162
+
151
163
  // 초기화 (환경 설정 및 docling-serve 시작)
152
164
  await pdfParser.init();
153
165
 
154
166
  // PDF 파싱
155
167
  const tokenUsageReport = await pdfParser.parse(
156
168
  'file:///path/to/report.pdf', // PDF URL (file:// 또는 http://)
157
- 'report-001', // 리포트 ID
169
+ 'report-001', // 리포트 ID
158
170
  async (outputPath) => {
159
171
  // 변환 완료 콜백
160
172
  console.log('PDF 변환 완료:', outputPath);
161
173
  },
162
- false, // cleanupAfterCallback
163
- {}, // PDFConvertOptions
174
+ false, // cleanupAfterCallback
175
+ {
176
+ correction: {
177
+ models: {
178
+ textCorrection: correctionModel,
179
+ pageGate: correctionModel,
180
+ reviewAssistance: correctionModel,
181
+ },
182
+ },
183
+ }, // PDFConvertOptions
164
184
  );
165
185
 
166
186
  // 토큰 사용량 리포트 (LLM 사용이 없으면 null)
@@ -193,10 +213,37 @@ const tokenUsageReport = await pdfParser.parse(
193
213
  async (outputPath) => console.log(outputPath),
194
214
  false,
195
215
  {
196
- // OCR 전략 옵션
197
- strategySamplerModel: openai('gpt-5.1'),
198
- vlmProcessorModel: openai('gpt-5.1'),
199
- vlmConcurrency: 3,
216
+ // Docling 이후 필수 보정
217
+ correction: {
218
+ models: {
219
+ textCorrection: openai('gpt-5.1'),
220
+ pageGate: openai('gpt-5.1'),
221
+ reviewAssistance: openai('gpt-5.1'),
222
+ tableCorrection: openai('gpt-5.1'),
223
+ reviewAssistanceTasks: {
224
+ text_ocr_hanja: openai('gpt-5.1'),
225
+ tables: openai('gpt-5.1'),
226
+ },
227
+ },
228
+ concurrency: {
229
+ pages: 1,
230
+ reviewTasks: 4,
231
+ tables: 1,
232
+ },
233
+ localModelConcurrency: 1,
234
+ workItemTimeoutMs: 900000,
235
+ maxRetries: {
236
+ textCorrection: 3,
237
+ pageGate: 3,
238
+ reviewAssistance: 3,
239
+ tableCorrection: 3,
240
+ },
241
+ autoApplyThreshold: 0.85,
242
+ proposalThreshold: 0.5,
243
+ temperature: 0,
244
+ outputLanguage: 'ko-KR',
245
+ },
246
+ onReviewAssistanceProgress: (event) => console.log(event),
200
247
 
201
248
  // 문서 유형 검증
202
249
  documentValidationModel: openai('gpt-5.1'),
@@ -227,29 +274,52 @@ const tokenUsageReport = await pdfParser.parse(
227
274
  await pdfParser.dispose();
228
275
  ```
229
276
 
230
- ## OCR 전략 시스템
277
+ ## 필수 보정 파이프라인
231
278
 
232
- ### 왜 이 전략인가?
279
+ ### ocrmac을 고정하는 이유
233
280
 
234
281
  **ocrmac(Apple Vision Framework)은 매우 우수한 OCR 엔진입니다** -- 무료이고, GPU 가속을 지원하며, 고품질 결과를 제공합니다. 수천~수백만 권의 고고학 보고서를 처리할 때 이만한 솔루션이 없습니다.
235
282
 
236
- **그러나 한국어 고고학 보고서는 문자 체계 인식 보정이 자주 필요합니다.** 한자 복원, CJK mojibake, 음독 치환, 기관명 등은 표준 OCR만으로 안정적으로 처리하기 어렵습니다. VLM을 기본 OCR 엔진으로 쓰는 대신, 빠른 ocrmac 파이프라인을 먼저 실행한 뒤 한국어 보고서에 VLM 텍스트 보정을 적용합니다.
283
+ `@heripo/pdf-parser`는 더 이상 OCR strategy를 sampling하거나 VLM OCR 경로로 전환하지 않습니다. Docling 변환은 항상 ocrmac으로 실행하고, VLM은 Docling 이후 필수 보정 단계에서만 사용합니다.
284
+
285
+ ### 필수 correction 계약
286
+
287
+ 모든 `parse()` 호출은 `correction.models.textCorrection`, `correction.models.pageGate`, `correction.models.reviewAssistance`를 제공해야 합니다. 필수 모델이 누락되면 변환 callback을 감싸기 전에 명확히 실패합니다.
288
+
289
+ 보정 단계는 다음 순서로 실행됩니다.
237
290
 
238
- ### 2단계 한국어 감지 (`OcrStrategySampler`)
291
+ 1. 변경 전 `result_ocr_origin.json`을 저장합니다.
292
+ 2. `textCorrection` 모델로 페이지 텍스트와 표 셀 OCR을 보정합니다.
293
+ 3. `pageGate` 모델로 Review Assistance page gate를 실행하고 `review_assistance_page_gate.json`을 기록합니다.
294
+ 4. task별 모델로 구조 Review Assistance work item을 실행합니다.
295
+ 5. 감지된 표마다 table-specific correction work item을 실행합니다.
296
+ 6. 실행 중 `review_assistance_checkpoint.json`을 기록하고, 완료 시 `review_assistance.json`을 기록합니다.
297
+
298
+ 텍스트 보정은 텍스트나 표가 있는 모든 페이지에 적용됩니다. page gate는 구조적 Review Assistance 노이즈만 제어하며, OCR 텍스트 보정 범위를 줄이지 않습니다.
299
+
300
+ ### 로컬 모델 권장 실행 방식
301
+
302
+ 보정 파이프라인은 로컬 VLM 기준으로 설계되었습니다. 큰 context 하나보다 작은 context를 자주 호출하고, deterministic validator와 retry, timeout, checkpoint/resume으로 안정성을 확보합니다. 처음에는 `concurrency.pages: 1`, `concurrency.tables: 1`, `localModelConcurrency: 1`, `temperature: 0`, 충분한 `workItemTimeoutMs`로 시작하고, 모델이 안정화된 뒤 동시성을 높이는 것을 권장합니다.
303
+
304
+ ### 롤아웃 smoke test
305
+
306
+ 레포 contributor는 로컬 demo 고고학 보고서 산출물 2종으로 correction rollout smoke test를 실행할 수 있습니다.
307
+
308
+ ```bash
309
+ pnpm --filter @heripo/pdf-parser smoke:correction
310
+ ```
239
311
 
240
- 1. **텍스트 레이어 사전 검사** (비용 없음): `pdftotext`로 문서의 텍스트 레이어를 추출하여 한글을 확인합니다. 한글이 있으면 즉시 한국어 문서로 판별합니다.
241
- 2. **VLM 샘플링** (필요 시에만): 최대 15페이지를 샘플링(앞뒤 10%는 표지·부록으로 제외)하여 Vision LLM으로 언어를 판정합니다. `ko-KR` 감지 시 즉시 종료합니다.
312
+ 이 smoke test는 기존 demo artifact를 `/private/tmp/heripo-pdf-parser-correction-smoke`로 복사하고, deterministic local fake model로 correction을 실행한 뒤 `review_assistance.json`, 표 work-item trace, validation status, checkpoint resume 동작을 검증합니다. 파이프라인 기계적 경로를 검증하는 용도이며, 의미론적 표 보정 품질은 실제로 설정한 로컬 VLM 품질에 의존합니다.
242
313
 
243
- ### 전체 문서 보정 (`VlmTextCorrector`)
314
+ ## Review Assistance
244
315
 
245
- 한국어 보고서가 감지되면, 모든 페이지를 VLM에 전송하여 보정합니다:
316
+ Review Assistance는 텍스트 보정 이후 항상 실행되지만 모든 페이지를 같은 강도로 처리하지 않습니다. page gate가 표지, 챕터 표지, 바코드/ISBN 페이지, 장식 중심 페이지를 구조 review 저가치 페이지로 분류합니다. skip된 페이지도 `review_assistance.json`에 info issue와 skip reason으로 남습니다.
246
317
 
247
- - 각 페이지의 OCR 텍스트 요소와 표 셀을 추출
248
- - `pdftotext` 참조 텍스트를 품질 기준으로 활용
249
- - VLM이 치환 기반 보정(find -> replace)을 반환
250
- - 실패한 페이지는 원본 OCR 텍스트를 유지하며 건너뜀
318
+ eligible page는 text OCR/Hanja, text integrity, text role/footnote, tables, pictures/captions, layout/bbox/order, table-specific correction 같은 작은 work item으로 쪼개집니다. 각 호출의 timing, model id, attempts, target refs, deterministic validation status는 `review_assistance.json`에 기록됩니다.
251
319
 
252
- ### 전략 옵션
320
+ ### 표 보정 전략
321
+
322
+ 표는 page 부속물이 아니라 1급 보정 대상으로 처리합니다. scheduler는 표마다 독립 table-specific work item을 만들기 때문에 한 페이지에 표가 여러 개 있어도 bbox, crop, context, validation 상태가 섞이지 않습니다. table validator는 target identity, 같은 페이지 다른 표 내용 혼입, cell, span, header, unit, footnote, empty-cell expansion, adjacent-page continuation ref를 확인한 뒤에야 auto-apply 또는 proposal 결정을 허용합니다.
253
323
 
254
324
  ```typescript
255
325
  const tokenUsageReport = await pdfParser.parse(
@@ -258,21 +328,33 @@ const tokenUsageReport = await pdfParser.parse(
258
328
  async (outputPath) => console.log(outputPath),
259
329
  false,
260
330
  {
261
- // OCR 전략 샘플링 활성화 (Vision LLM 모델 제공)
262
- strategySamplerModel: openai('gpt-5.1'),
263
-
264
- // VLM 텍스트 보정 모델 (한국어 보고서 감지 시 필요)
265
- vlmProcessorModel: openai('gpt-5.1'),
266
-
267
- // VLM 페이지 처리 동시성 (기본값: 1)
268
- vlmConcurrency: 3,
269
-
270
- // 샘플링을 건너뛰고 특정 OCR 방식 강제
271
- forcedMethod: 'ocrmac', // 또는 'vlm'
331
+ correction: {
332
+ models: {
333
+ textCorrection: openai('gpt-5.1'),
334
+ pageGate: openai('gpt-5.1-mini'),
335
+ reviewAssistance: openai('gpt-5.1'),
336
+ tableCorrection: openai('gpt-5.1'),
337
+ },
338
+ autoApplyThreshold: 0.85,
339
+ proposalThreshold: 0.5,
340
+ maxRetries: {
341
+ textCorrection: 3,
342
+ pageGate: 3,
343
+ reviewAssistance: 3,
344
+ tableCorrection: 3,
345
+ },
346
+ temperature: 0,
347
+ outputLanguage: 'ko-KR',
348
+ },
349
+ onReviewAssistanceProgress: (event) => {
350
+ console.log(event.substage, event.status, event.pageNo);
351
+ },
272
352
  },
273
353
  );
274
354
  ```
275
355
 
356
+ Review Assistance는 page image와 text-layer reference를 위해 로컬 `file://` PDF를 필요로 합니다. 고신뢰도 수정은 `result.json`에 적용하고, 원본 snapshot은 `result_review_origin.json`, `result_ocr_origin.json`에 보존하며, `review_assistance_page_gate.json`과 페이지별 결정, 이슈, proposal, call trace, validation status, 요약 count를 담은 `review_assistance.json`을 기록합니다.
357
+
276
358
  ## 문서 유형 검증
277
359
 
278
360
  LLM 기반으로 PDF가 고고학 발굴조사보고서인지 검증하는 선택적 기능입니다. `documentValidationModel`을 제공하면 파서가 PDF에서 텍스트를 추출하고 LLM을 사용하여 문서 유형을 확인한 후 처리합니다. 검증에 실패하면 `InvalidDocumentTypeError`가 발생합니다.
@@ -287,6 +369,13 @@ try {
287
369
  async (outputPath) => console.log(outputPath),
288
370
  false,
289
371
  {
372
+ correction: {
373
+ models: {
374
+ textCorrection: openai('gpt-5.1'),
375
+ pageGate: openai('gpt-5.1'),
376
+ reviewAssistance: openai('gpt-5.1'),
377
+ },
378
+ },
290
379
  documentValidationModel: openai('gpt-5.1'),
291
380
  },
292
381
  );
@@ -308,6 +397,13 @@ const tokenUsageReport = await pdfParser.parse(
308
397
  async (outputPath) => console.log(outputPath),
309
398
  false,
310
399
  {
400
+ correction: {
401
+ models: {
402
+ textCorrection: openai('gpt-5.1'),
403
+ pageGate: openai('gpt-5.1'),
404
+ reviewAssistance: openai('gpt-5.1'),
405
+ },
406
+ },
311
407
  chunkedConversion: true,
312
408
  chunkSize: 50, // 청크당 페이지 수 (기본값: 상수에서 설정)
313
409
  chunkMaxRetries: 3, // 실패한 청크의 최대 재시도 횟수 (기본값: 상수에서 설정)
@@ -342,6 +438,13 @@ const tokenUsageReport = await pdfParser.parse(
342
438
  async (outputPath) => console.log(outputPath),
343
439
  false,
344
440
  {
441
+ correction: {
442
+ models: {
443
+ textCorrection: openai('gpt-5.1'),
444
+ pageGate: openai('gpt-5.1'),
445
+ reviewAssistance: openai('gpt-5.1'),
446
+ },
447
+ },
345
448
  forceImagePdf: true, // 항상 이미지 PDF로 먼저 변환
346
449
  },
347
450
  );
@@ -365,7 +468,15 @@ try {
365
468
  'report-001',
366
469
  async (outputPath) => console.log(outputPath),
367
470
  false,
368
- {},
471
+ {
472
+ correction: {
473
+ models: {
474
+ textCorrection: openai('gpt-5.1'),
475
+ pageGate: openai('gpt-5.1'),
476
+ reviewAssistance: openai('gpt-5.1'),
477
+ },
478
+ },
479
+ },
369
480
  controller.signal, // AbortSignal
370
481
  );
371
482
  } catch (error) {
@@ -404,7 +515,7 @@ try {
404
515
  ### 핵심 장점
405
516
 
406
517
  - **비용**: 클라우드 OCR 대비 100배 이상 저렴 (무료)
407
- - **성능**: Apple Silicon M1/M2/M3에서 GPU 가속으로 빠른 처리
518
+ - **성능**: Apple Silicon M1/M2/M3/M4/M5에서 GPU 가속으로 빠른 처리
408
519
  - **품질**: 복잡한 레이아웃의 문서도 정확히 인식
409
520
  - **프라이버시**: 문서가 외부 서버로 전송되지 않음
410
521
 
@@ -507,12 +618,8 @@ await pdfParser.dispose();
507
618
 
508
619
  ```typescript
509
620
  type PDFConvertOptions = {
510
- // OCR 전략 옵션
511
- strategySamplerModel?: LanguageModel; // OCR 전략 샘플링용 Vision LLM
512
- vlmProcessorModel?: LanguageModel; // 텍스트 보정용 Vision LLM
513
- vlmConcurrency?: number; // 병렬 페이지 처리 (기본값: 1)
514
- skipSampling?: boolean; // 전략 샘플링 건너뛰기
515
- forcedMethod?: 'ocrmac' | 'vlm'; // 특정 OCR 방식 강제
621
+ // Docling 이후 필수 보정
622
+ correction: PDFCorrectionOptions;
516
623
 
517
624
  // 이미지 PDF 옵션
518
625
  forceImagePdf?: boolean; // 이미지 기반 PDF 사전 변환 강제
@@ -525,6 +632,9 @@ type PDFConvertOptions = {
525
632
  document_timeout?: number; // 문서 처리 타임아웃 (초)
526
633
  documentValidationModel?: LanguageModel; // 문서 유형 검증용 LLM
527
634
 
635
+ // 보정 진행 상황
636
+ onReviewAssistanceProgress?: (event: ReviewAssistanceProgressEvent) => void; // 진행 상황 callback
637
+
528
638
  // 청크 변환 (대용량 PDF)
529
639
  chunkedConversion?: boolean; // 청크 변환 활성화
530
640
  chunkSize?: number; // 청크당 페이지 수
@@ -537,14 +647,47 @@ type PDFConvertOptions = {
537
647
  };
538
648
  ```
539
649
 
540
- ### ConvertWithStrategyResult
650
+ ### PDFCorrectionOptions
541
651
 
542
652
  ```typescript
543
- interface ConvertWithStrategyResult {
544
- /** 결정된 OCR 전략 */
545
- strategy: OcrStrategy;
546
- /** 샘플링 및/또는 VLM 처리의 토큰 사용량 리포트 (LLM 사용이 없으면 null) */
547
- tokenUsageReport: TokenUsageReport | null;
653
+ interface PDFCorrectionOptions {
654
+ models: {
655
+ textCorrection: LanguageModel; // 필수: 페이지 텍스트와 표 셀 OCR 보정
656
+ pageGate: LanguageModel; // 필수: 구조 Review Assistance page gate
657
+ reviewAssistance: LanguageModel; // 필수: 기본 구조 review 모델
658
+ tableCorrection?: LanguageModel; // 선택: 표 전용 보정 override
659
+ reviewAssistanceTasks?: Partial<
660
+ Record<
661
+ | 'text_ocr_hanja'
662
+ | 'text_integrity'
663
+ | 'text_role_footnote'
664
+ | 'tables'
665
+ | 'pictures_captions'
666
+ | 'layout_bbox_order',
667
+ LanguageModel
668
+ >
669
+ >;
670
+ };
671
+ concurrency?: {
672
+ pages?: number; // 페이지 단위 text correction/page gate 동시성
673
+ reviewTasks?: number; // 구조 Review Assistance work-item 동시성
674
+ tables?: number; // 표 전용 보정 동시성
675
+ };
676
+ maxRetries?: {
677
+ textCorrection?: number;
678
+ pageGate?: number;
679
+ reviewAssistance?: number;
680
+ tableCorrection?: number;
681
+ };
682
+ localModelConcurrency?: number; // 로컬 모델 요청 동시성 상한
683
+ workItemTimeoutMs?: number; // work item별 timeout
684
+ outputLanguage?: string; // 사람이 읽는 review reason 언어 (기본값: en-US)
685
+ pageGate?: {
686
+ structuralNoiseThreshold?: number;
687
+ };
688
+ autoApplyThreshold?: number; // 자동 적용 최소 confidence (기본값: 0.85)
689
+ proposalThreshold?: number; // sidecar proposal 최소 confidence (기본값: 0.5)
690
+ temperature?: number; // VLM 생성 temperature (기본값: 0)
548
691
  }
549
692
  ```
550
693
 
@@ -665,6 +808,13 @@ Docling SDK의 로컬 OCR은 macOS에서 Apple Metal GPU 가속을 활용해 성
665
808
  - [@heripo/document-processor](../document-processor) - 문서 구조 분석 및 LLM 처리
666
809
  - [@heripo/model](../model) - 데이터 모델 및 타입 정의
667
810
 
811
+ ## 후원
812
+
813
+ heripo lab의 오픈소스 연구를 후원하려면 다음 경로를 이용할 수 있습니다:
814
+
815
+ - [Open Collective](https://opencollective.com/heripo-project): 전반적인 프로젝트 후원
816
+ - [fairy.hada.io/@heripo](https://fairy.hada.io/@heripo): 한국인 개인 후원자를 위한 원화 결제
817
+
668
818
  ## 라이선스
669
819
 
670
820
  이 패키지는 [Apache License 2.0](../../LICENSE) 라이선스 하에 배포됩니다.