ai-startup
CHAPTER 43 / 100
읽기 약 2분
FUNCTION
AI 문서 요약: PDF/URL → 요약 리포트
핵심 개념
PDF 파싱·웹 스크래핑·LLM 요약·이메일 발송 — 정보 과부하 해결.
본문
사용 사례
[B2C]
- 학생: 논문·교재 요약
- 일반: 책·기사 요약
- 음성: 회의·인터뷰 요약
[B2B]
- 변호사: 계약서 요약
- 의료: 진료 차트 요약
- 컨설턴트: 시장 보고서
- 임원: 일일 뉴스 다이제스트PDF 처리
import pdfParse from 'pdf-parse';
import { generateObject } from 'ai';
async function summarizePDF(file: File) {
const buffer = Buffer.from(await file.arrayBuffer());
const { text, numpages } = await pdfParse(buffer);
const result = await generateObject({
model: anthropic('claude-sonnet-4-6'),
schema: z.object({
title: z.string(),
executiveSummary: z.string().describe('3-5 sentences'),
keyPoints: z.array(z.string()).max(7),
actionItems: z.array(z.string()),
quotes: z.array(z.object({
text: z.string(),
page: z.number().optional(),
})),
readingTime: z.string(),
}),
prompt: `Summarize this ${numpages}-page document:
${text}
Provide structured summary.`,
});
return result.object;
}URL 스크래핑
import { JSDOM } from 'jsdom';
import { Readability } from '@mozilla/readability';
async function summarizeURL(url: string) {
const html = await fetch(url).then(r => r.text());
const dom = new JSDOM(html);
const reader = new Readability(dom.window.document);
const article = reader.parse();
if (!article) throw new Error('Cannot extract content');
const result = await generateObject({
model: anthropic('claude-sonnet-4-6'),
schema: SummarySchema,
prompt: `Summarize this article from ${url}:
Title: ${article.title}
${article.textContent}`,
});
return result.object;
}
// 또는 Browserless / ScrapingBee (JavaScript 렌더링)
const html = await fetch('https://chrome.browserless.io/content', {
method: 'POST',
headers: { Authorization: `Bearer ${BROWSERLESS_KEY}` },
body: JSON.stringify({ url, waitFor: 2000 }),
}).then(r => r.text());큰 문서 (100+ 페이지)
// Map-Reduce 패턴
async function summarizeLargeDoc(text: string) {
// 1. Chunking
const chunks = chunkText(text, { maxTokens: 8000 });
// 2. Map — 각 chunk 요약
const summaries = await Promise.all(
chunks.map(chunk =>
generateText({
model: openai('gpt-4o-mini'), // 저렴한 모델
prompt: `Summarize:\n${chunk}`,
maxTokens: 500,
}).then(r => r.text)
),
);
// 3. Reduce — 요약본 통합
const finalResult = await generateObject({
model: anthropic('claude-sonnet-4-6'), // 고품질 모델
schema: SummarySchema,
prompt: `Combine these chunk summaries into a final structured summary:
${summaries.map((s, i) => `Chunk ${i+1}:\n${s}`).join('\n\n')}`,
});
return finalResult.object;
}회의 / 인터뷰 요약 (음성)
import { openai } from '@ai-sdk/openai';
async function summarizeMeeting(audioFile: File) {
// 1. 전사
const transcription = await openai.audio.transcriptions.create({
file: audioFile,
model: 'whisper-1',
response_format: 'verbose_json', // timestamps 포함
});
// 2. 요약
const result = await generateObject({
model: anthropic('claude-sonnet-4-6'),
schema: z.object({
participants: z.array(z.string()),
topics: z.array(z.string()),
decisions: z.array(z.string()),
actionItems: z.array(z.object({
task: z.string(),
assignee: z.string(),
deadline: z.string().optional(),
})),
quotes: z.array(z.object({
speaker: z.string(),
text: z.string(),
timestamp: z.string(),
})),
}),
prompt: `Analyze this meeting transcript:\n${transcription.text}`,
});
return result.object;
}결과물 발송
// 이메일로 PDF 리포트
import { Resend } from 'resend';
const pdf = await generatePDF(summary); // pdf-lib 사용
await resend.emails.send({
from: 'Summarizer <noreply@example.com>',
to: user.email,
subject: `📄 요약 완료: ${summary.title}`,
react: SummaryEmail({ summary }),
attachments: [{ filename: 'summary.pdf', content: pdf }],
});다음 챕터
CH.44 "AI 코드 리뷰".
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
무료
월 $0 — 검증·시작 단계
AI 문서 요약을 무료 도구만으로 시작하는 방법을 알려줘.
소자본
월 $20~50 — MVP·초기 운영
월 $20~50 예산으로 AI 문서 요약을 검증·MVP 단계까지 진행하는 전략은?
프로덕션
월 $200~500 — 성장 단계
AI 문서 요약을 프로덕션 단계로 확장할 때 필요한 도구·운영 체계는?
스택
풀스택 — 도구 조합 분석
2026년 AI 문서 요약 관련 도구 5개를 조합한 추천 스택을 알려줘.
⭐ 이것만 기억하세요
AI 문서 요약: PDF/URL → 요약 리포트는 이 3가지만 확실히 잡으세요
1.PDF·URL·음성 모두 → 구조화 요약 자동
2.큰 문서는 Map-Reduce 패턴 (chunk별 → 통합)
3.저렴 모델 (Mini) + 고품질 모델 (Sonnet) 조합 = 비용 효율
공유하기
진행도 43 / 100