본문으로 건너뛰기
AIDevOps
  • Learn
  • Learning Paths
  • Practice
  • Open Source
  • Books
  • Engineering

    AI DevOpsAI 서비스 개발·운영 전체 지도LLMOpsLLM 배포·평가·관측실전 프로젝트AI Agent 프로젝트 실습

    Knowledge

    Docs기술 문서 모음Blog엔지니어링 아티클Plogger개발 기록 피드

    Validate

    Certification3단계 역량 인증 · 준비 중
AI Models
LlamaMistralGemmaDeepSeekQwen
🧠 AI Core
AI 입문 & 로드맵ML FundamentalsLLM Fundamentals|Python AIC++|PyTorchTensorFlowJAX
🤖 AI 실전 개발
AI 실전 입문 & 로드맵Hugging FaceLangChainLlamaIndexLLMOps|LangGraphMCPMulti-AgentAgent Evaluation
🧠 AI Agent 개발
금융 AI AgentLLM API 서버주식 투자 AgentAIOps AI Agent교육 AI Agent코딩 AI Agent
🌱 Spring Cloud
Spring 입문 & 로드맵Spring Cloud GatewaySpring BootJava|Spring AISpring SecuritySpring BatchSpring JPA
🐳 DevOps
DevOps 입문 & 로드맵LinuxDockerCI/CD|Kubernetes 기본K8s 심화/실무PrometheusGrafana
🧱 인프라
인프라 입문 & 로드맵NginxRedis
☁️ 클라우드
클라우드 입문 & 로드맵AWSGCPAzureNCPCloudflare
🎨 Frontend
Frontend 입문 & 로드맵JavaScriptTypeScript|ReactNext.js|VueNuxt
📱 Mobile
Mobile 입문 & 로드맵KotlinAndroidFlutter
⚙️ Backend
Backend 입문 & 로드맵Python 기본FastAPIDjangoFlask|CGoGinNode.js
💾 Database
DB 입문 & 로드맵공통 SQLOracleMySQLPostgreSQL|MongoDB벡터 DB
🧪 검증
k6JMeternGrinder
AIDevOps

Engineering AI. From Code to Production.
AI와 AI Agent를 개발하고 운영하기 위한 엔지니어링 학습 플랫폼

Learn

  • 전체 가이드
  • Learning Paths
  • Practice
  • Books

Resources

  • AI DevOps
  • LLMOps
  • 실전 프로젝트
  • Docs
  • Blog
  • Plogger
  • Open Source
  • Certification (준비 중)

Start Here

  • AI Core 로드맵
  • AI 실전 개발 로드맵
  • Spring Cloud 로드맵
  • DevOps 로드맵
  • 인프라 로드맵

 

  • 클라우드 로드맵
  • Frontend 로드맵
  • Mobile 로드맵
  • Backend 로드맵
  • Database 로드맵
© 2026 AI DevOps Korea. All rights reserved.
이용약관개인정보처리방침Sitemaptestforge.kr
  1. Home
  2. Learn
  3. AI Core
  4. Python AI
Python AI 개발 가이드

🐍 Python AI 가이드

Visitors

Python으로 LLM 애플리케이션과 AI Agent를 구축합니다. 비동기 LLM 호출, Pydantic 구조화 출력, ReAct 루프, FastAPI 스트리밍 서버, Agent 테스트까지 실무 흐름으로 정리했습니다.

  • Beginner · 입문
  • 업데이트 2026.05.25
  • 약 13분 읽기
  • 11개 섹션
  • 예제 코드 8개

포함된 Learning Path

이 가이드는 아래 경로의 한 단계입니다. 앞뒤 순서와 함께 학습해보세요.

  • AI Foundations →
  • AI Agent Engineer →
  • AI Application Engineer →
LLM 애플리케이션AI Agent 개발구조화 출력FastAPI 스트리밍 서버

관련 프레임워크 & 개발환경

🐍Python 기본→🔥PyTorch→TFTensorFlow→HFHugging Face→LCLangChain→LILlamaIndex→

목차

0 / 13
  1. 가이드 사용법
  2. 구조 다이어그램
  3. AI 생태계 지형도
  4. 환경 구성 (uv)
  5. 비동기 LLM 호출
  6. Pydantic v2 구조화 출력
  7. Agent 루프 직접 구현
  8. 동시성 & 배치 처리
  9. FastAPI Agent 서버
  10. Agent 테스트
  11. Python AI 설계
  12. 운영 기준
  13. 검증 전략
