Recent Posts
Recent Comments
반응형
«   2026/03   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

오늘도 공부

Full-Stack AI Agent Template: 몇 주 걸릴 AI 제품 인프라를 몇 분 만에 뽑아내는 생성형 템플릿 본문

AI

Full-Stack AI Agent Template: 몇 주 걸릴 AI 제품 인프라를 몇 분 만에 뽑아내는 생성형 템플릿

행복한 수지아빠 2026. 3. 20. 12:49
반응형

AI 앱을 만든다고 하면 많은 팀이 먼저 모델 호출 코드부터 떠올립니다. 그런데 실제로 시간을 잡아먹는 건 모델 API가 아닙니다. 인증, 대화 저장, 스트리밍, 관측성, 백그라운드 작업, 프런트엔드 연결, 운영 환경 구성이 진짜 비용입니다.
vstorm-co/full-stack-ai-agent-template는 바로 그 “제품화에 필요한 나머지 80%”를 통째로 템플릿화한 프로젝트입니다. FastAPI 백엔드와 Next.js 프런트엔드를 기본으로, AI 에이전트 프레임워크, WebSocket 스트리밍, 대화 저장, 인증, Redis, 관측성, 배포 구성을 조합해서 바로 실행 가능한 풀스택 AI 앱을 생성하는 CLI입니다. (GitHub)

이 프로젝트가 흥미로운 이유는 “AI 기능을 넣는 법”보다 “AI 제품을 운영 가능한 형태로 시작하는 법”에 더 집중하기 때문입니다. 저장소 소개와 README를 보면 이 템플릿은 PydanticAI, LangChain, LangGraph, CrewAI, DeepAgents 같은 AI 프레임워크 지원을 내세우면서도, 동시에 JWT/API Key 인증, 데이터베이스 선택, WebSocket 스트리밍, 관측성, Docker/Kubernetes 같은 운영 요소를 한 덩어리로 묶어 제공합니다. 즉, 데모가 아니라 서비스 뼈대를 빠르게 만드는 쪽에 가깝습니다. (GitHub)

 

 

GitHub - vstorm-co/full-stack-ai-agent-template: Production-ready Full-Stack AI Agent Template — FastAPI + Next.js with 5 AI f

Production-ready Full-Stack AI Agent Template — FastAPI + Next.js with 5 AI frameworks (PydanticAI, LangChain, LangGraph, CrewAI, DeepAgents), WebSocket streaming, tool approval UI, auth, multi-DB,...

github.com

 


프로젝트 소개

이 프로젝트의 실체는 “앱 자체”라기보다 생성기(generator) 입니다. 패키지 이름은 fastapi-fullstack이고, Python 3.11+ 환경에서 동작하는 CLI로 배포되며, 내부적으로 cookiecutter, click, questionary, pydantic 등을 사용해 사용자가 선택한 옵션에 따라 프로젝트를 생성합니다. 패키지 구조도 fastapi_gen + template 폴더로 나뉘어 있어, 생성기 코드와 실제 템플릿 소스가 분리되어 있습니다. (GitHub)

생성 결과물은 전형적인 풀스택 구조를 따릅니다. 백엔드는 FastAPI 기반으로 API, 서비스, 리포지토리, 에이전트, 워커, 마이그레이션 구조를 갖고, 프런트엔드는 Next.js 15 + React 19 + TypeScript + Tailwind CSS v4 기반으로 채팅 UI, 훅, 상태 관리까지 포함합니다. README에는 useChat, useWebSocket, Zustand 스토어, Playwright E2E 테스트 구조까지 명시되어 있어 단순 샘플보다 훨씬 “앱 스타터”에 가깝습니다. (GitHub)

누가 만들었는지도 비교적 분명합니다. pyproject.toml에는 작성자가 Vstorm으로 표기되어 있고, 저장소도 vstorm-co 조직에서 관리합니다. 현재 공개 템플릿 저장소이며 MIT 라이선스로 배포됩니다. 또한 패키지 메타데이터에서는 아직 Development Status가 Alpha로 분류되어 있어, 프로덕션 지향 설계 철학은 강하지만 API나 템플릿 형태는 계속 바뀔 수 있다는 점도 같이 봐야 합니다. (GitHub)


왜 이런 프로젝트가 등장했을까

