feat: add summarization to pipeline (summarize + summary_sentences + summary_language)
This commit is contained in:
@@ -63,6 +63,9 @@ class PipelineIngestRequest(BaseModel):
|
||||
generate_html: bool = True
|
||||
translate: bool = True
|
||||
target_language: str = "ko"
|
||||
summarize: bool = False
|
||||
summary_sentences: int = 5
|
||||
summary_language: str | None = None
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
@@ -171,6 +174,9 @@ def pipeline_ingest(req: PipelineIngestRequest, _: None = Depends(require_api_ke
|
||||
generate_html=req.generate_html,
|
||||
translate=req.translate,
|
||||
target_language=req.target_language,
|
||||
summarize=req.summarize,
|
||||
summary_sentences=req.summary_sentences,
|
||||
summary_language=req.summary_language,
|
||||
)
|
||||
return {"status": "ok", "doc_id": result.doc_id, "added": result.added_chunks, "chunks": result.chunks, "html_path": result.html_path}
|
||||
|
||||
|
||||
@@ -25,6 +25,38 @@ class DocumentPipeline:
|
||||
self.output_dir = Path(output_dir)
|
||||
(self.output_dir / "html").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def summarize(self, parts: List[str], target_language: str = "ko", sentences: int = 5) -> List[str]:
|
||||
summarized: List[str] = []
|
||||
sys_prompt = (
|
||||
"당신은 전문 요약가입니다. 핵심 내용만 간결하게 요약하세요."
|
||||
)
|
||||
for p in parts:
|
||||
if not p.strip():
|
||||
summarized.append("")
|
||||
continue
|
||||
messages = [
|
||||
{"role": "system", "content": sys_prompt},
|
||||
{"role": "user", "content": (
|
||||
f"다음 텍스트를 {target_language}로 {sentences}문장 이내로 핵심만 요약하세요. 불필요한 수식어는 제거하고, 중요한 수치/용어는 보존하세요.\n\n{p}"
|
||||
)},
|
||||
]
|
||||
resp = self.ollama.chat(self.boost_model, messages, stream=False, options={"temperature": 0.2, "num_ctx": 32768})
|
||||
content = resp.get("message", {}).get("content") or resp.get("response", "")
|
||||
summarized.append(content.strip())
|
||||
# 최종 통합 요약(선택): 각 청크 요약을 다시 결합해 더 짧게
|
||||
joined = "\n\n".join(s for s in summarized if s)
|
||||
if not joined.strip():
|
||||
return summarized
|
||||
messages2 = [
|
||||
{"role": "system", "content": sys_prompt},
|
||||
{"role": "user", "content": (
|
||||
f"아래 부분 요약들을 {target_language}로 {max(3, sentences)}문장 이내로 다시 한번 통합 요약하세요.\n\n{joined}"
|
||||
)},
|
||||
]
|
||||
resp2 = self.ollama.chat(self.boost_model, messages2, stream=False, options={"temperature": 0.2, "num_ctx": 32768})
|
||||
content2 = resp2.get("message", {}).get("content") or resp2.get("response", "")
|
||||
return [content2.strip()]
|
||||
|
||||
def translate(self, parts: List[str], target_language: str = "ko") -> List[str]:
|
||||
translated: List[str] = []
|
||||
sys_prompt = (
|
||||
@@ -58,9 +90,30 @@ h1{{font-size: 1.6rem; margin-bottom: 1rem;}}
|
||||
html_path.write_text(html, encoding="utf-8")
|
||||
return str(html_path)
|
||||
|
||||
def process(self, *, doc_id: str, text: str, index, generate_html: bool = True, translate: bool = True, target_language: str = "ko") -> PipelineResult:
|
||||
def process(
|
||||
self,
|
||||
*,
|
||||
doc_id: str,
|
||||
text: str,
|
||||
index,
|
||||
generate_html: bool = True,
|
||||
translate: bool = True,
|
||||
target_language: str = "ko",
|
||||
summarize: bool = False,
|
||||
summary_sentences: int = 5,
|
||||
summary_language: str | None = None,
|
||||
) -> PipelineResult:
|
||||
parts = chunk_text(text, max_chars=1200, overlap=200)
|
||||
translated = self.translate(parts, target_language=target_language) if translate else parts
|
||||
|
||||
if summarize:
|
||||
# 요약 언어 기본값: 번역 언어와 동일, 번역 off면 ko로 요약(설정 없을 때)
|
||||
sum_lang = summary_language or (target_language if translate else "ko")
|
||||
summarized_parts = self.summarize(parts, target_language=sum_lang, sentences=summary_sentences)
|
||||
working_parts = summarized_parts
|
||||
else:
|
||||
working_parts = parts
|
||||
|
||||
translated = self.translate(working_parts, target_language=target_language) if translate else working_parts
|
||||
|
||||
to_append: List[IndexRow] = []
|
||||
for i, t in enumerate(translated):
|
||||
@@ -70,7 +123,7 @@ h1{{font-size: 1.6rem; margin-bottom: 1rem;}}
|
||||
|
||||
html_path: str | None = None
|
||||
if generate_html:
|
||||
title_suffix = "번역본" if translate else "원문"
|
||||
title_suffix = "요약+번역본" if (summarize and translate) else ("요약본" if summarize else ("번역본" if translate else "원문"))
|
||||
html_path = self.build_html(doc_id, title=f"문서 {doc_id} ({title_suffix})", ko_text="\n\n".join(translated))
|
||||
|
||||
return PipelineResult(doc_id=doc_id, html_path=html_path, added_chunks=added, chunks=len(translated))
|
||||
|
||||
Reference in New Issue
Block a user