목차 13개 섹션
  1. 가이드 사용법
  2. 구조 다이어그램
  3. AI 생태계 지형도
  4. 환경 구성 (uv)
  5. 비동기 LLM 호출
  6. Pydantic v2 구조화 출력
  7. Agent 루프 직접 구현
  8. 동시성 & 배치 처리
  9. FastAPI Agent 서버
  10. Agent 테스트
  11. Python AI 설계
  12. 운영 기준
  13. 검증 전략

가이드 사용법

읽는 방향

Python AI를 실무 흐름으로 이해하기

Python으로 LLM 애플리케이션과 AI Agent를 구축합니다. 비동기 LLM 호출, Pydantic 구조화 출력, ReAct 루프, FastAPI 스트리밍 서버, Agent 테스트까지 실무 흐름으로 정리했습니다. 이 가이드는 개념을 나열하기보다, 실제 프로젝트에서 판단해야 하는 순서대로 내용을 따라갈 수 있게 구성했습니다.

핵심 관점

AI / LLM 시스템

모델과 프롬프트만 보지 않고, 데이터 흐름, 평가, 배포 이후의 운영 지표까지 한 번에 연결해서 봅니다.

LLM 애플리케이션AI Agent 개발구조화 출력FastAPI 스트리밍 서버

구조 다이어그램

글로 읽은 내용을 머릿속에 오래 남기려면 먼저 흐름을 그림으로 잡는 편이 좋습니다. 아래 두 그림은 Python AI를 학습할 때 계속 되돌아볼 수 있는 기준 지도입니다.

학습 흐름

다이어그램 렌더링 중…

아키텍처 관점

다이어그램 렌더링 중…

AI 생태계 지형도

Python AI를 처음 펼칠 때는 세부 명령보다 큰 그림이 먼저입니다. 이 섹션에서는 앞으로 배울 개념들이 어떤 문제를 풀기 위해 등장했는지부터 잡아봅니다.

Python은 AI/ML 개발의 사실상 표준 언어입니다. 어떤 레이어에서 무엇을 쓸지 파악하는 것이 Agent 설계의 출발점입니다.
레이어라이브러리역할
모델 실행transformers, vLLM, OllamaLLM 로딩 · 추론 · 서빙
Agent 오케스트레이션LangChain, LlamaIndex, smolagents도구 호출 · 메모리 · 라우팅
구조화 출력Pydantic v2, instructor, outlines스키마 검증 · JSON 강제
벡터 검색ChromaDB, Pinecone, pgvectorRAG 임베딩 저장소
API 서버FastAPI, LangServe스트리밍 엔드포인트
평가 & 추적RAGAS, LangSmith, deepeval품질 측정 · 트레이싱

환경 구성 (uv)

여기서는 환경 구성 (uv)을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.

uv는 pip보다 10~100배 빠른 패키지 매니저입니다. AI 프로젝트는 의존성이 복잡하므로 반드시 프로젝트별 가상환경을 분리하고 lock 파일로 재현 가능성을 보장하세요.
BASH
# uv 설치 (macOS/Linux)
curl -LsSf https://astral.sh/uv/install.sh | sh

# AI Agent 프로젝트 초기화
uv init my-agent && cd my-agent

# 핵심 패키지 추가 (pyproject.toml 자동 업데이트)
uv add langchain langchain-openai langchain-community
uv add pydantic fastapi uvicorn chromadb
uv add instructor ragas langsmith

# 재현 가능한 환경 — lock 파일로 정확한 버전 고정
uv run python main.py          # venv 자동 활성화
uv sync                        # lock 파일 기준 동기화

비동기 LLM 호출

여기서는 비동기 LLM 호출을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.

LLM 호출은 수백ms~수 초가 걸립니다. asyncio로 여러 모델을 동시에 호출하면 전체 응답 시간을 크게 줄일 수 있습니다. 프로덕션 Agent는 반드시 async 기반으로 설계하세요.
async_llm.pyPYTHON
import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI()

# ── 기본 비동기 호출 ──────────────────────────────
async def call_llm(prompt: str, model: str = "gpt-4o-mini") -> str:
    resp = await client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
    )
    return resp.choices[0].message.content