AI 애플리케이션을 처음 붙일 때 많은 개발자가 다음 순서로 실패합니다.

  1. 일단 LLM 호출부터 붙인다.
  2. 스트리밍이 필요해져서 SSE나 WebSocket을 급히 추가한다.
  3. 대화 이력 저장이 필요해져서 DB 스키마를 나중에 설계한다.
  4. 인증, 권한, 운영 로깅, 에러 추적, 배포 설정이 뒤늦게 붙는다.
  5. 결국 “AI 기능”보다 주변 인프라 작업이 더 커진다.

이 템플릿은 그 흐름을 정반대로 뒤집습니다. README의 “Why This Template” 섹션은 AI/LLM 앱을 위해 필요한 요소로 타입 안전한 에이전트, WebSocket 실시간 스트리밍, 대화 저장, 인증, 레이트 리미팅, 관측성, 웹훅, 어드민 패널 같은 운영 기능을 먼저 제시합니다. 즉 “모델을 호출하는 코드”가 아니라 “운영 가능한 AI 제품의 기본 설계”를 출발점으로 둔 프로젝트입니다. (GitHub)

또 한 가지 중요한 배경은 프레임워크 전쟁입니다. 팀마다 PydanticAI를 선호할 수도 있고, LangChain/LangGraph를 선호할 수도 있습니다. 이 템플릿은 그 선택을 생성 시점으로 미룹니다. README와 AI Agent 문서에 따르면 생성 옵션으로 PydanticAI, LangChain, LangGraph, CrewAI 등을 선택할 수 있고, README는 기본 시나리오에서 PydanticAI와 LangChain을 중심으로 예시를 제공합니다. 즉, 특정 프레임워크에 올인하는 대신 “운영 구조는 공통으로 가져가고 에이전트 레이어만 바꾸는” 접근을 취합니다. (GitHub)

이 점이 실무에서 꽤 중요합니다. 에이전트 프레임워크는 바뀌기 쉽지만, 인증/DB/스트리밍/배포/모니터링 구조는 상대적으로 오래 갑니다. 이 템플릿은 변동성이 큰 LLM 레이어와, 바뀌기 어려운 제품 인프라 레이어를 분리하려는 의도가 강합니다. 이건 단순 보일러플레이트보다 더 좋은 설계 방향입니다. (GitHub)


핵심 기능

1) AI 에이전트 프레임워크를 생성 시점에 선택할 수 있다

README 기준으로 PydanticAI 또는 LangChain 중심의 생성이 가능하고, AI Agent 문서에서는 --ai-framework pydanticai, langchain, langgraph, crewai 같은 선택지를 보여줍니다. 저장소 설명에는 DeepAgents까지 포함되어 있습니다. 이것은 “프레임워크별 샘플 저장소 여러 개”를 유지하지 않고, 하나의 생성기에서 전략적으로 바꿔 끼우는 방식입니다. (GitHub)

개발자 관점에서 이 기능의 핵심은 단순한 옵션 추가가 아닙니다.
팀의 AI 레이어를 실험 가능하게 만든다는 점이 중요합니다.

  • PydanticAI가 필요하면 타입 안전성과 의존성 주입 중심 구조를 택할 수 있고
  • LangChain/LangGraph가 필요하면 그래프 기반 오케스트레이션 방향으로 갈 수 있으며
  • CrewAI 쪽이 필요하면 멀티 에이전트 협업 구성을 노릴 수 있습니다. (GitHub)

예를 들어 PydanticAI 통합 예시는 아래처럼 매우 직관적입니다.

from dataclasses import dataclass
from sqlalchemy.ext.asyncio import AsyncSession
from pydantic_ai import Agent, RunContext

@dataclass
class Deps:
    user_id: str | None = None
    db: AsyncSession | None = None

agent = Agent[Deps, str](
    model="openai:gpt-4o-mini",
    system_prompt="You are a helpful assistant.",
)

@agent.tool
async def search_database(ctx: RunContext[Deps], query: str) -> list[dict]:
    # ctx.deps를 통해 user_id, db 접근
    ...

이 방식의 장점은 툴 호출이 곧바로 애플리케이션 컨텍스트와 연결된다는 점입니다.
LLM 툴이 고립된 함수가 아니라, DB 세션과 사용자 컨텍스트를 받는 실제 서비스 로직 입구가 됩니다. 이 템플릿이 PydanticAI를 기본 옵션으로 미는 이유도 여기에 있습니다. (GitHub)


