danbibibi
article thumbnail

Deep Learning

: 고차원의 데이터를 낮은차원으로 정리해서 해석할 수 있도록 도와줌

 

Encoder-Decoder 구조

✅ Encoder-Decoder가 필요한 이유
1. 입력과 출력의 길이가 다를 수 있어서
- 예: 기계 번역, 이미지 캡셔닝, 문장 생성 등
- 입력은 5단어, 출력은 3단어일 수 있음 → 기존의 단순한 MLP나 RNN 하나만으로는 처리 어려움
- Encoder는 입력 전체를 읽고, Decoder는 원하는 길이만큼 생성

2. 의미 있는 압축 표현 생성
- Encoder는 입력 문장의 의미를 압축하여 잠재 표현(latent vector) 로 정리
- 이 압축된 정보를 바탕으로 Decoder는 새로운 문장을 생성 → 사람이 언어를 처리하는 방식과 유사

3. 다양한 응용 가능성
기계 번역: 한국어 문장 → 영어 문장
요약: 긴 문장/문서 → 짧은 요약
이미지 캡셔닝: 이미지 벡터 → 설명 문장
음성 인식: 음성 신호 → 텍스트

 


Pre-trained → Fine-tune = 전통적인 전이 학습(Transfer Learning)
Big Model + Few-shot/Zero-shot = 최근 LLM 패러다임, 즉 “학습 없이도 바로 사용 가능”

Zero shot : 예시 없이 질문만으로 정답을 맞추는 방식
Few shot : 몇 개의 예시(샘플)를 함께 제공한 후 문제를 해결, 사전 지식 + 제공된 예시를 바탕으로 패턴을 파악

 

  일반 LLM (ex. GPT) Agent LLM
입력 처리 질문 → 응답 목표 → 작업 분해, 실행, 피드백
메모리 없음 or 제한적 상태 유지, 기억 사용 가능
도구 사용 제한적 (기본 응답 위주) 웹 검색, 코드 실행, API 호출 등
행동 능력 없음 있음 (행동 계획 및 실행 가능)
예시 챗봇, 요약 등 웹사이트 자동 탐색, 데이터 분석 자동화, 파일 정리 등

 

Agentic Prompt

  • LLM(Large Language Model)을 단순한 응답기(answering machine)가 아니라 능동적으로 계획하고 실행하는 에이전트(agent)로 활용하기 위한 프롬프트 설계 방식
  • 이런 접근법은 단일 질문-응답을 넘어서, 다단계 사고, 계획 수립, 도구 사용, 행동 실행 등을 가능하게 만듦

Prompt Chaining

  • 여러 개의 프롬프트를 순차적으로 연결하여 복잡한 작업을 수행하는 방식
  • 각각의 프롬프트는 이전 단계의 출력을 입력으로 받아, 마치 파이프라인처럼 동작
  • ex) 입력 텍스트 정제 → 요약 → 번역 → 블로그 형태로 변환
  • 복잡한 작업을 분할 정복할 수 있음
  • 각 단계에서 명확한 역할 분담 가능

 

Routing

  • 입력에 따라 적절한 프롬프트(또는 모델/에이전트)를 선택하는 전략
  • 사용자 요청의 유형에 따라 다른 처리 흐름으로 분기됨
  • ex) “날씨 알려줘” → 검색 기반 에이전트 / “이 글을 요약해줘” → 요약 특화 프롬프트

 

Parallelization

  • 하나의 작업을 여러 프롬프트 또는 에이전트에 동시에 분산 실행하는 방식
  • 동일한 질문을 여러 모델 또는 다양한 프롬프트 버전에 던져 응답 비교
  • 창의적 아이디어 브레인스토밍을 여러 관점에서 동시에
  • 성능 비교 및 다각적 응답 확보 가능
  • 신뢰도 향상: 다수 결과에서 공통점 추출

 