# ── 스트리밍 (토큰 단위 실시간 출력) ─────────────
async def stream_llm(prompt: str):
    async with client.chat.completions.stream(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
    ) as stream:
        async for chunk in stream:
            delta = chunk.choices[0].delta.content
            if delta:
                print(delta, end="", flush=True)

# ── 여러 프롬프트 동시 병렬 호출 ─────────────────
async def batch_call(prompts: list[str]) -> list[str]:
    return await asyncio.gather(*[call_llm(p) for p in prompts])

async def main():
    prompts = ["Python이란?", "Go란?", "Rust란?"]
    # 직렬: 순차 실행 (~3초)  vs  병렬: 동시 실행 (~1초)
    serial   = [await call_llm(p) for p in prompts]
    parallel = await batch_call(prompts)          # 약 3배 빠름

asyncio.run(main())

Pydantic v2 구조화 출력

여기서는 Pydantic v2 구조화 출력을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.

LLM의 자유 텍스트를 검증된 데이터 구조로 변환하는 것이 안정적인 Agent 구축의 핵심입니다. instructor 라이브러리는 OpenAI function calling을 활용해 Pydantic 모델을 자동으로 추출합니다.
BASH
uv add instructor
structured_output.pyPYTHON
import instructor
from openai import OpenAI
from pydantic import BaseModel, Field
from enum import Enum

client = instructor.from_openai(OpenAI())

class Priority(str, Enum):
    HIGH   = "high"
    MEDIUM = "medium"
    LOW    = "low"

class Task(BaseModel):
    title:    str        = Field(description="작업 제목")
    priority: Priority   = Field(description="우선순위")
    deadline: str | None = Field(description="마감일 YYYY-MM-DD")
    subtasks: list[str]  = Field(default_factory=list)

class ProjectPlan(BaseModel):
    goal:        str        = Field(description="프로젝트 목표")
    tasks:       list[Task] = Field(description="작업 목록")
    total_weeks: int        = Field(description="예상 소요 기간(주)")

# LLM이 자유 텍스트 대신 검증된 Pydantic 객체를 반환
plan = client.chat.completions.create(
    model="gpt-4o",
    response_model=ProjectPlan,
    messages=[{"role": "user",
               "content": "AI 챗봇 서비스를 3개월 안에 출시하는 계획을 짜줘"}]
)

for task in plan.tasks:
    print(f"[{task.priority.upper()}] {task.title} — 마감: {task.deadline}")
    for sub in task.subtasks:
        print(f"  • {sub}")

Agent 루프 직접 구현

여기서는 Agent 루프 직접 구현을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.

LangChain 없이 OpenAI function calling만으로 ReAct 루프를 직접 구현합니다. 프레임워크 내부 동작을 이해하면 복잡한 Agent도 자유롭게 커스터마이징할 수 있습니다.
agent_loop.pyPYTHON
import json, math
from openai import OpenAI
from typing import Callable

client = OpenAI()

# ── 도구 정의 ─────────────────────────────────────
def search_web(query: str) -> str:
    """웹에서 최신 정보를 검색합니다."""
    return f"[검색 결과] {query}: 관련 최신 정보..."   # 실제: Tavily API

def calculate(expression: str) -> str:
    """수식을 안전하게 계산합니다."""
    try:
        allowed = {k: v for k, v in math.__dict__.items() if not k.startswith("_")}
        return str(eval(expression, {"__builtins__": {}}, allowed))
    except Exception as e:
        return f"오류: {e}"

TOOLS: dict[str, Callable] = {"search_web": search_web, "calculate": calculate}
SCHEMAS = [
    {"type": "function", "function": {
        "name": "search_web", "description": "웹 검색",
        "parameters": {"type": "object",
                       "properties": {"query": {"type": "string"}},
                       "required": ["query"]}}},
    {"type": "function", "function": {
        "name": "calculate", "description": "수식 계산",
        "parameters": {"type": "object",
                       "properties": {"expression": {"type": "string"}},
                       "required": ["expression"]}}},
]

