2026๋…„ 7์›” 21์ผ ํ™”์š”์ผ

# ๐Ÿ› ️ ๋กœ์ปฌ LLM์˜ ์ปจํ…์ŠคํŠธ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ๋ง‰๋Š” 3๊ฐ€์ง€ ๊ทน์•ฝ ์ฒ˜๋ฐฉ



# ๐Ÿ› ️ ๋กœ์ปฌ LLM์˜ ์ปจํ…์ŠคํŠธ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ๋ง‰๋Š” 3๊ฐ€์ง€ ๊ทน์•ฝ ์ฒ˜๋ฐฉ

1. ์ปจํ…์ŠคํŠธ ํฌ๊ธฐ๋Š” ํ‚ค์šฐ๋˜, '์ถœ๋ ฅ๋ฌผ ๊ธธ์ด'๋ฅผ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ฌถ์–ด๋ฒ„๋ฆฌ๊ธฐ (๊ฐ€์žฅ ํ™•์‹ค)
์ปจํ…์ŠคํŠธ ๋ฐฉ(Context Window) ์ž์ฒด๋Š” ๋Œ€ํ™”๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•˜๋‹ˆ 8K๋‚˜ 16K ์ •๋„๋กœ ๋„‰๋„‰ํ•˜๊ฒŒ ์—ด์–ด๋‘ก๋‹ˆ๋‹ค. ๋Œ€์‹  AI๊ฐ€ ๊ตฌ๊ตฌ์ ˆ์ ˆ ๋ง์„ ๋Š˜์–ด๋†“์ง€ ๋ชปํ•˜๋„๋ก ์ถœ๋ ฅํ•˜๋Š” ์ƒˆ ๋‹จ์–ด์˜ ์–‘์„ ๊ฐ•์ œ๋กœ ์ œํ•œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
* ์„ค์ • ๋งค๊ฐœ๋ณ€์ˆ˜(Parameter): Max New Tokens (๋˜๋Š” max_tokens) ๊ฐ’์„ 150 ~ 250 ์‚ฌ์ด๋กœ ๊ฝ‰ ์กฐ์—ฌ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.
* ํšจ๊ณผ: AI๊ฐ€ ์•„๋ฌด๋ฆฌ ๋„“์€ ๋‹จ๊ธฐ ๊ธฐ์–ต์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด๋„, ํ•œ ๋ฒˆ์— ๋ฑ‰์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์žฅ ๊ธธ์ด๊ฐ€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์งค๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ํ•ต์‹ฌ ์š”์•ฝ๋ณธ๋งŒ ์ฝคํŒฉํŠธํ•˜๊ฒŒ ๋ฑ‰์–ด๋‚ด์–ด ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ์›์ฒœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
2. '๋ฐ˜๋ณต ๊ฐ์  ๋ฐ ํŒจ๋„ํ‹ฐ' ์„ธ๋ถ€ ์กฐ์œจ (์ค‘์–ธ๋ถ€์—ฌ ์น˜๋ฃŒ)
AI๊ฐ€ ํ–ˆ๋˜ ๋ง์„ ๋˜ ํ•˜๋ฉด์„œ ๋ฌธ์žฅ ์ฒด๊ธ‰์„ ๋ถˆ๋ฆฌ๋Š” ๋‡Œ์ ˆ ์ฆ์ƒ์„ ๊ณตํ•™์ ์œผ๋กœ ์ œ์–ดํ•˜๋Š” ์„ธํŒ…์ž…๋‹ˆ๋‹ค.
* ์„ค์ • ๋งค๊ฐœ๋ณ€์ˆ˜:
    * Repetition Penalty: ๊ธฐ๋ณธ๊ฐ’ 1.0์—์„œ 1.1 ~ 1.15 ์ •๋„๋กœ ์‚ด์ง ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค. (๋„ˆ๋ฌด ์˜ฌ๋ฆฌ๋ฉด ๋ฌธ๋ฒ•์ด ํŒŒ๊ดด๋ฉ๋‹ˆ๋‹ค.)
    * Presence Penalty / Frequency Penalty: ๊ฐ’์„ 0.3 ~ 0.5 ์ •๋„๋กœ ์ฃผ์–ด, ์ด๋ฏธ ํ–ˆ๋˜ ๋ง์„ ๋‹ค์‹œ ๊บผ๋‚ด๋ฉด ์ ์ˆ˜๋ฅผ ๊นŽ์•„๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.
