1 Azure OpenAI LLM이란?
Azure OpenAI Service는 OpenAI의 강력한 언어 모델을 Azure 클라우드에서 제공하는 엔터프라이즈급 서비스다.
RAG 시스템에서의 역할:
- 검색된 문서를 컨텍스트로 활용
- 자연어 답변 생성
- 컨텍스트 기반 추론
- 한국어 지원
엔터프라이즈 장점:
- 99.9% SLA 보장
- 데이터 주권 (한국 리전)
- Private Endpoint 지원
- RBAC 기반 접근 제어
2 Azure OpenAI 모델
2.1 GPT-4 Turbo (권장)
출시: 2024년 4월
사양:
- 컨텍스트 윈도우: 128K 토큰
- 출력 토큰: 4,096
- 가격: $10 / 1M 입력 토큰, $30 / 1M 출력 토큰
특징:
- 최고 성능 (복잡한 추론)
- JSON 모드 지원
- 함수 호출
- 비전 (이미지 이해)
RAG 권장: ✅ 높은 정확도 필요 시
2.2 GPT-4o (최신)
출시: 2024년 5월
사양:
- 컨텍스트 윈도우: 128K 토큰
- 출력 토큰: 4,096
- 가격: $5 / 1M 입력 토큰, $15 / 1M 출력 토큰 (GPT-4 대비 50% 저렴)
특징:
- GPT-4 수준 성능
- 2배 빠른 속도
- 멀티모달 (텍스트, 이미지, 오디오)
- 향상된 한국어 지원
RAG 권장: ✅ 최선의 선택 (성능 + 비용)
2.3 GPT-3.5 Turbo
사양:
- 컨텍스트 윈도우: 16K 토큰
- 가격: $0.50 / 1M 입력 토큰, $1.50 / 1M 출력 토큰
특징:
- 빠른 응답 속도
- 낮은 비용
- 간단한 질문에 적합
RAG 권장: 단순 FAQ 또는 개발/테스트 환경
2.4 모델 비교
| 모델 | 컨텍스트 | 입력 가격 | 출력 가격 | 성능 | 속도 | RAG 권장 |
|---|---|---|---|---|---|---|
| GPT-4o | 128K | $5/1M | $15/1M | ⭐⭐⭐⭐⭐ | ⚡⚡⚡ | ✅ 최고 |
| GPT-4 Turbo | 128K | $10/1M | $30/1M | ⭐⭐⭐⭐⭐ | ⚡⚡ | 고정밀도 |
| GPT-3.5 Turbo | 16K | $0.50/1M | $1.50/1M | ⭐⭐⭐ | ⚡⚡⚡ | 개발용 |
3 환경 설정
3.1 Azure OpenAI 리소스 생성
3.2 모델 배포
Azure OpenAI Studio에서:
1. “배포” → “+ 배포 만들기”
2. 모델 선택: gpt-4o
3. 배포 이름: gpt-4o
4. TPM: 80K (분당 토큰 제한)
3.3 환경 변수
.env 파일:
AZURE_OPENAI_ENDPOINT=https://openai-rag-prod.openai.azure.com/
AZURE_OPENAI_API_KEY=your-key-here
AZURE_OPENAI_DEPLOYMENT=gpt-4o
AZURE_OPENAI_API_VERSION=2024-02-01
4 기본 사용법
4.1 AzureChatOpenAI 초기화
from langchain_openai import AzureChatOpenAI
from dotenv import load_dotenv
import os
load_dotenv()
llm = AzureChatOpenAI(
azure_deployment=os.getenv("AZURE_OPENAI_DEPLOYMENT"),
openai_api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
temperature=0, # 결정적 출력
max_tokens=1000 # 최대 출력 길이
)
# 테스트
response = llm.invoke("Azure OpenAI란 무엇인가?")
print(response.content) 4.2 메시지 형식
5 RAG 프롬프트 엔지니어링
5.1 기본 RAG 프롬프트
5.2 한국어 최적화 프롬프트
5.3 구조화된 답변 프롬프트
5.4 Few-Shot 프롬프트
few_shot_prompt = ChatPromptTemplate.from_template(
"""다음 예시를 참고하여 질문에 답변하세요.
예시 1:
질문: Azure Blob Storage란?
답변: Azure Blob Storage는 Microsoft의 클라우드 객체 스토리지 서비스입니다.
대량의 비구조화 데이터를 저장할 수 있으며, Hot/Cool/Archive 티어를 제공합니다.
예시 2:
질문: Document Intelligence의 용도는?
답변: Document Intelligence는 OCR 및 문서 분석 서비스입니다.
PDF, 이미지에서 텍스트, 표, 레이아웃을 추출하여 RAG 시스템의 입력으로 사용합니다.
이제 실제 질문에 답변하세요:
컨텍스트:
{context}
질문: {question}
답변:"""
) 6 컨텍스트 관리
6.1 컨텍스트 압축
def compress_context(docs, max_tokens=3000):
"""컨텍스트를 토큰 제한 내로 압축"""
import tiktoken
encoding = tiktoken.encoding_for_model("gpt-4")
compressed = []
total_tokens = 0
for doc in docs:
tokens = encoding.encode(doc.page_content)
doc_tokens = len(tokens)
if total_tokens + doc_tokens <= max_tokens:
compressed.append(doc.page_content)
total_tokens += doc_tokens
else:
# 남은 공간에 맞춰 자르기
remaining = max_tokens - total_tokens
truncated = encoding.decode(tokens[:remaining])
compressed.append(truncated + "...")
break
return "\n\n".join(compressed)
# 사용
# context = compress_context(retrieved_docs, max_tokens=3000) 6.2 컨텍스트 재정렬
7 고급 RAG 패턴
7.1 Chain-of-Thought (CoT)
7.2 Self-Ask
7.3 인용 포함 답변
8 스트리밍
8.1 실시간 응답 스트리밍
# 스트리밍 활성화
streaming_llm = AzureChatOpenAI(
azure_deployment=os.getenv("AZURE_OPENAI_DEPLOYMENT"),
openai_api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
streaming=True,
temperature=0
)
# 스트리밍 실행
for chunk in streaming_llm.stream("Azure AI Search란?"):
print(chunk.content, end="", flush=True) 8.2 RAG 체인 스트리밍
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
# 스트리밍 RAG 체인
streaming_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| korean_prompt
| streaming_llm
| StrOutputParser()
)
# 실행
print("답변: ", end="")
for chunk in streaming_chain.stream("Azure AI Search의 장점은?"):
print(chunk, end="", flush=True)
print() 9 JSON 모드
9.1 구조화된 출력
json_llm = AzureChatOpenAI(
azure_deployment=os.getenv("AZURE_OPENAI_DEPLOYMENT"),
openai_api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
temperature=0,
model_kwargs={"response_format": {"type": "json_object"}}
)
json_prompt = ChatPromptTemplate.from_template(
"""다음 컨텍스트를 참고하여 질문에 JSON 형식으로 답변하세요.
컨텍스트:
{context}
질문: {question}
JSON 형식:
{{
"answer": "답변 내용",
"confidence": "high/medium/low",
"sources": ["출처1", "출처2"]
}}
JSON 응답:"""
)
# 사용
response = json_llm.invoke(
json_prompt.invoke({
"context": "Azure AI Search는 벡터 검색을 지원합니다.",
"question": "Azure AI Search의 주요 기능은?"
})
)
import json
result = json.loads(response.content)
print(f"답변: {result['answer']}")
print(f"신뢰도: {result['confidence']}") 10 함수 호출
10.1 도구 정의
from langchain_core.tools import tool
@tool
def search_documents(query: str) -> str:
"""문서를 검색하는 도구"""
# 실제로는 retriever 사용
return f"'{query}'에 대한 검색 결과입니다."
@tool
def get_metadata(doc_id: str) -> dict:
"""문서 메타데이터를 가져오는 도구"""
return {"id": doc_id, "title": "샘플 문서", "date": "2025-01-01"}
tools = [search_documents, get_metadata] 10.2 함수 호출 LLM
11 토큰 최적화
11.1 토큰 계산
import tiktoken
def count_tokens(text, model="gpt-4"):
"""토큰 수 계산"""
encoding = tiktoken.encoding_for_model(model)
return len(encoding.encode(text))
# 프롬프트 토큰 확인
prompt_text = korean_prompt.invoke({
"context": "샘플 컨텍스트",
"question": "샘플 질문"
}).to_string()
tokens = count_tokens(prompt_text)
print(f"프롬프트 토큰: {tokens}") 11.2 비용 추정
def estimate_cost(input_tokens, output_tokens, model="gpt-4o"):
"""비용 추정 (USD)"""
prices = {
"gpt-4o": {"input": 5.0, "output": 15.0}, # per 1M tokens
"gpt-4-turbo": {"input": 10.0, "output": 30.0},
"gpt-3.5-turbo": {"input": 0.5, "output": 1.5}
}
price = prices.get(model, prices["gpt-4o"])
input_cost = (input_tokens / 1_000_000) * price["input"]
output_cost = (output_tokens / 1_000_000) * price["output"]
return input_cost + output_cost
# 예시: 1000개 질문 (각 3000 입력, 500 출력 토큰)
total_cost = estimate_cost(3000 * 1000, 500 * 1000, "gpt-4o")
print(f"예상 비용: ${total_cost:.2f}") 12 콜백을 통한 모니터링
13 오류 처리
13.1 재시도 로직
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10)
)
def invoke_llm_with_retry(messages):
"""재시도 가능한 LLM 호출"""
return llm.invoke(messages)
# 사용
try:
response = invoke_llm_with_retry("테스트 질문")
print(response.content)
except Exception as e:
print(f"LLM 호출 실패: {e}") 13.2 Rate Limit 처리
14 참고 자료
14.1 공식 문서
14.2 LangChain
15 다음 단계
Azure OpenAI LLM 최적화가 완료되었다면, 이제 서버리스 배포를 준비하자:
👉 07-Azure-Functions-Apps.qmd - Azure Functions를 활용한 서버리스 RAG 배포