[260723 18일차] Streamlit · Gradio · Claude Code

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

# 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
st.emptycolumnsplotly
Gradio
gr.Interfacegr.Blockslaunch
웹앱 예제
CCTV 탐지번역기YOLO
Claude 명령어
/init@파일/model
CLAUDE.md
메모리@import200줄
프롬프트
위치지정역할단계분해

📊 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
⚠ import 하자마자 ImportError: numpy.core.multiarray failed to import가 나면 — gradio 잘못이 아니라 numpy 2 버전 충돌이다(numpy 2부터 numpy.corenumpy._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.Interfacegr.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으로 시작한다.

명령어설명
/initCLAUDE.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에게 주는 자율권을 조절하는 장치다. 신입에게 "매번 확인받고 진행"시키다 신뢰가 쌓이면 "알아서 해"로 바꾸는 것과 같은데, 자율권 ↑ = 속도 ↑ = 위험 ↑이라 실수를 되돌리기 어려워진다. 극단이 claude --dangerously-skip-permissions(bypassPermissions) — 모든 작업을 확인 없이 자동 실행하므로 신뢰 가능한 격리 환경(도커·VM)에서만 써야 한다. "큰 힘에는 큰 책임이 따른다."

05 — 이미지 사용

스크린샷을 채팅창에 드롭하면 분석한다. "이 UI 오류 고쳐줘", "이 시안대로 HTML 만들어줘", "이 에러 원인이 뭐야?"처럼 화면을 그대로 넘길 수 있다.

06 · 07 — 용어

용어설명
Context WindowAI가 한 번에 처리할 수 있는 최대 텍스트 길이
Token텍스트 처리 최소 단위(약 0.75단어)
Hallucination사실 아닌 내용을 자신 있게 생성하는 현상
MCPUSB-C처럼 통일 규격으로 외부 도구 연결
프롬프트 엔지니어링 vs 컨텍스트 엔지니어링 — 전자는 무엇을 물어볼지(질문·지시를 잘 쓰기), 후자는 어떤 정보를 줄지(CLAUDE.md·@파일로 대화에 담을 정보를 구성)에 집중한다.

08 — AI 도입 3단계 여정

새 도구를 채택할 때 누구나 거치는 과정(Mitchell Hashimoto): ① 비효율의 기간(기존보다 느리고 어색) → ② 적절성의 기간(비슷한 효율) → ③ 발견의 기간(워크플로가 바뀌는 생산성 도약).

🔒 하네스 엔지니어링 (Harness Engineering)

하네스(Harness)는 AI 에이전트가 오랜 시간 일할 때 방향을 잡아주고 실수를 감지하는 관리 기술이다. 마치 등산 안전줄처럼 — AI가 자유롭게 일하되, 위험한 순간엔 자동으로 제동이 걸리게 만드는 제어 시스템이다. 프롬프트/컨텍스트 엔지니어링이 "한 번의 요청을 잘 만드는" 것이라면, 하네스 엔지니어링은 "장시간 자율 실행되는 에이전트를 안전하게 굴리는" 상위 관점이다.

참고: Anthropic — Effective Harnesses for Long-Running Agents. 그리고 하네스 엔지니어링 이후, 요즘은 루프 엔지니어링(Loop Engineering)이라는 개념도 새로 등장했다. 에이전트가 관찰 → 행동 → 피드백을 반복하는 실행 루프 자체를 설계·최적화하는 접근으로, 언제 멈추고 언제 다시 시도할지, 어떤 신호로 루프를 조율할지에 초점을 둔다.

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 — 프롬프트 잘 쓰는 법

1위치 지정"auth.js에서 비밀번호 찾기 버튼 오류 수정" — @파일로 콕 집기
2역할 명확화"당신은 시니어 백엔드 엔지니어, 성능 최적화 중심으로"
3금지사항 명시"새 패키지 추가 금지, 동작하는 기능은 건드리지 말 것"
4단계별 분해"분석 → 방법 설명 → 코드 작성 → 저장 순서로"
5검증 수단 제공"수정 후 자동 검사 돌려 기존 기능 문제없는지 확인"
# 구조화 템플릿
[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 파일을 만들어 작업 지시를 적고 /이름으로 실행되는 나만의 스킬을 직접 만들어봤다. 자주 반복하는 프롬프트를 한 번 스킬로 굳혀 두니, 다음부턴 명령어 하나로 똑같은 작업을 재현할 수 있어서 편했다.
💰 스킬도 사고판다 — 잘 만든 스킬은 상품이 되기도 한다. skills.ag 같은 마켓에서는 검증된 AI 에이전트 스킬을 판매·구매한다. "반복 작업을 절차적 지식으로 굳혀 재사용한다"는 스킬의 개념이, 이제 하나의 생태계·시장으로 커지고 있다는 게 인상적이었다.

✍️ 마치며

Streamlit·Gradio를 보면서 "AI 모델을 만드는 것"과 "그걸 사람이 쓰게 만드는 것"은 다른 일이라는 걸 느꼈다. 함수 하나에 gr.Interface 몇 줄만 붙여도 친구에게 링크로 보낼 수 있는 웹앱이 된다는 게 특히 인상적이었다. 그리고 그동안 무심코 써온 Claude Code 자체를 뜯어보니, 결국 핵심은 "무엇을 시키느냐(프롬프트)"보다 "어떤 맥락을 주느냐(CLAUDE.md·@파일)"라는 컨텍스트 엔지니어링이었다. 도구를 아는 만큼 더 잘 쓸 수 있다는 걸 체감한 하루였다. 다음엔 만든 앱들을 실제로 배포해 링크로 공유해볼 생각이다.

🏷️ Streamlit  |  Gradio  |  Claude Code  |  웹앱  |  AI  |  학습일지