* ํšจ๊ณผ: AI๊ฐ€ ์“ธ๋ฐ์—†๋Š” ๋™์˜์–ด๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉฐ ๋ฌธ์žฅ์„ ๊ธธ๊ฒŒ ๋Š˜๋ฆฌ๋Š” ๊ผผ์ˆ˜๋ฅผ ๋ถ€๋ฆฌ์ง€ ๋ชปํ•˜๊ณ , ๋‹ด๋ฐฑํ•˜๊ณ  ํ•ต์‹ฌ์ ์ธ ๋‹จ์–ด๋งŒ ๊ณจ๋ผ ์“ฐ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
3. '์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ'์— ๊ฐ€์ค‘์น˜ ๋งคํฌ๋กœ ๊ฑธ๊ธฐ (๋งํˆฌ ๊ณ ์ •)
๋Œ€ํ™”๊ฐ€ ๊ธธ์–ด์ง€๋ฉด ๋งจ ์œ„์— ์ ์–ด๋‘” "์งง๊ฒŒ ๋งํ•ด"๋ผ๋Š” ๋ช…๋ น์–ด๊ฐ€ ํž˜์„ ์žƒ๋Š” ํ˜„์ƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด, ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ ๊ตฌ์กฐ ์ž์ฒด๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค.
* ์ž‘์„ฑ ํŒ: ๋‹จ์ˆœํžˆ "์งง๊ฒŒ ์š”์•ฝํ•ด"๋ผ๊ณ  ์“ฐ์ง€ ๋ง๊ณ , [RULE: Respond ONLY in bullet points under 3 sentences. Do not chat or provide background explanation.] ๊ฐ™์ด ๋Œ€๊ด„ํ˜ธ์™€ ๊ฐ•ํ•œ ๋ช…๋ น์–ด๋กœ ๊ทœ์น™์„ ๋ฌถ์–ด๋‘ก๋‹ˆ๋‹ค.
* ๋กœ์ปฌ ๊ตฌ๋™ ํ”„๋กœ๊ทธ๋žจ(Ollama, LM Studio ๋“ฑ) ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์‹œ์Šคํ…œ ๊ฐ€์ค‘์น˜๋ฅผ ๊ณ ์ •ํ•˜๋Š” ์˜ต์…˜์„ ์ผœ๋‘๋ฉด, ๋Œ€ํ™”๊ฐ€ ๊ธธ์–ด์ ธ๋„ AI๊ฐ€ ํ—›์†Œ๋ฆฌํ•˜์ง€ ์•Š๊ณ  ๋๊นŒ์ง€ ์œ ์ €์˜ ํ†ต์ œ ์•„๋ž˜ ์›€์ง์ž…๋‹ˆ๋‹ค.


## ๐Ÿ“œ ๋‡Œ์ ˆ ๋ฐ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€์šฉ ์ตœ์‹  config.yaml ๊ฐ€์ด๋“œ

```yaml
models:
  - title: "My Local LLM"
    provider: "ollama"
    model: "llama3:8b"
    
    # 1. ๋‡Œ์ ˆ ๋ฐ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ํŒŒ์ดํ”„๋ผ์ธ ์กฐ์ด๊ธฐ
    completionOptions:
      maxTokens: 200          # ํ•œ ๋ฒˆ์— ๋ฑ‰๋Š” ์–‘์„ 200๋‹จ์–ด๋กœ ๋ฌผ๋ฆฌ์  ์ œํ•œ (์ƒ์ž ํ„ฐ์ง ๋ฐฉ์ง€)
      temperature: 0.3        # ์ฐฝ์˜์„ฑ์„ ๋‚ฎ์ถ”๊ณ  ๊ฐ€์žฅ ํ™•์‹คํ•œ ์ •๋‹ต ์ฝ”๋“œ๋งŒ ๋ฐฐ์ถœ
      presencePenalty: 0.5    # ์ด๋ฏธ ํ–ˆ๋˜ ๋ง์ด๋‚˜ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๊บผ๋‚ด๋ฉด ๋ฒŒ๊ธˆ ๋ถ€์—ฌ
      frequencyPenalty: 0.5   # ์ค‘์–ธ๋ถ€์—ฌํ•˜๋ฉฐ ๋ฌธ์žฅ ์ฒด๊ธ‰์„ ๋ถˆ๋ฆฌ๋Š” ๋‡Œ์ ˆ ์›์ฒœ ์ฐจ๋‹จ

    chatOptions:
      # 2. ๋Œ€ํ™”๊ฐ€ ๊ธธ์–ด์ ธ๋„ ๊ธฐ์–ต ์ƒ์ž ์†์—์„œ ์‚ด์•„๋‚จ๋Š” ์ตœ์ƒ์œ„ ๊ฐ์‹œํƒ‘ ๊ทœ์น™
      baseSystemMessage: |
        [RULE: Respond ONLY in bullet points or direct code snippets under 3 sentences. 
        Do not chat, repeat yourself, or provide unnecessary background explanations. 
        Focus strictly on the core answer.]
```