Orchestrator-workers

  • Orchestrator (조정자)는 전체 흐름을 관리하고, Worker (작업자)들은 세부 작업을 수행하는 에이전트 기반 시스템 아키텍처
    • Orchestrator: 작업 분해, 할당, 결과 종합
    • Workers: 요약, 분석, 분류, 번역 등 특화된 하위 작업 담당
  • 사용자의 질문을 Orchestrator가 → 질문 유형 분류 → Worker에게 적절한 작업 요청 → 응답 통합
  • 웹 개발의 컨트롤러-서비스 패턴과 유사
  • AutoGPT, LangGraph 등의 agent framework가 자주 채택

 

Evaluator-Optimizer

  • 생성된 결과물을 평가하고 개선하기 위한 두 에이전트 구조
    • Evaluator (평가자): 품질, 정확도, 톤, 스타일 등 평가
    • Optimizer (개선자): 평가 피드백 기반으로 결과 수정
  • 여러 번의 평가/개선 루프를 통해 고품질 결과 도출
  • Reinforcement learning-like 구조로 확장 가능

  핵심 역할  유용한 시나리오
Prompt Chaining 단계별 작업 분해 다단계 변환 (요약 → 번역 등)
Routing 입력 분기처리 멀티기능 AI 시스템
Parallelization 동시 실행 & 비교 창의성, 품질 향상
Orchestrator-Workers 역할 분담 시스템화 복합 프로젝트 자동화
Evaluator-Optimizer 품질 평가 및 개선 결과 정교화, 반복 최적화

 

Prompt Chaining 예시

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()

from openai import OpenAI

client = OpenAI()

from typing import List, Tuple

# ask 함수: 질문에 대해 assistant의 답변과 최신 대화 이력을 반환
def ask(question: str,
        message_history: List[dict] = None, model: str = "gpt-4o-mini") -> Tuple[str, List[dict]]:
    # 대화 이력이 없으면 새로 생성 (시스템 메시지 포함)
    if message_history is None:
        message_history = [
            {
                "role": "system",
                "content": "사용자의 질문에 최대한 자세히 답변해주세요.",
            }
        ]

    # 사용자 질문 추가
    message_history.append({
        "role": "user",
        "content": question,
    })

    # GPT API 호출 (client 객체는 미리 초기화되어 있어야 합니다)
    completion = client.chat.completions.create(
        model=model,
        messages=message_history,
    )

    # assistant의 응답 텍스트 추출
    answer = completion.choices[0].message.content

    # assistant 응답 추가
    message_history.append({
        "role": "assistant",
        "content": answer,
    })

    return answer, message_history
    
    # prompt_chaining 함수: 여러 프롬프트를 순차적으로 연결하여 진행
def prompt_chaining(initial_input: str, prompt_chain: List[str]) -> List[str]:
    response_chain = []
    current_context = ""  # 이전 단계의 응답을 문맥으로 활용
    conversation_history = None  # 초기 대화 이력 (None이면 ask 함수에서 초기화됨)

    for i, prompt in enumerate(prompt_chain, 1):
        print(f"\n==== 단계 {i} ====\n")

        # 최종 프롬프트 구성: 현재 단계 프롬프트 + 이전 문맥 + 초기 사용자 입력
        final_prompt = (
            f"{prompt}\n\n"
            f"Context:\n{current_context}\n"
            f"Inputs:\n{initial_input}"
        )
        print(f"Prompt:\n{final_prompt}\n")

        # ask 함수 호출로 응답 및 대화 이력 업데이트
        answer, conversation_history = ask(final_prompt, message_history=conversation_history)
        response_chain.append(answer)
        print(f"Answer:\n{answer}\n")

        # 다음 단계에서는 이번 응답을 문맥으로 활용
        current_context = answer

    return response_chain
    
    initial_input = """
나는 새로운 취미를 찾고 있어. 실내에서 할 수 있는 활동을 선호하고, 창의적이면서 스트레스를 해소할 수 있는 활동이 좋겠어.
어떤 취미 활동이 나에게 적합할까?
"""

