2026. 7. 23. 16:05ㆍAI 기반 프론트엔드 웹개발자 양성과정

[Streamlit · Gradio · Claude Code]
Python 웹앱 만들기 + AI 코딩 CLI
2026.07.23 · 학습 범위: Streamlit, Gradio, Claude Code(로드맵 01~19)
📋 오늘 다룬 것들
오늘은 "내가 만든 AI를 화면으로 보여주는" 하루였다. Python만으로 웹 대시보드를 만드는 Streamlit, 함수 하나로 웹앱을 뚝딱 만드는 Gradio로 CCTV 실시간 탐지·번역기·YOLO 탐지기를 웹으로 띄웠다. 그리고 지금 이 실습을 도와준 도구인 Claude Code(AI 코딩 CLI) 자체의 명령어·CLAUDE.md·프롬프트·협업까지 로드맵으로 정리했다.
📊 Streamlit — Python 대시보드
Streamlit은 Python만으로 웹 앱을 뚝딱 만드는 도구. HTML·CSS·JS를 몰라도 AI 데모·대시보드를 즉시 만들고, streamlit run 파일.py 한 줄로 브라우저에서 실행된다.
# 가상환경 활성화 conda activate pyweb310 # 설치 pip install streamlit pip install ultralytics streamlit # 실행 streamlit run v19_01_streamlit_b.py
| 함수 | 역할 |
|---|---|
st.set_page_config() | 페이지 레이아웃·제목 설정(코드 최상단) |
st.empty() | 나중에 채울 빈 공간(placeholder) 예약 |
st.columns(n) | 화면을 n개 컬럼으로 분할 |
placeholder.image() | 예약 공간에 이미지(프레임) 갱신 |
placeholder.plotly_chart() | 예약 공간에 Plotly 그래프 갱신 |
① 기본 CCTV 실시간 탐지
빈 액자(st.empty())를 만들어 두고, 루프에서 YOLO 탐지 결과를 그 액자에 한 장씩 덮어써 슬라이드 쇼처럼 실시간 영상을 보여준다.
import streamlit as st from ultralytics import YOLO import cv2 st.set_page_config(layout="wide") # 넓게 (반드시 맨 위) frame_placeholder = st.empty() # 사진 갈아끼울 빈 액자 cap = cv2.VideoCapture(stream_url) model = YOLO("yolo11n.pt") while cap.isOpened(): success, frame = cap.read() if not success: break annotated = model(frame)[0].plot() frame_placeholder.image(annotated, channels="BGR") # 액자 갱신
set_page_config(layout="wide")는 반드시 코드 최상단에 있어야 동작한다. OpenCV는 색 순서가 BGR이라 channels="BGR"를 명시해야 Streamlit에서 색이 제대로 나온다. st.empty() placeholder를 루프에서 .image()로 계속 덮어써야 실시간 효과가 난다.② 컬럼 레이아웃 + 실시간 그래프
화면을 좌우 2칸으로 쪼개 왼쪽엔 영상, 오른쪽엔 탐지 개수 막대 그래프를 동시에 갱신한다. Plotly로 종류별 개수를 매 프레임 다시 그린다.
col1, col2 = st.columns(2) # 좌·우 2칸 with col1: frame_placeholder = st.empty() with col2: chart_placeholder = st.empty() @st.cache_resource # 무거운 모델은 1회만 로드 def load_model(): return YOLO("yolo11n.pt") model = load_model() # 탐지된 클래스 이름 모으기 → 개수 집계 → 막대그래프 labels = [model.names[int(c)] for c in results[0].boxes.cls] df = pd.DataFrame({"Object": labels}).value_counts().reset_index(name="Count") fig = px.bar(df, x="Object", y="Count", color="Object", text="Count") chart_placeholder.plotly_chart(fig, key=f"chart_{time.time()}")
@st.cache_resource는 무거운 AI 모델을 딱 한 번만 불러온다(화면 조작으로 스크립트가 재실행돼도 캐시에서 즉시 반환 → 안 쓰면 매번 새로 읽어 느림). Plotly 차트는 매 프레임 key=f"chart_{time.time()}"로 고유 key를 줘야 위젯 충돌이 안 난다.🎨 Gradio — 함수 하나로 웹앱
Gradio는 Python 함수만 있으면 웹 화면을 만들어주는 도구. HTML·CSS 없이 AI 데모를 만들고 launch(share=True)로 인터넷 주소까지 발급한다.
# 설치
pip install gradio deep-translator
ImportError: numpy.core.multiarray failed to import가 나면 — gradio 잘못이 아니라 numpy 2 버전 충돌이다(numpy 2부터 numpy.core→numpy._core로 바뀜, 옛 pandas·matplotlib이 옛 이름을 부름). gradio는 내부에서 pandas를 불러오다 터지는 피해자. 해결: pip install -U pandas matplotlib로 최신판으로 갈아끼운다(numpy를 1.x로 내리는 건 비권장).| 파라미터 | 역할 | 예시 |
|---|---|---|
fn | 실행할 함수 | fn=say_hello |
inputs | 입력 컴포넌트 | "text", gr.Image(type="numpy") |
outputs | 출력 컴포넌트 | "text", gr.Image() |
launch(share=True) | 공개 URL 생성(72시간) | — |
① 기본 웹앱 (Hello)
함수 정의 → gr.Interface 연결 → launch 세 단계로 끝나는 가장 쉬운 첫 웹앱.
def say_hello(name): return "Hello, " + name gr.Interface(fn=say_hello, inputs="text", outputs="text").launch(share=True)
② 번역 웹앱
구글 번역 라이브러리에 Gradio 화면만 입혀 5줄로 완성한 영한 번역기.
from deep_translator import GoogleTranslator def trans_en_to_ko(text): return GoogleTranslator(source="en", target="ko").translate(text) gr.Interface(fn=trans_en_to_ko, inputs="text", outputs="text", title="번역기", description="영어 → 한국어").launch()
③ YOLO 이미지 탐지
사진을 올리면 YOLO가 사물을 찾아 박스를 그려준다. gr.Image(type="numpy")로 이미지를 숫자 배열로 받아 모델에 바로 넘긴다.
def det_image(image): return model(image)[0].plot() gr.Interface(fn=det_image, inputs=gr.Image(type="numpy"), outputs=gr.Image(), title="YOLO 이미지 객체 탐지").launch()
gr.Image(type="numpy") — type을 안 적으면 PIL 객체로 들어가 오류가 난다. YOLO엔 숫자 배열(numpy)로 넘겨야 한다. 출력의 gr.Image()는 배열도 자동으로 그림으로 표시한다.④ gr.Blocks 통합 앱 (탭 3개)
인사·번역·YOLO를 탭 3개로 묶어 한 앱에 담았다. 함수는 그대로 두고 화면 짜는 부분만 gr.Blocks로 바꾼다.
with gr.Blocks() as gr_web: gr.Markdown("# 내가 만든 AI 앱 모음") with gr.Tab("번역"): en = gr.Textbox(label="영어") ko = gr.Textbox(label="한국어") gr.Button("번역").click(trans_en_to_ko, en, ko) # (함수, 입력칸, 출력칸) gr_web.launch()
| 비교 | gr.Interface | gr.Blocks |
|---|---|---|
| 화면 | Gradio가 알아서 | 내가 쓴 순서대로 배치 |
| 기능 개수 | 1개 | 여러 개(탭·행·열) |
| 실행 시점 | 입력하면 자동 | .click()으로 내가 정함 |
name_box) 나중 것이 앞 것을 덮어써 엉뚱한 칸에 결과가 나온다. .click()은 칸을 만든 with 블록 안에, launch()는 with 밖에 둔다. 버튼만 만들고 .click()을 안 붙이면 눌러도 아무 일이 없다.🤖 Claude Code — AI 코딩 CLI (로드맵 01~19)
Claude Code는 Anthropic이 만든 터미널용 AI 코딩 도구. 지금 이 정리도 Claude Code로 만들고 있어서, 도구 자체를 제대로 뜯어봤다.
# 01 설치 (Node.js 18+) npm install -g @anthropic-ai/claude-code claude --version # 확인 후 claude 로 실행
02~03 · 명령어
세션 안에서 쓰는 슬래시 명령어. 새 프로젝트는 /init으로 시작한다.
| 명령어 | 설명 |
|---|---|
/init | CLAUDE.md 자동 생성(프로젝트 설정) |
/help · /clear | 도움말 · 대화 초기화 |
/compact | 긴 대화 요약·압축(컨텍스트 절약) |
@파일 | 특정 파일만 수정 지정(@src/main.py) |
! prefix | 터미널 명령 즉시 실행(!ls -la) |
/model · /btw | 모델 전환 · 작업 중단 없이 간단 질문 |
04 · 14 · 15 — 작동 모드 · 모델 · Effort
Shift+Tab으로 작동 모드 3가지를 순환한다: default(매번 확인) → auto(자동 수행) → plan(계획 먼저 작성 후 승인). 작업 성격에 따라 모델(Opus=복잡, Sonnet=일반, Haiku=빠름)과 Effort(low~max, 높을수록 깊은 사고·토큰↑)를 고른다.
claude --dangerously-skip-permissions(bypassPermissions) — 모든 작업을 확인 없이 자동 실행하므로 신뢰 가능한 격리 환경(도커·VM)에서만 써야 한다. "큰 힘에는 큰 책임이 따른다."05 — 이미지 사용
스크린샷을 채팅창에 드롭하면 분석한다. "이 UI 오류 고쳐줘", "이 시안대로 HTML 만들어줘", "이 에러 원인이 뭐야?"처럼 화면을 그대로 넘길 수 있다.
06 · 07 — 용어
| 용어 | 설명 |
|---|---|
| Context Window | AI가 한 번에 처리할 수 있는 최대 텍스트 길이 |
| Token | 텍스트 처리 최소 단위(약 0.75단어) |
| Hallucination | 사실 아닌 내용을 자신 있게 생성하는 현상 |
| MCP | USB-C처럼 통일 규격으로 외부 도구 연결 |
@파일로 대화에 담을 정보를 구성)에 집중한다.08 — AI 도입 3단계 여정
새 도구를 채택할 때 누구나 거치는 과정(Mitchell Hashimoto): ① 비효율의 기간(기존보다 느리고 어색) → ② 적절성의 기간(비슷한 효율) → ③ 발견의 기간(워크플로가 바뀌는 생산성 도약).
🔒 하네스 엔지니어링 (Harness Engineering)
하네스(Harness)는 AI 에이전트가 오랜 시간 일할 때 방향을 잡아주고 실수를 감지하는 관리 기술이다. 마치 등산 안전줄처럼 — AI가 자유롭게 일하되, 위험한 순간엔 자동으로 제동이 걸리게 만드는 제어 시스템이다. 프롬프트/컨텍스트 엔지니어링이 "한 번의 요청을 잘 만드는" 것이라면, 하네스 엔지니어링은 "장시간 자율 실행되는 에이전트를 안전하게 굴리는" 상위 관점이다.
09 · 10 · 11 — CLAUDE.md 메모리
CLAUDE.md는 모든 세션 시작 시 자동으로 컨텍스트에 로드된다. 200줄 이하로 유지해야 지침 준수율이 높다. 초과 내용은 @import로 분리한다.
# CLAUDE.md 안에서 다른 파일 참조
@docs/git-instructions.md
@.claude/rules/testing.md
IMPORTANT·YOU MUST로. 개인 설정은 CLAUDE.local.md(gitignore), 팀 공유는 git 커밋.12 · 13 · 16 — 프롬프트 잘 쓰는 법
# 구조화 템플릿
[ROLE: 시니어 백엔드 엔지니어]
[GOAL: 로그인 버그 수정]
[CONSTRAINTS: Python만, 새 패키지 금지]
[CONTEXT: auth.py 245번 줄 오류]
[QUESTION: 원인과 수정 방법은?]
17 — 세션 관리
종료했다 다시 시작해도 문맥을 유지한다. claude --resume으로 최근 세션 목록에서 골라 이어가거나, --continue로 최근 세션을 바로 잇는다.
18 · 19 — 스킬 & 협업
자주 쓰는 작업을 .claude/skills/이름.md에 저장하면 /이름으로 바로 실행하는 나만의 슬래시 명령어가 된다. 나아가 Claude App + Chrome 확장 + MCP를 연결하면 "뉴스 요약해서 카톡으로 보내줘" 같은 복합 자동화도 가능하다.
# .claude/skills/translate-ko.md → /translate-ko 로 실행
주어진 텍스트를 자연스러운 한국어로 번역합니다.
- 구어체보다 문어체 우선
- 전문 용어는 원문 병기
.claude/skills/ 폴더에 이름.md 파일을 만들어 작업 지시를 적고 /이름으로 실행되는 나만의 스킬을 직접 만들어봤다. 자주 반복하는 프롬프트를 한 번 스킬로 굳혀 두니, 다음부턴 명령어 하나로 똑같은 작업을 재현할 수 있어서 편했다.✍️ 마치며
Streamlit·Gradio를 보면서 "AI 모델을 만드는 것"과 "그걸 사람이 쓰게 만드는 것"은 다른 일이라는 걸 느꼈다. 함수 하나에 gr.Interface 몇 줄만 붙여도 친구에게 링크로 보낼 수 있는 웹앱이 된다는 게 특히 인상적이었다. 그리고 그동안 무심코 써온 Claude Code 자체를 뜯어보니, 결국 핵심은 "무엇을 시키느냐(프롬프트)"보다 "어떤 맥락을 주느냐(CLAUDE.md·@파일)"라는 컨텍스트 엔지니어링이었다. 도구를 아는 만큼 더 잘 쓸 수 있다는 걸 체감한 하루였다. 다음엔 만든 앱들을 실제로 배포해 링크로 공유해볼 생각이다.
🏷️ Streamlit | Gradio | Claude Code | 웹앱 | AI | 학습일지
'AI 기반 프론트엔드 웹개발자 양성과정' 카테고리의 다른 글
| [260727 20일차] 프로젝트 #1 (0) | 2026.07.28 |
|---|---|
| [260724 19일차] Claude Code 심화 (0) | 2026.07.28 |
| [260722 17일차] OpenAPI · HuggingFace · Transformers · OCR (1) | 2026.07.22 |
| [260721 16일차] YOLO 심화 (0) | 2026.07.22 |
| [260720 15일차] Data, YOLO (0) | 2026.07.20 |