2) WebSocket 스트리밍이 “기본값”이다

많은 AI 템플릿이 REST 응답을 반환하는 수준에서 끝납니다. 하지만 실제 채팅 제품은 스트리밍이 UX의 핵심입니다. 이 저장소는 README와 AI Agent 문서 모두에서 WebSocket 기반 실시간 스트리밍을 중심 기능으로 설명합니다. WebSocket 엔드포인트에서 토큰 단위 이벤트를 전송하고, 툴 호출 이벤트까지 별도로 보낼 수 있도록 설계되어 있습니다. (GitHub)

문서에 실린 기본 핸들러 예시는 이런 흐름입니다.

@router.websocket("/ws")
async def agent_websocket(websocket: WebSocket):
    await websocket.accept()
    agent = AssistantAgent()
    history: list[dict[str, str]] = []

    while True:
        data = await websocket.receive_json()
        user_input = data.get("content", "")
        history = data.get("history", history)

        await websocket.send_json({"type": "start"})

        full_response = ""
        async for event in agent.iter(user_input, history):
            if isinstance(event, PartDeltaEvent):
                token = event.delta.content
                full_response += token
                await websocket.send_json({
                    "type": "token",
                    "content": token,
                })

            if hasattr(event, "tool_name"):
                await websocket.send_json({
                    "type": "tool_call",
                    "tool": {
                        "name": event.tool_name,
                        "args": event.args,
                    },
                })

        history.append({"role": "user", "content": user_input})
        history.append({"role": "assistant", "content": full_response})

        await websocket.send_json({"type": "end"})

이 코드가 의미하는 건 명확합니다.

  • 프런트는 단순히 최종 문자열 하나를 기다리지 않는다.
  • 토큰 단위 응답과 툴 실행 과정을 실시간으로 관찰할 수 있다.
  • 채팅 UI는 “모델이 생각하고 도구를 쓰는 과정”까지 보여줄 수 있다.

실무에서는 이 차이가 큽니다. 사용자 체감 속도, 디버깅 편의성, 툴 호출 가시성 모두 여기서 갈립니다. (GitHub)


3) 대화 저장 구조가 템플릿에 이미 들어 있다

AI 앱이 데모를 넘어서려면 결국 대화 저장이 필요합니다. 이 프로젝트는 Conversation 과 Message 모델을 별도 엔터티로 두고, 메시지의 역할(user, assistant, tool)과 tool_calls JSON 필드까지 저장하는 구조를 문서화합니다. 또 ConversationService를 통해 생성, 메시지 추가, 조회 같은 흐름을 서비스 레이어로 감쌉니다. (GitHub)

이 설계는 꽤 현실적입니다. 단순히 문자열 배열을 세션에 들고 있는 수준이 아니라, 나중에 아래 기능으로 확장하기 쉬운 모델이기 때문입니다.

  • 대화 목록
  • 세션 제목 자동 생성
  • 툴 호출 기록 조회
  • 사용자별 채팅 분리
  • 장기 메모리/리트리벌 연결
  • 감사 로그 및 운영 분석

즉, “대화 UI가 된다”가 아니라 “대화 데이터가 제품 데이터 모델이 된다”는 쪽에 가깝습니다. (GitHub)

예시 구조를 간단히 재구성하면 아래처럼 볼 수 있습니다.

class Conversation(Base):
    __tablename__ = "conversations"
    id = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid4)
    user_id = mapped_column(ForeignKey("users.id"), nullable=False)
    title = mapped_column(String(255), nullable=True)
    created_at = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at = mapped_column(DateTime(timezone=True), onupdate=func.now())

class Message(Base):
    __tablename__ = "messages"
    id = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid4)
    conversation_id = mapped_column(ForeignKey("conversations.id"), nullable=False)
    role = mapped_column(String(20), nullable=False)   # user, assistant, tool
    content = mapped_column(Text, nullable=False)
    tool_calls = mapped_column(JSON, nullable=True)

4) 백엔드가 “AI 코드”가 아니라 “서비스 코드” 구조를 따른다

이 저장소의 가장 좋은 부분 중 하나는 아키텍처 문서가 꽤 정직하다는 점입니다. 백엔드는 API Layer → Service Layer → Repository Layer → Database의 전형적인 레이어드 아키텍처를 따르고, 라우트는 얇게 유지하고 비즈니스 로직은 서비스로 위임하며, 리포지토리는 데이터 접근을 담당하도록 구분합니다. (GitHub)

