# ๐Ÿš€ ์‹ค๋ฌด์šฉ ๊ณ ๊ธ‰ ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž (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. ๊ธฐ๋ณธ ์ดˆ๊ธฐํ™” ```python 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. ๋ฉ”์‹œ์ง€ ์ถ”๊ฐ€ ๋ฐ ์ž๋™ ์š”์•ฝ ```python # ์„ธ์…˜ 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. ์š”์•ฝ ๋ฐฉ๋ฒ• ์„ค์ • ```python # ์š”์•ฝ ๋ฐฉ๋ฒ• ๋ณ€๊ฒฝ context_manager.set_summary_method("smart") # simple, smart, extractive # ํ˜„์žฌ ์š”์•ฝ ๋ฐฉ๋ฒ• ํ™•์ธ print(context_manager.current_summary_method) ``` ### 4. ์••์ถ•๋œ ์ปจํ…์ŠคํŠธ ์‚ฌ์šฉ ```python # ์••์ถ•๋œ ์ปจํ…์ŠคํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ (์š”์•ฝ ํฌํ•จ) 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. ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง ```python # ์ปจํ…์ŠคํŠธ ์š”์•ฝ ์ •๋ณด 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ํ„ด๋งˆ๋‹ค ์ž๋™ ์ •๋ฆฌ ์‹คํ–‰ ### ์••์ถ• ๊ณผ์ • 1. **๊ทธ๋ฃนํ™”**: ํ„ด ์š”์•ฝ๋“ค์„ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ๊ธฐ 2. **์žฌ์š”์•ฝ**: ๊ทธ๋ฃน๋ณ„๋กœ ์ฃผ์š” ์ฃผ์ œ ์ถ”์ถœ 3. **๋ณ‘ํ•ฉ**: ์ค‘๋ณต ์ œ๊ฑฐ ๋ฐ ํ†ตํ•ฉ 4. **๊ต์ฒด**: ๊ธฐ์กด ์š”์•ฝ์„ ์••์ถ•๋œ ์š”์•ฝ์œผ๋กœ ๊ต์ฒด ## ๐Ÿ“Š ์„ฑ๋Šฅ ์ตœ์ ํ™” ### ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ - ์„ธ์…˜๋ณ„ ๋…๋ฆฝ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ - ์ž๋™ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ - ์ ์ง„์  ์••์ถ•์œผ๋กœ ์„ฑ๋Šฅ ์ €ํ•˜ ์ตœ์†Œํ™” ### ํ† ํฐ ํšจ์œจ์„ฑ - ํ•œ๊ตญ์–ด/์˜์–ด๋ณ„ ์ •ํ™•ํ•œ ํ† ํฐ ์ถ”์ • - ์š”์•ฝ ํ’ˆ์งˆ๊ณผ ํ† ํฐ ์ˆ˜์˜ ๊ท ํ˜• - ์‹ค์‹œ๊ฐ„ ํ† ํฐ ์‚ฌ์šฉ๋Ÿ‰ ๋ชจ๋‹ˆํ„ฐ๋ง ## ๐Ÿ” ๋””๋ฒ„๊น… ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง ### ๋กœ๊ทธ ๋ ˆ๋ฒจ ```python import logging logging.basicConfig(level=logging.INFO) # ์ƒ์„ธํ•œ ๋กœ๊ทธ ํ™•์ธ logging.getLogger('lily_llm_core.context_manager').setLevel(logging.DEBUG) ``` ### ์ฃผ์š” ๋กœ๊ทธ ๋ฉ”์‹œ์ง€ - `๐Ÿ“ ํ„ด ์š”์•ฝ ์ƒ์„ฑ ์™„๋ฃŒ`: ํ„ด ์š”์•ฝ ์ƒ์„ฑ ์„ฑ๊ณต - `๐Ÿ—œ๏ธ ํ„ด ์š”์•ฝ ์••์ถ• ์™„๋ฃŒ`: ์••์ถ• ์‹คํ–‰ ์™„๋ฃŒ - `๐Ÿ”„ ์ž๋™ ์ •๋ฆฌ ์‹œ์ž‘`: ์ž๋™ ์ •๋ฆฌ ์‹คํ–‰ - `โœ… ์ปจํ…์ŠคํŠธ ์••์ถ• ์™„๋ฃŒ`: ์ปจํ…์ŠคํŠธ ์••์ถ• ์™„๋ฃŒ ## ๐Ÿงช ํ…Œ์ŠคํŠธ ### ํ…Œ์ŠคํŠธ ์‹คํ–‰ ```bash cd lily_generate_package python test_advanced_context.py ``` ### ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค 1. 8ํ„ด ๋Œ€ํ™” ์‹œ๋ฎฌ๋ ˆ์ด์…˜ 2. ์ž๋™ ์š”์•ฝ ์ƒ์„ฑ ํ™•์ธ 3. ์••์ถ• ์‹œ์Šคํ…œ ๋™์ž‘ ํ™•์ธ 4. ํ† ํฐ ์‚ฌ์šฉ๋Ÿ‰ ๋ชจ๋‹ˆํ„ฐ๋ง ## ๐Ÿ”— API ์—ฐ๋™ ### FastAPI ์—”๋“œํฌ์ธํŠธ ```python @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 ํ™œ์šฉ) - [ ] ๋‹ค๊ตญ์–ด ์ง€์› ํ™•์žฅ - [ ] ์‹ค์‹œ๊ฐ„ ํ˜‘์—… ์„ธ์…˜ ์ง€์› - [ ] ํด๋ผ์šฐ๋“œ ๋™๊ธฐํ™” ### ์„ฑ๋Šฅ ๊ฐœ์„  - [ ] ๋น„๋™๊ธฐ ์š”์•ฝ ์ฒ˜๋ฆฌ - [ ] ์บ์‹œ ์‹œ์Šคํ…œ ๋„์ž… - [ ] ๋ถ„์‚ฐ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ --- ## ๐Ÿ“ž ์ง€์› ๋ฐ ๋ฌธ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๊ฐœ์„  ์ œ์•ˆ์ด ์žˆ์œผ์‹œ๋ฉด ์ด์Šˆ๋ฅผ ๋“ฑ๋กํ•ด ์ฃผ์„ธ์š”. **์‹ค๋ฌด์šฉ ๊ณ ๊ธ‰ ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž๋กœ ํšจ์œจ์ ์ธ ๋Œ€ํ™” ํžˆ์Šคํ† ๋ฆฌ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค! ๐ŸŽ‰**