Spaces:
Sleeping
Sleeping
๐ ์ค๋ฌด์ฉ ๊ณ ๊ธ ์ปจํ ์คํธ ๊ด๋ฆฌ์ (Advanced Context Manager)
์ค์ ChatGPT, Gemini, Claude ๋ฑ์์ ์ฌ์ฉํ๋ ๋ฐฉ์์ ๋ชจ๋ฐฉํ ๊ณ ๊ธ ๋ฉ์์ง ์์ฝ ๋ฐ ํ์คํ ๋ฆฌ ์์ถ ์์คํ ์ ๋๋ค.
โจ ์ฃผ์ ๊ธฐ๋ฅ
๐ ํด๋ณ ๋ฉ์์ง ์์ฝ
- ๊ฐ ํด๋ง๋ค ์ฌ์ฉ์-์ด์์คํดํธ ๋ฉ์์ง ์์ ์๋์ผ๋ก ์์ฝ
- 3๊ฐ์ง ์์ฝ ๋ฐฉ๋ฒ ์ง์: simple, smart, extractive
- ์ฃผ์ ํค์๋ ์๋ ์ถ์ถ ๋ฐ ์ ์ฅ
๐๏ธ ํ์คํ ๋ฆฌ ์์ถ
- ์ผ์ ํ ํฐ ์ด์ ์์ด๋ฉด ๊ธฐ์กด ํ์คํ ๋ฆฌ๋ฅผ ์ฌ์์ฝ
- ๊ณ์ธต์ ์์ถ: ๊ฐ๋ณ ๋ฉ์์ง โ ํด ์์ฝ โ ์ธ์ ์์ฝ
- ํ ํฐ ์ ํ ๋ด์์ ๋ํ ํ๋ฆ ์ ์ง
๐ ์ค์๊ฐ ํ ํฐ ๊ด๋ฆฌ
- ํ๊ตญ์ด/์์ด๋ณ ํ ํฐ ์ ์๋ ์ถ์
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ค์๊ฐ ๋ชจ๋ํฐ๋ง
- ์๋ ์ ๋ฆฌ ๋ฐ ์์ถ ์คํ
๐๏ธ ์์คํ ๊ตฌ์กฐ
ConversationTurn (๋ํ ํด)
โโโ role: 'user' | 'assistant'
โโโ content: ์๋ณธ ๋ฉ์์ง
โโโ summary: ์์ฝ๋ ๋ฉ์์ง
โโโ tokens_estimated: ์ถ์ ํ ํฐ ์
TurnSummary (ํด ์์ฝ)
โโโ turn_id: ๊ณ ์ ์๋ณ์
โโโ user_message: ์ฌ์ฉ์ ๋ฉ์์ง
โโโ assistant_message: ์ด์์คํดํธ ๋ฉ์์ง
โโโ summary: ํด ์์ฝ
โโโ key_topics: ์ฃผ์ ์ฃผ์ ๋ค
โโโ tokens_estimated: ์ด ํ ํฐ ์
SessionSummary (์ธ์
์์ฝ)
โโโ session_id: ์ธ์
์๋ณ์
โโโ summary: ์ ์ฒด ์ธ์
์์ฝ
โโโ key_topics: ์ฃผ์ ์ฃผ์ ๋ค
โโโ total_turns: ์ด ํด ์
๐ ์ฌ์ฉ๋ฒ
1. ๊ธฐ๋ณธ ์ด๊ธฐํ
from lily_llm_core.context_manager import AdvancedContextManager
# ๊ณ ๊ธ ์ปจํ
์คํธ ๊ด๋ฆฌ์ ์์ฑ
context_manager = AdvancedContextManager(
max_tokens=2000, # ์ต๋ ํ ํฐ ์
max_turns=20, # ์ต๋ ํด ์
enable_summarization=True, # ์์ฝ ํ์ฑํ
summary_threshold=0.8, # 80% ๋๋ฌ ์ ์์ฝ ์์
max_summary_tokens=500 # ์์ฝ๋น ์ต๋ ํ ํฐ ์
)
2. ๋ฉ์์ง ์ถ๊ฐ ๋ฐ ์๋ ์์ฝ
# ์ธ์
ID ์ค์
session_id = "user_123"
# ์ฌ์ฉ์ ๋ฉ์์ง ์ถ๊ฐ (์๋ ์์ฝ ์์ฑ)
user_msg = "ํ์ด์ฌ์์ ๋ฆฌ์คํธ์ ํํ์ ์ฐจ์ด์ ์ด ๊ถ๊ธํด์."
context_manager.add_user_message(user_msg, metadata={"session_id": session_id})
# ์ด์์คํดํธ ์๋ต ์ถ๊ฐ (์๋ ์์ฝ ์์ฑ)
assistant_msg = "๋ฆฌ์คํธ๋ ๊ฐ๋ณ(mutable)์ด๊ณ , ํํ์ ๋ถ๋ณ(immutable)์
๋๋ค..."
context_manager.add_assistant_message(assistant_msg, metadata={"session_id": session_id})
# ํด ์์ฝ์ด ์๋์ผ๋ก ์์ฑ๋ฉ๋๋ค!
3. ์์ฝ ๋ฐฉ๋ฒ ์ค์
# ์์ฝ ๋ฐฉ๋ฒ ๋ณ๊ฒฝ
context_manager.set_summary_method("smart") # simple, smart, extractive
# ํ์ฌ ์์ฝ ๋ฐฉ๋ฒ ํ์ธ
print(context_manager.current_summary_method)
4. ์์ถ๋ ์ปจํ ์คํธ ์ฌ์ฉ
# ์์ถ๋ ์ปจํ
์คํธ ๊ฐ์ ธ์ค๊ธฐ (์์ฝ ํฌํจ)
compressed_context = context_manager.get_compressed_context(session_id)
# ๋ชจ๋ธ๋ณ ์ต์ ํ๋ ์ปจํ
์คํธ
polyglot_context = context_manager.get_context_for_model("polyglot", session_id)
llama_context = context_manager.get_context_for_model("llama", session_id)
5. ์ํ ๋ชจ๋ํฐ๋ง
# ์ปจํ
์คํธ ์์ฝ ์ ๋ณด
context_summary = context_manager.get_context_summary(session_id)
print(f"์ด ํด ์: {context_summary['total_turns']}")
print(f"์ถ์ ํ ํฐ ์: {context_summary['estimated_tokens']}")
# ์์ฝ ํต๊ณ
summary_stats = context_manager.get_summary_stats(session_id)
print(f"์ด ์์ฝ ์: {summary_stats['total_summaries']}")
print(f"์์ถ ๋น์จ: {summary_stats['compression_ratio']:.2f}")
๐ง ์์ฝ ๋ฐฉ๋ฒ ์์ธ
1. Simple (๊ฐ๋จํ ์์ฝ)
- ์ฒซ 100์ + ์ฃผ์ ํค์๋
- ๋น ๋ฅด๊ณ ํจ์จ์
- ํค์๋ ๊ธฐ๋ฐ ์ ๋ณด ๋ณด์กด
2. Smart (์ค๋งํธ ์์ฝ)
- ์ฒซ ๋ฌธ์ฅ + ๋ง์ง๋ง ๋ฌธ์ฅ + ์ค๊ฐ ์์ฝ
- ๋ฌธ๋งฅ ์ ๋ณด ์ต๋ํ ๋ณด์กด
- ๊ท ํ์กํ ์์ฝ ํ์ง
3. Extractive (์ถ์ถ์ ์์ฝ)
- ์ค์๋ ์ ์ ๊ธฐ๋ฐ ๋ฌธ์ฅ ์ ํ
- ํต์ฌ ์ ๋ณด ์ฐ์ ๋ณด์กด
- ๊ฐ์ฅ ์ ํํ ์์ฝ
๐๏ธ ์์ถ ์์คํ
์๋ ์์ถ ์กฐ๊ฑด
- ํด ์์ฝ์ด
max_turns์ด๊ณผ ์ - ํ ํฐ ์ฌ์ฉ๋์ด
summary_threshold๋๋ฌ ์ - 5ํด๋ง๋ค ์๋ ์ ๋ฆฌ ์คํ
์์ถ ๊ณผ์
- ๊ทธ๋ฃนํ: ํด ์์ฝ๋ค์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ๊ธฐ
- ์ฌ์์ฝ: ๊ทธ๋ฃน๋ณ๋ก ์ฃผ์ ์ฃผ์ ์ถ์ถ
- ๋ณํฉ: ์ค๋ณต ์ ๊ฑฐ ๋ฐ ํตํฉ
- ๊ต์ฒด: ๊ธฐ์กด ์์ฝ์ ์์ถ๋ ์์ฝ์ผ๋ก ๊ต์ฒด
๐ ์ฑ๋ฅ ์ต์ ํ
๋ฉ๋ชจ๋ฆฌ ํจ์จ์ฑ
- ์ธ์ ๋ณ ๋ ๋ฆฝ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
- ์๋ ๊ฐ๋น์ง ์ปฌ๋ ์
- ์ ์ง์ ์์ถ์ผ๋ก ์ฑ๋ฅ ์ ํ ์ต์ํ
ํ ํฐ ํจ์จ์ฑ
- ํ๊ตญ์ด/์์ด๋ณ ์ ํํ ํ ํฐ ์ถ์
- ์์ฝ ํ์ง๊ณผ ํ ํฐ ์์ ๊ท ํ
- ์ค์๊ฐ ํ ํฐ ์ฌ์ฉ๋ ๋ชจ๋ํฐ๋ง
๐ ๋๋ฒ๊น ๋ฐ ๋ชจ๋ํฐ๋ง
๋ก๊ทธ ๋ ๋ฒจ
import logging
logging.basicConfig(level=logging.INFO)
# ์์ธํ ๋ก๊ทธ ํ์ธ
logging.getLogger('lily_llm_core.context_manager').setLevel(logging.DEBUG)
์ฃผ์ ๋ก๊ทธ ๋ฉ์์ง
๐ ํด ์์ฝ ์์ฑ ์๋ฃ: ํด ์์ฝ ์์ฑ ์ฑ๊ณต๐๏ธ ํด ์์ฝ ์์ถ ์๋ฃ: ์์ถ ์คํ ์๋ฃ๐ ์๋ ์ ๋ฆฌ ์์: ์๋ ์ ๋ฆฌ ์คํโ ์ปจํ ์คํธ ์์ถ ์๋ฃ: ์ปจํ ์คํธ ์์ถ ์๋ฃ
๐งช ํ ์คํธ
ํ ์คํธ ์คํ
cd lily_generate_package
python test_advanced_context.py
ํ ์คํธ ์๋๋ฆฌ์ค
- 8ํด ๋ํ ์๋ฎฌ๋ ์ด์
- ์๋ ์์ฝ ์์ฑ ํ์ธ
- ์์ถ ์์คํ ๋์ ํ์ธ
- ํ ํฐ ์ฌ์ฉ๋ ๋ชจ๋ํฐ๋ง
๐ API ์ฐ๋
FastAPI ์๋ํฌ์ธํธ
@app.get("/context/summary/{session_id}")
async def get_context_summary(session_id: str):
return context_manager.get_context_summary(session_id)
@app.get("/context/compressed/{session_id}")
async def get_compressed_context(session_id: str):
return context_manager.get_compressed_context(session_id)
@app.post("/context/force-compress/{session_id}")
async def force_compression(session_id: str):
context_manager.force_compression(session_id)
return {"message": "๊ฐ์ ์์ถ ์๋ฃ"}
๐ ์ฑ๋ฅ ์งํ
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก
- 8ํด ๋ํ: ์๋ณธ 2,000 ํ ํฐ โ ์์ฝ 800 ํ ํฐ (60% ์ ์ฝ)
- 16ํด ๋ํ: ์๋ณธ 4,000 ํ ํฐ โ ์์ฝ 1,200 ํ ํฐ (70% ์ ์ฝ)
- 32ํด ๋ํ: ์๋ณธ 8,000 ํ ํฐ โ ์์ฝ 1,800 ํ ํฐ (77% ์ ์ฝ)
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋
- ๊ธฐ๋ณธ ๋ชจ๋: 2-3MB (8ํด ๊ธฐ์ค)
- ์์ฝ ๋ชจ๋: 1-2MB (8ํด ๊ธฐ์ค)
- ์์ถ ๋ชจ๋: 0.5-1MB (8ํด ๊ธฐ์ค)
๐จ ์ฃผ์์ฌํญ
์ ํ์ฌํญ
- ์์ฝ ํ์ง์ ์ ๋ ฅ ํ ์คํธ์ ๋ณต์ก๋์ ๋ฐ๋ผ ๋ฌ๋ผ์ง
- ๋งค์ฐ ์งง์ ๋ฉ์์ง(50์ ๋ฏธ๋ง)๋ ์์ฝํ์ง ์์
- ํ๊ตญ์ด/์์ด ์ธ ์ธ์ด๋ ๊ธฐ๋ณธ ํ ํฐ ์ถ์ ์ฌ์ฉ
๊ถ์ฅ์ฌํญ
- ์ค์ํ ์ ๋ณด๋ ์์คํ ํ๋กฌํํธ์ ํฌํจ
- ์ ๊ธฐ์ ์ธ ์์ถ ์คํ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ
- ์ธ์ ๋ณ ๋ ๋ฆฝ์ ์ธ ์ปจํ ์คํธ ๊ด๋ฆฌ
๐ฎ ํฅํ ๊ณํ
์์ ๋ ๊ธฐ๋ฅ
- AI ๊ธฐ๋ฐ ๊ณ ํ์ง ์์ฝ (LLM ํ์ฉ)
- ๋ค๊ตญ์ด ์ง์ ํ์ฅ
- ์ค์๊ฐ ํ์ ์ธ์ ์ง์
- ํด๋ผ์ฐ๋ ๋๊ธฐํ
์ฑ๋ฅ ๊ฐ์
- ๋น๋๊ธฐ ์์ฝ ์ฒ๋ฆฌ
- ์บ์ ์์คํ ๋์
- ๋ถ์ฐ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
๐ ์ง์ ๋ฐ ๋ฌธ์
๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ๊ฐ์ ์ ์์ด ์์ผ์๋ฉด ์ด์๋ฅผ ๋ฑ๋กํด ์ฃผ์ธ์.
์ค๋ฌด์ฉ ๊ณ ๊ธ ์ปจํ ์คํธ ๊ด๋ฆฌ์๋ก ํจ์จ์ ์ธ ๋ํ ํ์คํ ๋ฆฌ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค! ๐