import "openai/shims/node"; import OpenAI from "openai"; export interface SummarizerOptions { maxChunkLength?: number; summaryLength?: number; focus?: string; dangerouslyAllowBrowser?: boolean; } export interface SummarizationResult { summary: string; fullText: string; metadata: Record; } export class WebpageSummarizer { private openai: OpenAI; private options: SummarizerOptions; constructor(apiKey: string, options: SummarizerOptions = {}) { this.openai = new OpenAI({ apiKey, dangerouslyAllowBrowser: true }); this.options = { maxChunkLength: 2000, summaryLength: 300, ...options, }; } public async summarize( content: string, metadata: Record = {} ): Promise { const chunks = this.chunkContent(content, this.options.maxChunkLength!); const summaries = await Promise.all( chunks.map((chunk) => this.summarizeChunk( chunk, this.options.summaryLength, this.options.focus ) ) ); const summary = summaries.join("\n"); return { summary, fullText: content, metadata, }; } private chunkContent(content: string, maxLen: number): string[] { const result: string[] = []; let i = 0; while (i < content.length) { result.push(content.slice(i, i + maxLen)); i += maxLen; } return result; } private async summarizeChunk( chunk: string, summaryLength = 300, focus?: string ): Promise { const prompt = `다음 웹페이지 본문을 ${summaryLength}자 이내로 핵심만 요약하세요.${ focus ? "\n요약 초점: " + focus : "" }\n\n본문:\n${chunk}`; const res = await this.openai.chat.completions.create({ model: "gpt-3.5-turbo", messages: [ { role: "system", content: "당신은 웹페이지 요약 전문가입니다." }, { role: "user", content: prompt }, ], max_tokens: summaryLength, temperature: 0.3, }); return res.choices[0].message?.content?.trim() || ""; } }