개념: 기본 LLM 상호 작용

개요

이 예제는 로컬 컴퓨터에서 실행되는 대규모 언어 모델(LLM)을 다루는 기본 개념을 소개합니다. 가장 간단한 상호 작용, 즉 모델을 로드하고 질문하는 방법을 시연합니다.

로컬 LLM이란?

로컬 LLM은 인터넷 연결이나 외부 API 호출 없이 전적으로 사용자의 컴퓨터에서 실행되는 AI 언어 모델입니다. 주요 이점:

  • 개인 정보 보호: 데이터가 사용자의 기기를 벗어나지 않음
  • 비용: 토큰당 API 비용 없음
  • 제어: 모델 선택 및 파라미터에 대한 완벽한 제어
  • 오프라인: 인터넷 연결 없이 작동

핵심 구성 요소

1. 모델 파일 (GGUF 형식)

┌─────────────────────────────┐
│   Qwen3-1.7B-Q8_0.gguf      │
│   (모델 가중치 파일)      │
│                             │
│  • 학습된 패턴 저장      │
│  • 효율성을 위해 양자화됨   │
│  • RAM/VRAM에 로드됨      │
└─────────────────────────────┘
  • GGUF: llama.cpp에 최적화된 파일 형식
  • 양자화(Quantization): 모델 크기를 줄임 (예: 16비트 대신 8비트)
  • 트레이드오프: 약간의 품질 손실 대비 더 작은 크기와 더 빠른 속도

2. 추론 파이프라인

사용자 입력 → 모델 → 생성 → 응답
    ↓          ↓          ↓           ↓
 "안녕하세요"   컨텍스트   샘플링    "안녕하세요!"

흐름도:

┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│ 프롬프트 │ --> │ 컨텍스트 │ --> │  모델    │ --> │ 응답     │
│          │     │ (메모리) │     │(가중치)  │     │ (텍스트) │
└──────────┘     └──────────┘     └──────────┘     └──────────┘

3. 컨텍스트 창

컨텍스트는 모델의 작업 메모리입니다.

┌─────────────────────────────────────────┐
│           컨텍스트 창                     │
│  ┌──────────────────────────────────┐    │
│  │ 시스템 프롬프트 (있는 경우)         │    │
│  ├────────────────────────────── ───┤    │
│  │ 사용자: "node-llama에 대해 아나요?" │    │
│  ├─────────────────────────────── ──┤    │
│  │ AI: "네, 익숙합니다..."           │    │
│  ├─────────────────────────────────┤    │
│  │ (더 많은 대화를 위한 공간)         │    │
│  └─────────────────────────────────┘    │
└─────────────────────────────────────────┘
  • 제한된 크기 (예: 2048, 4096 또는 8192 토큰)
  • 가득 차면 이전 메시지를 제거해야 함
  • 모든 이전 메시지가 다음 응답에 영향을 미침

LLM이 응답을 생성하는 방법

토큰 단위 생성

LLM은 문장 전체를 한 번에 생성하지 않습니다. 단어 조각인 토큰을 한 번에 하나씩 예측합니다.

프롬프트: "AI란 무엇인가?"

생성 과정:
"What is AI?" → [모델] → "AI"
"What is AI? AI" → [모델] → "is"
"What is AI? AI is" → [모델] → "a"
"What is AI? AI is a" → [모델] → "field"
... 중지 조건까지 계속

시각화:

입력 프롬프트
     ↓
┌─────────────┐
│   모델      │ → 토큰 1: "AI"
│ 처리 및 예측│ → 토큰 2: "is"
└─────────────┘ → 토큰 3: "a"
                → 토큰 4: "field"
                → ...

AI 에이전트를 위한 핵심 개념

1. 상태 비저장 처리 (Stateless Processing)

  • 컨텍스트를 유지하지 않는 한 각 프롬프트는 독립적입니다.
  • 모델은 다른 스크립트 실행 간에 메모리가 없습니다.
  • “에이전트”를 구축하려면 다음을 수행해야 합니다.
    • 프롬프트 간에 컨텍스트를 활성 상태로 유지
    • 대화 기록 유지
    • 도구/함수 추가 (이후 예제에서 다룸)

2. 프롬프트 엔지니어링 기본 사항

질문을 구성하는 방식이 응답에 영향을 미칩니다.

❌ 나쁨: "node-llama-cpp"
✅ 더 나음: "node-llama-cpp에 대해 아시나요?"
✅ 최고: "node-llama-cpp가 무엇인지, 그리고 어떻게 작동하는지 설명해 주세요."

3. 리소스 관리

LLM은 상당한 리소스를 소비합니다.

모델 로드
     ↓
┌─────────────────┐
│  RAM/VRAM 사용량 │  ← 모델은 기가바이트 필요
│  CPU/GPU 시간   │  ← 추론에 시간이 걸림
│  메모리 누수?    │  ← 제대로 정리해야 함
└─────────────────┘
     ↓
적절한 해제

이것이 에이전트에 중요한 이유

이 기본 예제는 AI 에이전트의 기반을 구축합니다.

  1. 에이전트는 “생각”하기 위해 LLM이 필요: 모델이 정보를 처리하고 응답을 생성합니다.
  2. 에이전트는 컨텍스트가 필요: 상호 작용 전반에 걸쳐 상태를 유지해야 합니다.
  3. 에이전트는 구조가 필요: 이후 예제에서는 도구, 메모리 및 추론 루프를 추가합니다.

다음 단계

기본 프롬프팅을 이해한 후 다음을 탐색하십시오.

  • 시스템 프롬프트: 모델에 특정 역할 또는 동작 부여
  • 함수 호출: 모델이 도구를 사용하도록 허용
  • 메모리: 세션 전반에 걸쳐 정보 유지
  • 추론 패턴: ReAct (추론 + 행동)와 같은 패턴

다이어그램: 전체 아키텍처

┌──────────────────────────────────────────────────┐
│            귀하의 애플리케이션                   │
│  ┌────────────────────────────────────────────┐  │
│  │         node-llama-cpp 라이브러리          │  │
│  │  ┌──────────────────────────────────────┐  │  │
│  │  │      llama.cpp (C++ 런타임)          │  │  │
│  │  │  ┌────────────────────────────────┐  │  │  │
│  │  │  │   모델 파일 (GGUF)             │  │  │  │
│  │  │  │   • Qwen3-1.7B-Q8_0.gguf       │  │  │  │
│  │  │  └────────────────────────────────┘  │  │  │
│  │  └──────────────────────────────────────┘  │  │
│  └────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────┘
           ↕
    ┌──────────────┐
    │  CPU / GPU   │
    └──────────────┘

이 계층적 아키텍처를 통해 기본 LLM 상호 작용 위에 정교한 AI 에이전트를 구축할 수 있습니다.