# ── ReAct 루프 ────────────────────────────────────
def run_agent(query: str, max_steps: int = 5) -> str:
    messages = [{"role": "user", "content": query}]
    for _ in range(max_steps):
        resp = client.chat.completions.create(
            model="gpt-4o", messages=messages, tools=SCHEMAS
        )
        msg = resp.choices[0].message
        messages.append(msg)
        if not msg.tool_calls:          # 도구 없음 → 최종 답변
            return msg.content
        for tc in msg.tool_calls:       # 도구 실행
            args   = json.loads(tc.function.arguments)
            result = TOOLS[tc.function.name](**args)
            print(f"  [Tool] {tc.function.name}({args}) → {result[:60]}")
            messages.append({"role": "tool", "tool_call_id": tc.id,
                              "content": result})
    return "최대 스텝 초과"

print(run_agent("삼성전자 현재 주가에 2.5를 곱하면?"))

동시성 & 배치 처리

여기서는 동시성 & 배치 처리을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.

프로덕션에서는 수백~수천 개의 문서를 처리해야 합니다. asyncio.Semaphore로 동시 호출 수를 제한해 API Rate Limit 오류를 방지하면서 최대 처리량을 유지하세요.
batch_processor.pyPYTHON
import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI()

async def summarize_one(sem: asyncio.Semaphore, doc: str, idx: int) -> dict:
    async with sem:   # 동시 최대 N개 호출 제한
        try:
            resp = await client.chat.completions.create(
                model="gpt-4o-mini",
                messages=[{"role": "user", "content": f"요약:\n{doc}"}],
                max_tokens=200,
            )
            return {"idx": idx, "summary": resp.choices[0].message.content,
                    "ok": True}
        except Exception as e:
            return {"idx": idx, "error": str(e), "ok": False}

async def batch_summarize(docs: list[str], concurrency: int = 10) -> list[dict]:
    sem     = asyncio.Semaphore(concurrency)
    results = await asyncio.gather(
        *[summarize_one(sem, doc, i) for i, doc in enumerate(docs)]
    )
    return sorted(results, key=lambda x: x["idx"])

# 1,000개 문서를 직렬 대비 ~10배 빠르게 처리
docs    = [f"문서 {i} 내용..." for i in range(100)]
results = asyncio.run(batch_summarize(docs))
print(f"완료: {sum(r['ok'] for r in results)}, "
      f"실패: {sum(not r['ok'] for r in results)}")

FastAPI Agent 서버

여기서는 FastAPI Agent 서버을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.

Agent를 FastAPI로 서빙하면 SSE 스트리밍 응답, Pydantic 자동 검증, 자동 OpenAPI 문서가 즉시 제공됩니다. 프론트엔드에서 `EventSource`로 토큰을 실시간으로 받을 수 있습니다.
agent_server.pyPYTHON
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
from openai import AsyncOpenAI
import json

app    = FastAPI(title="AI Agent API")
client = AsyncOpenAI()

class ChatRequest(BaseModel):
    message:    str
    model:      str = "gpt-4o"
    session_id: str = "default"

# ── SSE 스트리밍 엔드포인트 ──────────────────────
@app.post("/chat/stream")
async def chat_stream(req: ChatRequest):
    async def generate():
        async with client.chat.completions.stream(
            model=req.model,
            messages=[{"role": "user", "content": req.message}],
        ) as stream:
            async for chunk in stream:
                delta = chunk.choices[0].delta.content
                if delta:
                    yield f"data: {json.dumps({'token': delta})}\n\n"
        yield "data: [DONE]\n\n"

    return StreamingResponse(generate(), media_type="text/event-stream",
                             headers={"Cache-Control": "no-cache"})

# ── 구조화 출력 엔드포인트 ────────────────────────
class AnalysisResult(BaseModel):
    sentiment:  str
    key_points: list[str]
    confidence: float

@app.post("/analyze", response_model=AnalysisResult)
async def analyze(req: ChatRequest):
    import instructor
    inst = instructor.from_openai(AsyncOpenAI(), mode=instructor.Mode.JSON)
    return await inst.chat.completions.create(
        model=req.model, response_model=AnalysisResult,
        messages=[{"role": "user", "content": f"분석:\n{req.message}"}]
    )

# 실행: uvicorn agent_server:app --reload --port 8000

Agent 테스트

여기서는 Agent 테스트을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.