이건 AI 앱에 특히 중요합니다.
왜냐하면 LLM 툴 함수가 커지면 곧바로 “에이전트 안에 비즈니스 로직이 섞이는 문제”가 생기기 때문입니다.

이 템플릿의 방향은 아래처럼 이해하면 쉽습니다.

  • 라우트는 HTTP/WebSocket 입구
  • 서비스는 업무 규칙과 오케스트레이션
  • 리포지토리는 DB 접근
  • 에이전트는 서비스 호출을 조합하는 얇은 레이어

즉, LLM이 앱의 중심이 아니라 앱의 한 인터페이스로 자리 잡습니다. 이 구조 덕분에 나중에 REST API, 백그라운드 작업, 관리자 기능과 AI 기능이 충돌하지 않습니다. (GitHub)

대표적인 흐름을 Mermaid로 그리면 이렇습니다.

이 다이어그램이 보여주는 핵심은 하나입니다.
에이전트가 모든 것을 직접 하지 않는다.
툴은 서비스로 위임되고, 서비스는 저장소와 외부 연동을 담당합니다. 그래서 유지보수가 쉬워집니다. (GitHub)


5) 운영 기능이 기본 옵션으로 붙는다

이 프로젝트는 AI 프레임워크보다 운영 환경 쪽이 더 강력할 수도 있습니다. README와 설정 문서 기준으로 다음을 조합할 수 있습니다.

  • 데이터베이스: PostgreSQL, MongoDB, SQLite, none
  • 인증: JWT, API Key, both, none
  • OAuth: Google
  • 백그라운드 작업: Celery, Taskiq, ARQ
  • 관측성: Logfire, LangSmith, Sentry, Prometheus
  • 기타: Redis, rate limiting, admin panel, webhooks, Docker, GitHub Actions, GitLab CI, Kubernetes (GitHub)

특히 --preset production 과 --preset ai-agent 같은 프리셋은 스타터 템플릿이 아니라 “조합 가능한 제품 생성기”에 더 가깝게 만듭니다. 스타트업이나 사내 PoC 팀이 가장 자주 하는 일이 바로 이 옵션 조합 실험인데, 이 프로젝트는 그 반복을 CLI 단계로 밀어 넣었습니다. (GitHub)


내부 구조를 어떻게 이해하면 좋을까

이 저장소는 사실 두 개의 프로젝트가 겹쳐 있습니다.

  1. 생성기 자체
  2. 생성된 결과물

이 구분을 이해해야 제대로 볼 수 있습니다.

1) 생성기 자체

저장소 루트에는 fastapi_gen, template, docs, tests 폴더가 있고, fastapi-fullstack CLI 엔트리포인트가 fastapi_gen.cli:main으로 연결됩니다. 즉 이 저장소는 코드 생성 도구입니다. (GitHub)

2) 생성된 결과물

README에 명시된 생성 결과 구조는 아래와 같습니다.

my_project/
├── backend/
│   ├── app/
│   │   ├── api/
│   │   ├── core/
│   │   ├── db/models/
│   │   ├── schemas/
│   │   ├── repositories/
│   │   ├── services/
│   │   ├── agents/
│   │   ├── commands/
│   │   └── worker/
│   ├── cli/
│   ├── tests/
│   └── alembic/
├── frontend/
│   ├── src/
│   │   ├── app/
│   │   ├── components/
│   │   ├── hooks/
│   │   └── stores/
│   └── e2e/
├── docker-compose.yml
├── Makefile
└── README.md

이 구조는 매우 실무적입니다.
특히 commands/ 와 worker/ 가 눈에 띕니다. 이건 단순 CRUD + 챗봇이 아니라, 운영 명령과 비동기 작업이 들어갈 것을 전제로 설계했다는 뜻입니다. README에는 Django 스타일 CLI 명령 자동 탐지도 따로 설명되어 있습니다. (GitHub)

이를 아키텍처 관점에서 다시 그리면 아래처럼 볼 수 있습니다.


실제로 언제 쓰면 좋은가

이 템플릿은 모든 AI 프로젝트에 맞지는 않습니다. 하지만 아래 경우에는 꽤 잘 맞습니다.

잘 맞는 경우