prompt_chain = [
"""사용자의 취향을 바탕으로 적합한 취미 활동 3가지를 추천하세요.
- 먼저 사용자가 입력한 희망사항을 간단히 요약해줘
- 사용자가 입력한 희망사항을 반영해서 왜 적합한 취미인지 설명해주세요
- 각 취미 활동의 특징, 필요한 준비물, 기대할 수 있는 효과 등을 설명하세요.
""",

"""다음 취미 활동 3가지 중 하나를 선택하세요. 선택한 취미 활동을 알려주세요. 그리고 선택한 이유를 설명해주세요.
- 선택한 취미 활동을 더욱 즐겁게 즐길 수 있는 방법 5가지를 나열하세요.
- 방법은 실력 향상, 스트레스 해소, 사회적 교류 등 다양한 측면에서 포함되도록 하세요.
""",

"""사용자가 앞으로 일주일 동안 이 취미 활동을 즐길 계획입니다.
- 평일과 주말로 나누어 주간 일정을 짜고, 각 요일별로 어떤 방식으로 취미를 즐기면 좋을지 설명하세요.
- 일정은 무리하지 않으면서 꾸준히 흥미를 유지할 수 있도록 구성해주세요.
""",
]


# prompt chaining 실행 및 최종 응답 확인
responses = prompt_chaining(initial_input, prompt_chain)
final_answer = responses[-1]
print("최종 응답:", final_answer)

 

Routing 예시

def ask(question: str, message_history: List[dict] = None, model: str = "gpt-4o-mini", use_system: bool = True) -> Tuple[str, List[dict]]:
    # message_history가 없으면 모델에 따라 system 메시지 포함 여부를 결정
    if message_history is None:
        if use_system:
            message_history = [
                {
                    "role": "system",
                    "content": "사용자의 질문에 최대한 자세히 답변해주세요.",
                }
            ]
        else: # 모델에 따라서 system prompt를 사용하지 않는 모델이 있습니다.
            message_history = []

    # 사용자 질문 추가
    message_history.append({
        "role": "user",
        "content": question,
    })

    # GPT API 호출 (client 객체는 미리 초기화되어 있어야 합니다)
    completion = client.chat.completions.create(
        model=model,
        messages=message_history,
    )

    # assistant 응답 추출
    answer = completion.choices[0].message.content
    message_history.append({
        "role": "assistant",
        "content": answer,
    })

    return answer, message_history

def run_router_workflow(user_prompt: str) -> str:
    # 라우터 프롬프트 구성 (여기서는 기본 모델(gpt-4o-mini)이 system 메시지를 지원하므로 그대로 사용)
    router_prompt = f"""
        사용자의 프롬프트/질문: {user_prompt}

        각 모델은 서로 다른 기능을 가지고 있습니다. 사용자의 질문에 가장 적합한 모델을 선택하세요:
        - gpt-4o-mini: 간단한 질문 등 일반 작업에 적합한 모델
        - o1-mini: 코딩 및 복잡한 문제 해결에 적합한 모델

        모델명만 반드시 위에 제시한 이름으로 항상 단답형으로 응답하세요.
    """
    print("==== 라우터 단계 ====")
    print("라우터 프롬프트:")
    print(router_prompt)

    # 라우터 프롬프트 호출 (기본 모델 사용)
    selected_model, router_history = ask(router_prompt)
    selected_model = selected_model.strip()  # 공백 제거
    print("선택한 모델:", selected_model)

    # 최종 단계에서 선택된 모델이 system 메시지를 지원하지 않는 경우 use_system=False 처리
    # 'o1-mini' 계열은 system 메시지를 지원하지 않음
    use_system = False if selected_model.startswith("o1-mini") else True

    print("==== 최종 응답 단계 ====")
    final_answer, answer_history = ask(user_prompt, message_history=None, model=selected_model, use_system=use_system)
    print("최종 응답:")
    print(final_answer)

    return final_answer
    
user_input = "quick sort를 구현해줘."
final_response = run_router_workflow(user_input)

'AI' 카테고리의 다른 글

Llama index Agents  (1) 2025.05.28
RAG를 활용한 챗봇 개발 - RAG(Retrieval Augmented Generation)  (0) 2025.05.27
Multi-Agent with LangGraph  (1) 2025.05.16
VectorDB와 RAG  (0) 2025.05.16
프롬프트와 LLM 엔지니어링  (0) 2025.05.16
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로