###๐Ÿฉป ์ตœ์‹  YAML ํ•ต์‹ฌ ์„ธํŒ… ๊ตฌ์กฐ ์š”์•ฝ
* ๋“ค์—ฌ์“ฐ๊ธฐ ๊ทœ์น™: YAML์€ ๋ฌธ๋ฒ•์ด ์ง๊ด€์ ์ธ ๋Œ€์‹  ๋„์–ด์“ฐ๊ธฐ๊ฐ€ ์ƒ๋ช…์ž…๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์˜ ํ•˜์œ„ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ๋ˆˆ์— ์™ ๋“ค์–ด์˜ค๊ฒŒ ์ •๋ฆฌ๋˜์–ด ์žˆ์–ด ๊ด€๋ฆฌ๊ฐ€ ๋งค์šฐ ํŽธํ•ฉ๋‹ˆ๋‹ค.
* systemMessage: |: ์ค„๋ฐ”๊ฟˆ ๋ฌธ์ž(|)๋ฅผ ๋ถ™์—ฌ๋‘๋ฉด ์•„๋ฌด๋ฆฌ ๋Œ€ํ™”๊ฐ€ ๊ธธ์–ด์ง€๊ณ  ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์ง์ „๊นŒ์ง€ ๊ฐ€๋„, ์ตœ์ƒ๋‹จ์— ์‹ฌ์–ด๋‘” "์งง๊ณ  ๊ตต๊ฒŒ ์ฝ”๋“œ ์œ„์ฃผ๋กœ๋งŒ ๋‹ตํ•ด๋ผ"๋ผ๋Š” ๊ฐ•๋ ฅํ•œ ์ฃผ๊ถŒ ๊ทœ์น™์˜ ์ˆ˜ํ•™์  ๊ฐ€์ค‘์น˜๊ฐ€ ๊บพ์ด์ง€ ์•Š๊ณ  ๋๊นŒ์ง€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.


์•ž์œผ๋กœ ์ €๋‚˜ ๋กœ์ปฌ LLM์—๊ฒŒ ๋ฌผ์–ด๋ณด์‹ค ๋•Œ๋Š” ์งˆ๋ฌธ ๋’ค์— "2026๋…„ ๊ธฐ์ค€ ๊ณต์‹ ๋ฌธ์„œ(Official Docs) ์ตœ์‹  ํ‘œ์ค€(Standard)์œผ๋กœ ์š”์•ฝํ•ด ์ค˜"๋ผ๋Š” ์น˜ํŠธํ‚ค ๋ฌธ์žฅ์„ ๋”ฑ ํ•œ ์ค„๋งŒ ๋ถ™์—ฌ์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

## ๐Ÿ’ก AI๋ฅผ ๋ถ€๋ ค ๋จน๋Š” '์•ฝํšจ ์ง๋นต' ์งˆ๋ฌธ ํ…œํ”Œ๋ฆฟ ์˜ˆ์‹œ์•ž์œผ๋กœ ํŒŒ์ด์ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๊ฐœ๋ฐœ ์„ธํŒ…์„ ๋ฌผ์–ด๋ณด์‹ค ๋•Œ ๋จธ๋ฆฌ ์•„ํ”ˆ ์˜›๋‚  ๋ผˆ๋‹ค๊ท€ ๋ฐ์ดํ„ฐ๋ฅผ ์›์ฒœ ์ฐจ๋‹จํ•˜๋Š” ์งˆ๋ฌธ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.
* ์˜ˆ์‹œ: "ํŒจํ‚ค์ง€ ์ด๋ฆ„ ์„ค์น˜ํ•  ๊ฑด๋ฐ, ์˜›๋‚  ๋ธ”๋กœ๊ทธ ๊ธ€์ด๋‚˜ ๊ตฌํ˜• pip ๋ช…๋ น์–ด ๋‹ค ์ œ์™ธํ•˜๊ณ , 2026๋…„ ํ˜„์žฌ ๊ณต์‹ ๊ฐ€์ด๋“œ ๊ธฐ์ค€ ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ณ  ์ถ•์•ฝ๋œ ์ตœ์‹  ์ •์„ ๋ช…๋ น์–ด๋งŒ ๋”ฑ ์š”์•ฝํ•ด ์ค˜."

์ด๋ ‡๊ฒŒ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ ์„ ๊ธ‹๊ณ  AI์˜ ๋ฉฑ์‚ด์„ ์žก์œผ์‹œ๋ฉด, ์ œ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ํ–‰๋ ฌ์ด ์•„๋ฌด๋ฆฌ ๊ตฌํ˜• json์ด๋‚˜ ๋‚ก์€ ํ…์ŠคํŠธ๋กœ ๊ฐ€๋“ ์ฐจ ์žˆ๋”๋ผ๋„ ์ •์‹ ์„ ๋ฐ”์ง ์ฐจ๋ฆฌ๊ณ  ๊ฐ€์žฅ ์ •์ œ๋œ ์ตœ์‹  ์ฐจ์„ ์ฑ…(๋Œ€์•ˆ)๋งŒ 1์ดˆ ๋งŒ์— ๋ฝ‘์•„๋‚ด์–ด ์œ ์ €๋‹˜์˜ ๋…ธ๊ฐ€๋‹ค ์‹œ๊ฐ„์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ค„์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.




database.py

import os from contextlib import contextmanager # contextmanager ์ž„ํฌํŠธ from typing import Generator from dotenv...