1) “챗봇”이 아니라 “제품”을 만들 때

인증, 대화 저장, 관측성, 배포까지 같이 필요하면 매우 잘 맞습니다. README가 강조하는 포인트도 정확히 이 부분입니다. (GitHub)

2) FastAPI + Next.js 스택에 익숙한 팀

생성 결과물의 기본 스택이 명확합니다. Python 백엔드와 React 기반 프런트를 동시에 운영하는 팀에게는 학습 비용이 낮습니다. (GitHub)

3) AI 프레임워크를 아직 확정하지 않은 팀

PydanticAI, LangChain, LangGraph, CrewAI 같은 선택지를 생성 시점에 바꿀 수 있기 때문에, 아키텍처는 유지하면서 에이전트 레이어만 실험하기 좋습니다. (GitHub)

4) 내부 업무용 에이전트 SaaS를 빠르게 띄우고 싶은 팀

웹훅, admin panel, rate limiting, background task, observability 같은 조합은 내부 운영 도구나 B2B SaaS에 특히 유용합니다. (GitHub)


아쉬운 점도 있다

이 프로젝트는 강력하지만, 몇 가지는 분명히 감안해야 합니다.

첫째, 패키지 메타데이터 기준으로 아직 Alpha 상태입니다. 따라서 템플릿 구조나 생성 옵션, 문서와 실제 구현의 차이가 앞으로 바뀔 가능성이 있습니다. (GitHub)

둘째, 저장소 설명은 5개 AI 프레임워크와 tool approval UI까지 크게 내세우지만, 현재 README와 문서에서 가장 자세히 설명되는 축은 PydanticAI, LangChain, WebSocket 스트리밍, 대화 저장, 운영 인프라입니다. 따라서 팀이 정말 DeepAgents나 특정 멀티에이전트 플로우를 핵심 기능으로 본다면, 생성 후 실제 템플릿 코드 검증은 한 번 더 필요합니다. 이 평가는 저장소 소개와 문서 간의 강조점 차이를 바탕으로 한 해석입니다. (GitHub)

셋째, 옵션이 많다는 건 장점이지만 동시에 의사결정 비용도 의미합니다. 템플릿이 모든 문제를 해결하는 건 아니고, 결국 생성 후에는 자기 팀의 서비스 경계에 맞게 서비스 레이어와 에이전트 툴 설계를 다시 해야 합니다. 다만 그건 템플릿의 한계라기보다, 이 프로젝트가 “제품 출발점”이지 “완성 제품”은 아니라는 뜻에 가깝습니다. (GitHub)


빠르게 시작하는 흐름

문서 기준으로 시작 방법은 꽤 간단합니다.

# 설치
uv tool install fastapi-fullstack

# 인터랙티브 실행
fastapi-fullstack

# AI 에이전트 프리셋으로 생성
fastapi-fullstack create my_ai_app --preset ai-agent

# 또는 프레임워크 지정
fastapi-fullstack create my_app --ai-agent --ai-framework pydantic_ai

그리고 생성 후에는 프로젝트 폴더로 이동해 의존성을 설치하고 개발 서버를 올리는 방식입니다. Docker 기반 실행도 별도로 제공됩니다. (GitHub)


한 줄 평가

이 저장소를 한 문장으로 요약하면 이렇습니다.

“LLM 호출 샘플”이 아니라, AI 제품을 실제 서비스 구조로 시작하게 해주는 풀스택 생성기입니다. (GitHub)

PydanticAI나 LangChain을 쓰는 것 자체는 이제 어렵지 않습니다. 어려운 건 그 주변의 제품 인프라입니다.
이 템플릿은 바로 그 지점을 정면으로 겨냥합니다.

그래서 이런 팀에게 추천할 만합니다.

  • 챗봇을 넘어 SaaS형 AI 앱을 만들고 싶은 팀
  • FastAPI + Next.js 기반으로 빠르게 MVP를 내야 하는 팀
  • 스트리밍, 인증, 대화 저장, 관측성을 처음부터 같이 가져가고 싶은 팀
  • AI 프레임워크를 실험하되 제품 아키텍처는 안정적으로 유지하고 싶은 팀

반대로 아주 작은 단일 스크립트형 에이전트나, 백엔드 없이 특정 AI 프레임워크만 실험하려는 경우에는 오히려 과할 수 있습니다.

반응형