Agent 테스트는 LLM 호출을 Mock으로 대체하고, 도구 실행 경로와 구조화 출력 유효성을 검증합니다. 비결정적 LLM 출력은 RAGAS·deepeval로 품질을 정량 측정하세요.
test_agent.pyPYTHON
import pytest
from unittest.mock import patch, MagicMock
from pydantic import BaseModel, ValidationError

from agent_loop import calculate

# ── 도구 단위 테스트 ──────────────────────────────
def test_calculate_basic():
    assert calculate("2 + 3") == "5"
    assert calculate("10 ** 2") == "100"
    assert float(calculate("math.sqrt(2)")) == pytest.approx(1.414, rel=1e-3)

def test_calculate_blocks_dangerous():
    assert "오류" in calculate("__import__('os').system('ls')")

# ── LLM 호출 Mock 테스트 ──────────────────────────
def test_agent_calls_tool_then_answers():
    tool_call = MagicMock()
    tool_call.function.name      = "calculate"
    tool_call.function.arguments = '{"expression": "2 + 2"}'
    tool_call.id                 = "call_1"

    msg1 = MagicMock(); msg1.tool_calls = [tool_call]; msg1.content = None
    msg2 = MagicMock(); msg2.tool_calls = None;        msg2.content = "4입니다"

    r1 = MagicMock(); r1.choices[0].message = msg1
    r2 = MagicMock(); r2.choices[0].message = msg2

    with patch("agent_loop.client.chat.completions.create",
               side_effect=[r1, r2]):
        from agent_loop import run_agent
        assert "4" in run_agent("2 더하기 2는?")

# ── 구조화 출력 스키마 검증 ───────────────────────
class AgentOut(BaseModel):
    answer:     str
    sources:    list[str]
    confidence: float

def test_valid_schema():
    out = AgentOut(answer="결과", sources=["doc.pdf"], confidence=0.9)
    assert 0.0 <= out.confidence <= 1.0

def test_rejects_out_of_range():
    with pytest.raises(ValidationError):
        AgentOut(answer="", sources=[], confidence=1.5)

Python AI 실무 설계

Python AI 실무 설계은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.

Python 가이드는 AI Agent와 API 서버 흐름이 핵심이므로, 스크립트 중심 코드에서 벗어나 config, client, prompt, tool, evaluator를 분리하는 구조로 확장해야 합니다. Agent 루프는 상태 전이와 실패 처리를 명시하고, Pydantic 모델로 입력/출력 계약을 고정하는 것이 중급 이상의 기준입니다.
결정 지점확인 질문실무 기준
경계Python AI 코드에서 바뀌기 쉬운 부분은 어디인가?입출력, 설정, 외부 연동, 핵심 규칙을 분리합니다.
상태상태가 어디서 생성되고 어디서 사라지는가?상태 소유자와 수명 주기를 코드로 드러냅니다.
장애실패했을 때 호출자는 무엇을 받는가?timeout, fallback, error contract를 먼저 정합니다.

Python AI 운영 기준

이 섹션은 Python AI 운영 기준을 실무 관점에서 정리합니다. 개념을 외우기보다, 어떤 상황에서 이 기준을 꺼내 쓸지에 초점을 맞춰보세요.

운영에서는 async 호출 수, 모델 timeout, 토큰 사용량, 재시도 정책, 캐시 키 설계가 비용과 지연 시간을 좌우합니다. 배치 작업과 실시간 API를 같은 이벤트 루프에서 무제한 실행하지 말고, queue와 semaphore로 처리량을 제한해야 합니다.

Tip

  • Pydantic schema versioning
  • LLM timeout/retry budget
  • prompt regression set
  • token/cost metric

Python AI 검증 전략

Python AI 검증 전략은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.

Agent 품질은 함수 단위 테스트만으로 충분하지 않습니다. golden prompt set, 실패 응답 샘플, structured output schema, hallucination 판정 기준을 테스트 자산으로 관리해야 합니다.
품질 축검증 방법완료 기준
정확성정상/실패 케이스를 자동화합니다.핵심 시나리오가 재현 가능하게 통과합니다.
회귀 방지버그 수정 시 동일 케이스를 테스트로 남깁니다.같은 장애가 다시 배포되지 않습니다.
운영성로그, 메트릭, 알림을 확인합니다.문제가 생겼을 때 원인 추적 경로가 있습니다.
← 이전 가이드LLM Fundamentals다음 가이드 →C++