AI 파이썬 Lab · 심화 · 2주차
📎 기록 노션: AI Python Lab 기록 페이지
심화 · 프로젝트 1 웹앱

프로젝트 1: 웹앱 (기획+시작)

오늘부터 2주 동안 '입력하면 AI가 처리해서 보여주는' 웹앱을 만듭니다. 먼저 선생님과 함께 대표 사례를 만들어 본 뒤, 내가 만들 프로젝트를 정하고 화면 뼈대까지 시작해요.

오늘의 목표

오늘 배우는 것

웹앱 프로젝트는 크게 입력 → 처리 → 출력 세 덩어리로 이루어져요. 오늘은 이 구조를 직접 만든 뒤, 내 프로젝트의 첫 화면까지 시작해봅니다.

🧩
GOAL 1
입력→처리→출력 구조로 웹앱을 이해한다
🤖
GOAL 2
내 코드로 Claude API를 호출한다
📝
GOAL 3
내 프로젝트를 정하고 화면 뼈대를 시작한다

오늘의 흐름 한눈에

1
함께 만들기
선생님과 3줄 요약기를 만들며 입력→처리→출력을 익혀요.
2
내 주제 정하기
내 웹앱의 문제정의핵심기능 1개를 정해요.
3
화면 시작하기
정한 주제로 제목과 입력 위젯까지 만들어요.
📌 오늘과 다음 주의 역할
오늘(W02)은 기획과 시작이에요. 대표 사례를 익히고 내 프로젝트의 첫 화면을 세워요. 다음 주(W03)는 완성과 배포예요. 오늘 만든 화면에 AI를 붙이고 세상에 공개해요.
새 개념 ①

처음 나오는 것 — 입력→처리→출력

지금까지 여러분이 만든 웹앱은 화면에 버튼과 결과만 있었어요. 오늘부터는 그 화면을 세 덩어리로 나눠서 생각해볼게요. 모든 웹앱 프로젝트가 이 구조 위에서 만들어지거든요.

🧩
입력 → 처리 → 출력
사용자가 입력하면, 코드가 그 값을 처리하고, 결과를 화면에 출력하는 세 덩어리 흐름이에요.
자판기에 비유하면 버튼을 누르고(입력) → 기계 안에서 상품을 고르고(처리) → 음료가 나와요(출력). 웹앱도 똑같이 세 단계로 나눠서 생각하면 어떤 앱이든 설계할 수 있어요.
📌 하나 더 — 편의점 계산대로 생각해도 같아요
물건을 바구니에 담아 내밀면(입력) → 계산원이 바코드를 찍어 값을 더하고(처리) → 영수증과 총액을 알려줘요(출력). 겉모습은 자판기와 달라도 세 덩어리 구조는 똑같아요.
📌 왜 세 덩어리로 나눠서 볼까요
한꺼번에 "앱을 만들자"고 하면 막막해요. 하지만 "무엇을 입력받지?", "그걸 어떻게 처리하지?", "무엇을 출력하지?" 세 질문으로 쪼개면 아무리 큰 앱도 시작할 수 있어요.
입력사용자가 값을 넣는 부분 — 글 상자, 선택 메뉴, 버튼
처리넣은 값을 계산하거나 AI에게 물어보는 부분
출력처리한 결과를 화면에 보여주는 부분
💡 오늘 이것만 기억해요

"입력 → 처리 → 출력". 앞으로 어떤 앱을 만들든 이 세 단어를 먼저 떠올리면 설계의 절반은 끝난 거예요.

📌 우리가 매일 쓰는 앱도 이 구조예요
번역기(글 입력 → 번역 → 결과), 지도 앱(목적지 입력 → 길 계산 → 경로 표시), 검색창(검색어 입력 → 찾기 → 결과 목록) — 모두 입력·처리·출력 세 덩어리예요.
번역기입력: 원문 / 처리: 번역 / 출력: 번역문
지도 앱입력: 목적지 / 처리: 경로 계산 / 출력: 길 안내
검색창입력: 검색어 / 처리: 검색 / 출력: 결과 목록
계산기입력: 숫자·기호 / 처리: 연산 / 출력: 답
⚠️ 처음 구조를 잡을 때 흔한 오해
  • "처리가 꼭 AI여야 하나요?" → 아니에요. 계산기처럼 단순 계산도 처리예요. 오늘은 그중에서 AI로 처리하는 것뿐이에요.
  • "출력이 화면 말고도 있나요?" → 소리·파일도 출력이 될 수 있지만, 오늘은 화면에 보여주는 출력만 다뤄요.

세 덩어리를 그림처럼 떠올리기

글로만 보면 어려우니, 세 상자가 이어진 그림으로 상상해 보세요.

▸ 흐름 그림
[ 입력 상자 ]  →  [ 처리 상자 ]  →  [ 출력 상자 ]
  사용자 글          AI가 요약          화면에 표시
  (text_area)       (ask_ai)           (st.write)
📌 화살표가 곧 데이터의 이동
왼쪽에서 넣은 값이 화살표를 타고 오른쪽으로 흘러가요. 값이 끊기지 않고 세 상자를 지나면 앱이 완성돼요.
입력 상자값을 받아 변수에 담는다
처리 상자담긴 값을 ask_ai에 넘긴다
출력 상자돌아온 값을 화면에 쓴다
복습 + 확장 ②

다시 만나는 것 — Claude API

API·API 키·system prompt는 기초 과정에서 이미 배웠죠. 오늘은 새로 배우는 게 아니라, Claude Code에게 코드를 부탁하는 것내 프로그램이 직접 AI를 부르는 것이 어떻게 다른지 살펴볼게요.

🔌
Claude API
내가 만든 파이썬 코드 안에서 직접 Claude에게 질문을 보내고 답을 받는 통로예요. API 키(.env)로 문을 여는 방식은 기초에서 하던 것과 똑같아요.
둘의 차이를 비유하면 "Claude Code에게 시켜서 코드 받기"는 요리사(Claude Code)에게 "이 요리 만들어줘"라고 부탁해서 완성된 요리(코드)를 받는 것과 같아요. "내 프로그램이 직접 API 호출"은 내가 요리사(Claude API)를 내 식당(앱) 안에 아예 고용해서, 손님이 주문할 때마다 즉석으로 요리해 내보내는 것이에요.
📌 4주차 기억나시나요?
4주차에 날씨 API와 AI를 조합해봤죠. 그때는 날씨 정보를 가져와서 AI에게 넘겼어요. 오늘은 그 결과를 화면(Streamlit)에 직접 보여주는 앱으로 연결합니다.
📌 "부탁하기"와 "고용하기"를 비교하면
Claude Code에게 부탁하면 지금 딱 한 번 코드를 받아요. 하지만 Claude API를 앱 안에 넣어두면, 손님이 올 때마다 매번 앱이 스스로 Claude를 불러요. 부탁하기는 우리가 앱을 만들 때 하는 일이고, 고용하기는 앱이 실제로 움직일 때 하는 일이에요.
Claude Code내가 코드를 만들 때 도와주는 도구 (개발 도우미)
Claude API완성된 앱이 실행 중에 직접 부르는 AI (앱 속 일꾼)
⚠️ 헷갈리기 쉬운 점
  • Claude Code로 코드를 받았다고 API가 저절로 연결되는 건 아니에요 — 앱 안에 ask_ai()가 있어야 해요.
  • API 키는 사람이 로그인할 때 쓰는 비밀번호가 아니에요. 앱이 AI에게 가는 문을 여는 열쇠라고 생각하면 돼요.

API 키는 어떻게 쓰이나요 — 복습 포인트

API 키는 기초에서 배운 그대로예요. 오늘은 딱 세 가지만 다시 확인해요.

.env 파일내 컴퓨터에서 키를 보관하는 곳
st.secrets배포했을 때 키를 대신 넣어주는 곳
자동 로드코드에 키를 직접 안 써도 알아서 읽어와요
📌 왜 키를 코드에 직접 안 쓰나요
집 열쇠를 대문에 매달아두면 누구나 열고 들어올 수 있겠죠. 키를 코드에 그대로 적어두면 GitHub에 올렸을 때 똑같은 일이 벌어져요. 그래서 키는 따로 보관하고, 코드는 "알아서 읽어오게"만 해둬요.
⚠️ 키 관련 복습 포인트
  • 키는 선생님이 나눠준 것을 써요. 직접 발급받지 않아요.
  • 키를 화면이나 채팅창에 붙여넣지 않아요.
  • 키가 안 먹히면 코드가 아니라 키 설정부터 확인해요.

"부탁하기" vs "고용하기" 다시 정리

오늘 가장 헷갈리기 쉬운 두 가지를 표로 다시 짚어요.

▸ 두 방식 비교
Claude Code에게 부탁  : 개발할 때, 나 대신 코드를 써 줌 (한 번)
내 앱이 API를 호출    : 앱이 돌 때, 손님마다 AI가 답함 (매번)
📌 언제 무엇을 쓰나요
코드를 만드는 동안엔 Claude Code에게 부탁해요. 만든 앱이 실행되는 동안엔 앱이 ask_ai()로 Claude API를 직접 불러요. 둘은 하는 때가 달라요.
💡 오늘의 주인공은 API 호출

오늘 배우는 핵심은 "내 앱이 스스로 AI를 부르게 만드는 것"이에요. 개발 도우미로서의 Claude Code와 헷갈리지 않도록 이 차이를 꼭 기억해요.

내 앱이 AI를 부르는 순간을 그림으로

사용자가 버튼을 누르면 앱 안에서 어떤 일이 벌어지는지 순서대로 그려볼게요.

▸ 버튼을 누른 뒤 벌어지는 일
사용자 → [버튼] → 앱이 ask_ai(질문) 호출
      → Claude API가 답을 만듦
      → 앱이 답을 받음 → 화면에 표시
📌 이 모든 게 몇 초 안에
사용자는 버튼 하나만 눌렀는데, 앱은 그 사이 Claude에게 다녀와 답을 화면에 띄워요. 이 왕복 전부가 ask_ai() 한 줄 안에 들어 있어요. 우리는 그 함수를 부르기만 하면 됩니다.
개념

웹앱 = 입력 → 처리 → 출력

앞으로 여러분이 만들 모든 프로젝트는 이 세 덩어리로 쪼개서 생각할 수 있어요. 오늘 함께 만드는 '3줄 요약기'도 마찬가지예요.

1
입력 받기
사용자가 글을 붙여넣거나 값을 고르는 부분. st.text_area 같은 위젯을 씁니다.
2
AI로 처리하기
입력값을 ask_ai()에 넘겨 Claude API가 처리한 답을 받습니다.
3
결과 출력하기
st.write() 등으로 처리된 결과를 화면에 보여줍니다.
📌 오늘 함께 만들 대표 사례 — 3줄 요약기
긴 글을 붙여넣으면(입력) → Claude API가 핵심만 골라(처리) → 세 줄로 정리해 보여주는(출력) 앱이에요. 입출력이 단순해서 오늘 구조를 익히기에 좋아요.
📌 같은 구조, 다른 앱 — 세 가지 예시로 보기
앱마다 넣는 위젯만 다를 뿐, 입력→처리→출력 뼈대는 똑같아요. 아래 세 앱을 비교해 보세요.
3줄 요약기긴 글 입력 → AI가 요약 처리 → 세 줄 출력
말투 변환기문장+말투 입력 → AI가 변환 처리 → 바뀐 문장 출력
레시피 추천기재료 입력 → AI가 요리 추천 처리 → 레시피 출력
⚠️ 세 덩어리를 나눌 때 자주 하는 실수
  • 입력 위젯을 안 만들고 코드에 값을 고정해 버림 → 사용자가 값을 바꿀 수 없어요.
  • 처리 결과를 화면에 안 보여줌st.write() 같은 출력 줄을 빠뜨리기 쉬워요.
  • 처리와 출력을 한 줄에 섞어 써서 나중에 고치기 어려워져요.
🔒 힌트 — 내 앱을 세 덩어리로 나눠보기

만들고 싶은 앱이 떠올랐다면, 아래 빈칸을 말로 채워보세요. 세 칸이 다 채워지면 설계가 끝난 거예요.

입력사용자에게 무엇을 받을까? (예: 긴 글, 재료 목록)
처리그걸로 AI가 무엇을 할까? (예: 요약, 추천)
출력화면에 무엇을 보여줄까? (예: 세 줄 요약, 레시피)

세 덩어리가 실제로 어떻게 도는지

입력→처리→출력 구조가 실제로 어떻게 도는지, 출력까지 미리 보여줄게요. 지금은 눈으로만 훑어도 충분해요.

📌 말투 변환기 — 입력→처리→출력
입력 "내일 회의 시간 좀 알려줘" + 말투 '정중체' → 처리 AI가 뜻은 유지하고 말투만 바꿈 → 출력 아래 결과.
▸ 말투 변환기 출력 예시
정중체 : 내일 회의 시간을 알려주시면 감사하겠습니다.
반말   : 내일 회의 몇 시야? 알려줘.
사투리 : 낼 회의 및 시고? 좀 알키도.
💡 여기서 눈치챌 것

앱마다 입력과 출력의 내용만 다를 뿐, "받고 → 맡기고 → 보여준다"는 흐름은 똑같아요. 이 감각만 잡으면 어떤 앱이든 시작할 수 있어요. 다음 미션에서 "무엇을 처리할지"를 정하는 게, 곧 내 앱이 무엇이 될지를 정하는 일이에요.

미션 1

3줄 요약기 같이 만들기

🎯 목표: 긴 글을 붙여넣으면 Claude API가 세 줄로 요약해주는 웹앱을 만든다.

① API 키 준비 — 복습

API 키는 기초에서 이미 .env로 다뤄봤죠. 이번에도 원리는 같아요. 배포할 때는 st.secrets가 그 역할을 대신합니다. 선생님이 나눠준 키를 아래처럼 저장하세요.

.env
OPENAI_API_KEY=여기에_선생님이_알려준_키_붙여넣기
⚠️ .env 복습 포인트
  • 키 앞뒤 공백·따옴표 없이 딱 붙여 저장.
  • .envapp.py같은 폴더에.
  • .env는 GitHub에 올리지 않기 — 배포 시엔 Secrets 칸에.

② ask_ai 함수 정의 — openai SDK로

지금까지는 AI를 부르는 함수를 만들 때 다른 도구를 쓰기도 했어요. 오늘은 openai 파이썬 SDK라는 도구로 ask_ai()를 새로 만듭니다. 이 함수는 앞으로 매주 그대로 다시 쓸 거예요.

app.py — AI 호출 함수 (한 번만 작성)
from openai import OpenAI
client = OpenAI()   # 키는 .env / secrets에서 자동으로

def ask_ai(prompt):
    res = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}]
    )
    return res.choices[0].message.content
1
client = OpenAI()
Claude에게 전화를 걸 준비를 해요. 키는 .env에서 자동으로 가져와요.
2
def ask_ai(prompt):
"프롬프트를 넣으면 답을 돌려주는 상자"를 만들어요. 이름은 ask_ai예요.
3
client.chat.completions.create(...)
그 상자 안에서 진짜로 Claude에게 메시지를 보내요.
4
return res.choices[0].message.content
Claude가 준 답 중 글자 답변만 꺼내서 돌려줘요.
📌 ask_ai("...")를 부르면 벌어지는 일
편지를 보내면 답장이 오는 것처럼, ask_ai("안녕?")이라고 쓰면 함수 안에서 Claude에게 "안녕?"이 배달되고 잠시 뒤 답장이 글자로 돌아와요. 우리는 그 답을 받아서 화면에 보여주기만 하면 돼요.
📌 함수로 만들어 두면 좋은 점
ask_ai()를 한 번 만들어 두면, 앱 어디서든 이름만 부르면 AI를 쓸 수 있어요. 요약할 때도, 변환할 때도, 추천할 때도 같은 함수를 재사용해요.
model어떤 모델을 쓸지 (gpt-4o-mini)
messages사용자가 보내는 질문이 담기는 곳
💡 이 함수는 '한 번만' 만들어요

ask_ai() 정의는 앱에 딱 한 번만 있으면 돼요. 그다음부터는 필요할 때마다 ask_ai(...)로 부르기만 하면 됩니다.

⚠️ ask_ai 함수에서 자주 하는 실수
  • ask_ai()를 정의만 하고 부르지 않음 → 버튼 안에서 ask_ai(prompt)로 실제 호출해야 해요.
  • return을 빠뜨림 → 답이 안 돌아와 화면이 비어요.
  • res.choices[0].message.content에서 [0]을 빠뜨림 → 글자만 못 꺼내요.
💡 지금까지와 뭐가 다를까

"Claude Code에게 시켜서 코드를 받는 것"은 여러분이 지금 이 순간 하고 있는 일이에요. 반면 ask_ai()여러분이 만든 앱이 실행되는 동안 앱 스스로 Claude에게 질문을 보내고 답을 받는 거예요. 앱은 옆에 사람이 없어도 이 일을 혼자 해낼 수 있어요.

🔒 힌트 — ask_ai가 왜 이렇게 생겼는지 한 줄씩
from openai import OpenAIClaude에게 연결하는 도구를 불러와요
OpenAI()연결 담당 '전화기(client)'를 하나 만들어요
chat.completions.create()실제로 질문 메시지를 보내는 부분이에요
choices[0].message.content답 보따리에서 글자 답만 꺼내요

③ ask_ai를 한 번 테스트해 보기

화면을 만들기 전에, ask_ai()가 잘 도는지 짧은 질문으로 먼저 확인해요.

app.py — 함수 테스트
print(ask_ai("안녕? 한 문장으로 인사해줘."))
▸ 터미널 출력
안녕하세요! 오늘도 좋은 하루 보내세요.
📌 왜 먼저 테스트할까
레고를 다 조립한 뒤에 어디가 잘못됐는지 찾으려면 힘들죠. 화면까지 다 만든 뒤 에러가 나면 마찬가지로 어디가 문제인지 찾기 어려워요. 함수만 먼저 확인해두면, 나중에 화면에서 문제가 생겨도 "함수는 멀쩡하다"는 걸 바로 알 수 있어요.
⚠️ 테스트에서 막힐 때
  • 답 대신 에러가 뜸 → 대부분 키 설정 문제예요. 선생님께 확인 요청.
  • 한참 멈춤 → 인터넷 연결을 확인해요. AI 응답은 잠깐 시간이 걸려요.

④ 입력→처리→출력 화면 만들기

이제 앞서 배운 세 덩어리를 그대로 코드에 옮깁니다.

app.py
import streamlit as st

st.title("📝 3줄 요약기")

# ── ① 입력 ──
text = st.text_area("긴 글을 붙여넣으세요")

# ── ② 처리 ──
if st.button("요약하기"):
    prompt = f"다음 글을 3줄로 요약해줘:\n{text}"
    result = ask_ai(prompt)
    # ── ③ 출력 ──
    st.write(result)
1
st.text_area(...) — 입력
사용자가 긴 글을 붙여넣을 글 상자를 만들어요. 붙여넣은 값은 text에 담겨요.
2
if st.button(...) — 버튼
'요약하기'를 눌렀을 때만 아래 처리가 실행돼요. 안 누르면 아무 일도 안 해요.
3
prompt = f"...{text}" — 처리 준비
사용자 글을 요약 지시문과 합쳐 Claude에게 보낼 문장을 만들어요.
4
st.write(result) — 출력
ask_ai()가 돌려준 요약을 화면에 그대로 보여줘요.
📌 f"...{text}"가 뭐예요?
빈칸 채우기 문제라고 생각하면 쉬워요. 중괄호 {text} 자리에 사용자가 넣은 글이 그대로 끼워 넣어져요. 그래서 매번 다른 글을 넣어도 똑같은 지시문 틀로 요약을 부탁할 수 있어요.
⚠️ 이 화면 코드에서 자주 하는 실수
  • if st.button 아래 줄을 들여쓰기 안 함 → 버튼과 상관없이 늘 실행돼요.
  • st.write()를 빠뜨림 → 요약은 됐는데 화면에 안 보여요.
  • text 대신 다른 이름을 씀 → 위젯 변수명과 똑같이 맞춰야 해요.
📌 코드를 읽는 순서
파이썬은 위에서 아래로 읽어요. 그래서 ask_ai() 정의가 먼저 나오고, 그걸 부르는 화면 코드가 나중에 나와야 해요. 순서가 바뀌면 "그런 함수 없다"는 에러가 나요.
st.title화면 맨 위 제목을 만든다
st.text_area여러 줄 입력창을 만든다
st.button누를 수 있는 버튼을 만든다
st.write결과를 화면에 보여준다
💡 st. 으로 시작하면 화면 담당

st.로 시작하는 줄은 모두 화면에 무언가를 그리는 명령이에요. 반대로 ask_ai()는 화면이 아니라 AI를 부르는 명령이에요.

⑤ 프롬프트를 다듬으면 결과가 달라져요

같은 글이라도 prompt에 어떻게 부탁하느냐에 따라 요약 모양이 달라져요. 두 가지를 비교해 볼게요.

app.py — 프롬프트만 바꿔보기
prompt = f"다음 글을 3줄로 요약해줘:\n{text}"
# prompt = f"다음 글을 초등학생도 알게 3줄로:\n{text}"
▸ 기본 vs "초등학생도 알게" 프롬프트
기본  : 1. 삼성전자가 청소년 10만 명에게 AI 교육을 지원한다.
초등  : 1. 큰 회사가 학생들에게 AI 공부를 도와줘요.
        2. 인터넷으로도 교실에서도 배울 수 있어요.
📌 프롬프트가 곧 앱의 성격
코드는 그대로 두고 부탁하는 문장만 바꿔도 앱이 완전히 다르게 느껴져요. 내 앱이 어떤 답을 주면 좋을지 프롬프트로 정해보세요.
🔒 힌트 — 좋은 프롬프트 쓰는 법
개수 지정"딱 3줄", "키워드 3개"처럼 수를 정해줘요
대상 지정"초등학생도 알게"처럼 눈높이를 정해줘요
형식 지정"번호를 붙여서"처럼 모양을 정해줘요

⑥ 앱 실행하기

터미널
streamlit run app.py
▸ 브라우저 화면
📝 3줄 요약기
[ 긴 글을 붙여넣으세요             ]
[ 요약하기 ]

1. 삼성전자가 청소년 10만 명에게 AI 교육을 지원한다.
2. 전국 중·고등학생이 온·오프라인으로 참여할 수 있다.
3. 디지털 격차 해소와 인재 양성이 목표다.
📸 스크린샷 자리
긴 글을 붙여넣고 '요약하기'를 눌렀을 때 3줄 요약 결과가 출력된 화면
📌 글 길이에 따라 달라지는 점
입력한 글이 달라지면 결과도 달라져요. 긴 글은 여러 문단 속에서 핵심을 골라내서 세 줄로 줄여요. 짧은 글은 이미 짧아서 세 줄이 서로 비슷해질 수 있어요. 둘 다 정상이니 걱정하지 않아도 돼요. 글이 아무리 길거나 항목이 많아도, 프롬프트에 "3줄"이라고 정해두면 AI가 그 틀에 맞춰 핵심을 골라줘요.
⚠️ 자주 하는 실수
  • ModuleNotFoundError: openai(venv) 상태에서 pip install openai 다시 설치.
  • 요약이 안 나옴 → text가 비어있는 채로 버튼을 눌렀는지 확인.
  • 요약이 너무 김 → 프롬프트에 "각 줄 한 문장, 딱 3줄만"을 명시.
  • 버튼을 눌러도 반응 없음 → if st.button(...) 아래 코드의 들여쓰기를 확인.
  • 같은 글인데 매번 요약이 조금씩 다름 → AI 특성이에요, 정상입니다.
⚠️ 실행·환경에서 자주 막히는 곳
  • 터미널에 streamlit: command not found → 가상환경 (venv)이 켜졌는지 확인.
  • 브라우저가 안 열림 → 터미널에 뜬 localhost 주소를 직접 눌러요.
  • 수정했는데 화면이 그대로 → 브라우저 오른쪽 위 Rerun을 눌러요.

⑦ 프로젝트 예시 모음 — 이런 웹앱도 만들 수 있어요

방금 함께 만든 3줄 요약기는 다섯 가지 예시 중 하나일 뿐이에요. 다음 미션에서 내 프로젝트를 정할 때, 아래 예시를 참고해도 되고 완전히 다른 아이디어를 내도 좋아요.

A
요약
3줄 요약기
긴 글을 붙여넣으면 핵심만 세 줄로 정리 — 방금 함께 만든 것
B
변환
말투 변환기
같은 문장을 정중체·반말·사투리로 바꿔준다
C
추천
재료 레시피 추천기
가진 재료 몇 개로 만들 수 있는 요리를 제안한다
D
작명
이름 짓기 도우미
가게·캐릭터 컨셉을 입력하면 어울리는 이름을 제안한다
E
설명
공부 개념 풀이 봇
어려운 개념을 초등·중등·고등 수준으로 나눠 설명한다
💡 이 목록의 목적

다섯 개 중 하나를 그대로 베끼라는 뜻이 아니에요. "이 정도 폭으로 자유롭게 정해도 된다"는 감각을 가지려는 거예요. 다음 미션에서 여기 없는 아이디어를 내도 좋아요.

📌 다섯 예시의 공통점 찾기
모두 입력 하나 → AI 처리 → 결과 출력 구조예요. 가운데 '처리'만 앱마다 다를 뿐, 입력과 출력은 늘 한 쌍이에요. 여러분의 아이디어도 이 틀에 맞으면 충분히 만들 수 있어요. "무엇을 넣으면, 무엇이 나오면 재밌을까?"만 생각하면 돼요.
⚠️ 예시를 볼 때 주의
  • 다섯 개를 다 만들려고 하지 마세요 → 다음 미션에서 딱 하나만 골라요.
  • 예시와 똑같이 만들 필요 없어요 → 입력·출력만 내 식으로 바꿔도 새 앱이에요.
🔒 힌트 — 예시마다 입력·출력이 뭘까?
말투 변환기입력: 문장+말투 / 출력: 바뀐 문장
레시피 추천기입력: 재료 목록 / 출력: 요리와 순서
이름 짓기 도우미입력: 컨셉 설명 / 출력: 이름 후보들
개념 풀이 봇입력: 개념+수준 / 출력: 눈높이 설명
📌 같은 앱, 입력만 바꾸면 — 결과 미리보기
개념 풀이 봇처럼 수준(초등/고등)만 바꿔도 완전히 다른 답이 나와요("광합성은 식물이 햇빛으로 밥을 만드는 일이에요" vs "광합성은 엽록체에서 빛에너지를 화학에너지로 바꾸는 과정이다"). 이렇게 "무엇을 바꾸면 결과가 달라지는지"를 정하는 게 곧 앱 설계예요. 다음 미션에서 주제를 고를 때 참고하세요.

⑨ 미션1 코드 전체 흐름 되짚기

지금까지 만든 3줄 요약기의 전체 흐름을 한 번에 훑어볼게요. 준비 → 입력 → 처리 → 출력. 오늘 만든 요약기뿐 아니라, 다음 미션에서 만들 내 프로젝트도 똑같은 순서로 완성돼요.

📌 미션1에서 꼭 챙길 세 가지
ask_ai()무슨 일을 하는지 말할 수 있다 / ② 코드에서 입력·처리·출력을 손으로 짚을 수 있다 / ③ 프롬프트를 바꾸면 결과가 달라진다는 걸 안다. 이 셋이면 충분해요.
💡 여기까지 왔다면

이제 진짜 재밌는 부분이에요 — 내 프로젝트를 정할 차례예요. 미션2로 넘어가요!

🔒 힌트 — 에러가 계속 떠요 (전체 참고 코드)

아래 전체 구조와 비교해 내 코드에서 빠진 부분을 찾아보세요.

app.py (전체 참고)
import streamlit as st
from openai import OpenAI

client = OpenAI()

def ask_ai(prompt):
    res = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}])
    return res.choices[0].message.content

st.title("📝 3줄 요약기")
text = st.text_area("긴 글을 붙여넣으세요")
if st.button("요약하기"):
    st.write(ask_ai(f"다음 글을 3줄로 요약해줘:\n{text}"))

키 관련 에러: 키 설정 파일이 제대로 들어갔는지 선생님께 확인을 요청하세요. 학생이 키를 직접 입력하지 않습니다.

미션 2

내 프로젝트 문제정의 + 핵심기능

🎯 목표: 내가 만들 웹앱이 어떤 문제를 푸는지 한 문장으로 정하고, 핵심 기능 1개를 정한다.

3줄 요약기가 잘 돌아간다면, 이제 내 프로젝트를 정할 차례예요. 꼭 지켜야 할 미션은 하나예요 — 입력→처리→출력 흐름을 갖춘 웹앱을 만들고 배포하는 것(배포는 다음 주에 완성해요). 주제는 여러분이 자유롭게 정하면 돼요.

✏️ 먼저 스스로 해보기
내 웹앱은 어떤 문제를 풀까?
① 이 앱이 어떤 문제를 푸는지 한 문장으로 적어보세요. (예: "긴 글을 읽을 시간이 없는 사람을 위해 핵심만 요약해준다") ② 그 문제를 풀기 위한 핵심 기능 1개를 정하세요. 아직 코드를 쓰지 말고, 문장으로만 먼저 정리해봅니다.
✏️ 한 걸음 더 — 세 칸 채우기
누가 · 언제 · 무엇을
누가 쓰나요? (예: 시간이 없는 학생) / 언제 쓰나요? (예: 긴 글을 빨리 파악해야 할 때) / 무엇을 얻나요? (예: 세 줄 요약). 이 세 칸이 채워지면 문제정의 문장이 저절로 만들어져요.
📌 문제정의 문장 예시 모음
"친구에게 사투리로 장난 문자를 보내고 싶은 사람을 위해, 문장을 사투리로 바꿔준다." / "냉장고에 남은 재료가 아까운 사람을 위해, 그 재료로 만들 요리를 추천한다." — 이렇게 '누구를 위해 + 무엇을 한다' 꼴로 쓰면 좋아요.
📌 핵심 기능은 '동사 하나'로
핵심 기능은 "요약한다", "변환한다", "추천한다"처럼 동사 하나로 끝나면 딱 좋아요. 두 개 이상 붙이면(예: 요약도 하고 번역도 하고) 오늘 안에 다 못 끝내요.

참고 — 프로젝트 아이디어

아이디어가 떠오르지 않는다면 미션1에서 본 프로젝트 예시 모음(3줄 요약기·말투 변환기·재료 레시피 추천기·이름 짓기 도우미·공부 개념 풀이 봇) 중 하나를 골라도 되고, 완전히 다른 자유 주제를 정해도 됩니다.

🎯 이번 주 목표는 완성이 아니에요
오늘은 문제정의와 핵심기능 1개를 정하고, 화면 뼈대까지만 시작하면 충분해요. 본격 구현과 배포는 다음 주에 이어갑니다.

주제 고르기 — 세 갈래로 생각하기

주제가 안 정해진다면 아래 세 갈래 중 하나를 따라가 보세요.

1
불편함에서 출발
평소 "이거 귀찮은데" 했던 일을 떠올려요. 그걸 AI가 대신하면 앱이 돼요.
2
좋아하는 것에서 출발
게임·요리·음악 등 좋아하는 주제로 AI가 뭘 해주면 재밌을지 생각해요.
3
예시에서 출발
미션1의 다섯 예시 중 하나를 골라 내 식으로 살짝 바꿔요.
📌 어떤 갈래든 결국 같은 질문
예를 들어 "긴 공지 읽기 귀찮음"(불편함)에서는 3줄 요약기가, "여행 좋아함"(좋아하는 것)에서는 하루 여행 코스 추천기가 나와요. 세 갈래 모두 마지막엔 "무엇을 입력받아 무엇을 출력할까?"로 모여요. 그 두 가지만 정하면 주제 선정 끝이에요. 후보가 정해지면 입력과 출력을 한 줄로 정리해 보세요.
✏️ 내 주제로 채워보기
한 줄 설계도 만들기
"( 내 앱 )은 ( 무엇 )을 입력받아 ( 무엇 )을 출력한다." 이 한 줄을 완성하면 오늘 만들 화면이 저절로 정해져요.

좋은 핵심기능 vs 아쉬운 핵심기능

같은 주제라도 핵심기능을 어떻게 잡느냐에 따라 오늘 끝낼 수 있는지가 갈려요. 좋은 예: "재료로 만들 요리 하나를 추천한다"(동사 1개). 아쉬운 예: "요리 추천 + 칼로리 계산 + 장보기 목록"(동사 3개).

📌 오늘은 '동사 하나'가 정답
기능을 하나로 좁히면 오늘 안에 화면을 만들 수 있어요. 더 넣고 싶은 기능은 다음 주 이후로 미뤄두세요. 메모만 해두면 안 잊어버려요.
⚠️ 욕심을 부를 때 신호
  • "~도 되고 ~도 되면 좋겠다" 생각이 들면 → 기능이 늘어나는 신호예요.
  • 화면에 위젯이 다섯 개 넘게 필요하면 → 범위가 너무 커진 거예요.
⚠️ 자주 하는 실수
  • 핵심 기능을 3~4개 한꺼번에 정함 → 오늘은 딱 1개만 정해요.
  • 문제정의 없이 기능부터 정함 → "누가, 왜 쓰는 앱인지" 한 문장을 먼저 써요.
  • 주제가 너무 커서 막힘 → "누구 한 사람"을 정하면 범위가 확 좁아져요.
⚠️ 아이디어를 못 정할 때
  • 완벽한 걸 찾으려다 시간 다 씀 → 미션1 예시 중 끌리는 것 하나로 바로 시작해요.
  • 남과 겹칠까 걱정 → 같은 주제라도 입력·출력을 다르게 하면 완전히 다른 앱이에요.

실제 학생들의 문제정의 예시

이전에 만들어진 문제정의 문장들이에요. 어떤 식으로 한 문장에 담았는지 살펴보세요.

▸ 문제정의 문장 모음
· 뉴스를 오래 읽기 싫은 사람을 위해 핵심만 세 줄로 요약한다.
· 부모님께 정중히 문자 보내고 싶은 학생을 위해 말투를 바꿔준다.
· 냉장고 재료가 아까운 자취생을 위해 만들 요리를 추천한다.
· 발표 제목이 안 떠오르는 사람을 위해 제목 후보를 지어준다.
· 어려운 개념을 못 알아듣는 친구를 위해 눈높이로 풀어준다.
📌 좋은 문제정의의 공통점
모두 "누구를 위해 + 무엇을 한다" 꼴이에요. '누구'가 구체적일수록(자취생·발표 준비하는 사람) 앱의 방향이 또렷해져요.
✏️ 마지막 점검
내 문장을 소리 내어 읽어보기
내가 쓴 문제정의 문장을 옆 친구에게 한 번 읽어주세요. 친구가 "그거 유용하겠다"고 하면 좋은 문제정의예요. 고개를 갸웃하면 '누구'를 더 좁혀 보세요.
🔒 힌트 — 문제정의 문장 틀

아래 빈칸만 채우면 문제정의 한 문장이 완성돼요.

채우기 틀
"( 누구 )를 위해, ( 무엇 )을 ( 어떻게 ) 해준다."
예) "요리 초보를 위해, 남은 재료로 만들 요리를 추천해준다."
🔒 힌트 — 핵심기능 1개로 좁히는 법

기능이 여러 개 떠오르면, "이거 하나가 없으면 앱이 성립 안 되는 것"을 골라요.

요약기필수: 요약 / 나중에: 번역·저장
레시피 추천기필수: 요리 추천 / 나중에: 칼로리·장보기
미션 3

내 프로젝트 화면 뼈대 만들기

🎯 목표: 정한 아이디어로 입력 위젯이 있는 Streamlit 기본 화면을 시작한다.

문제정의와 핵심기능을 정했다면, 오늘은 입력 부분까지만 만들어볼게요. 처리(AI 연동)와 출력은 다음 주에 이어서 완성해요.

오늘 만드는 범위

1
제목 넣기
st.title()로 내 앱 이름을 정합니다.
2
입력 위젯 넣기
핵심 기능에 필요한 입력을 받는 위젯 하나를 놓습니다. (st.text_input, st.text_area, st.selectbox 등)
3
버튼만 놓아두기
아직 AI 연동은 다음 주예요. 버튼을 누르면 입력값이 그대로 보이는 정도까지만 확인합니다.
app.py — 내 프로젝트 뼈대 (예시: 말투 변환기)
st.title("🗣️ 말투 변환기")

# ── ① 입력 ──
text = st.text_area("바꿀 문장을 입력하세요")
style = st.selectbox("바꿀 말투", ["정중체", "반말", "사투리"])

if st.button("변환하기"):
    st.write("여기에 다음 주 처리 결과가 나올 거예요")
▸ 브라우저 화면(예시)
🗣️ 말투 변환기
[ 바꿀 문장을 입력하세요            ]
바꿀 말투: [ 정중체 ▾ ]
[ 변환하기 ]

여기에 다음 주 처리 결과가 나올 거예요
📸 스크린샷 자리
내 프로젝트의 제목과 입력 위젯이 브라우저에 뜬 화면

다른 입력 위젯도 골라보기

입력 위젯은 앱 성격에 따라 다르게 골라요. 아래 세 가지가 대표적이에요. (재료 레시피 추천기처럼 한 줄 입력이 필요하면 st.text_input을 쓰면 돼요 — 뒤에서 전체 코드를 함께 볼게요.)

st.text_area긴 글을 여러 줄로 받을 때 (요약기 등)
st.text_input한 줄 짧은 입력을 받을 때 (재료·이름 등)
st.selectbox정해진 선택지 중 하나를 고를 때 (말투 등)

실제로 여러 프로젝트의 첫 화면을 로컬에서 띄워봤어요. 어떤 위젯을 골랐는지 비교해 보세요.

📸 스크린샷 자리
3줄 요약기에 짧은 안내문을 넣고 요약한 결과 화면
📸 스크린샷 자리
말투 변환기에서 문장·말투를 고르고 변환한 결과 화면
📸 스크린샷 자리
재료 레시피 추천기에 재료를 넣고 추천받은 결과 화면
📸 스크린샷 자리
처리·출력을 붙이기 전, 제목과 입력 위젯만 있는 화면 뼈대
📌 위젯이 달라도 뼈대는 같아요
위 화면들은 위젯 종류만 다를 뿐 모두 제목 → 입력 위젯 → 버튼 순서예요. 위젯만 내 주제에 맞게 바꾸면 오늘 목표는 끝이에요. 오늘은 여기까지가 목표고, 버튼을 누르면 나올 결과는 다음 주에 붙여요.

위젯을 만들면 사용자가 넣은 값이 왼쪽 변수에 담겨요(예: text = st.text_area(...)). 다음 주엔 이 변수를 ask_ai()에 넘겨 처리해요.

🔒 힌트 — 어떤 위젯을 몇 개 놓을까

핵심기능 1개에 필요한 입력 하나면 충분해요. 선택이 필요하면 selectbox를 하나 더 놓아도 돼요. 위젯이 많아지면 오늘 범위를 넘겨요.

🔒 힌트 — 버튼을 눌러도 아무 일도 안 일어나요

오늘은 그게 정상이에요! 버튼 아래에 st.write("...예정") 한 줄만 있으면 성공이에요. 진짜 처리는 다음 주에 ask_ai()를 붙여서 완성해요.

🃏 선택지 카드 — 어떤 프로젝트로 시작할까?

A
요약
3줄 요약기
긴 글을 붙여넣으면 핵심만 세 줄로 정리
난이도 ★☆☆
→ 오늘 미션1과 거의 동일한 구조로 시작 가능
B
변환
말투 변환기
같은 문장을 정중체·반말·사투리로 변환
난이도 ★☆☆
→ "문장과 말투를 입력받는 화면을 만들어줘"
C
추천
재료 레시피 추천기
가진 재료로 만들 수 있는 요리를 제안
난이도 ★★☆
→ "재료 목록을 입력받는 화면을 만들어줘"
D
설명
공부 개념 풀이 봇
어려운 개념을 수준별로 쉽게 설명
난이도 ★★☆
→ "개념과 학년 수준을 입력받는 화면을 만들어줘"
E
자유
나만의 아이디어!
목록에 없는 아이디어를 직접 기획해 화면을 만들어 보기

카드별 AI 요청 예시 — 이렇게 부탁하면 돼요

화면 뼈대를 AI 도구에게 부탁할 때, 아래처럼 요청하면 원하는 위젯이 붙은 코드를 받을 수 있어요.

💬 A · 3줄 요약기 요청 예시
Streamlit으로 '3줄 요약기' 첫 화면을 만들어줘. 제목, 긴 글을 넣는 text_area, '요약하기' 버튼까지만. 처리·출력은 빼줘.
💬 B · 말투 변환기 요청 예시
Streamlit으로 '말투 변환기' 첫 화면을 만들어줘. 문장을 넣는 입력창과 말투를 고르는 selectbox(정중체·반말·사투리), '변환하기' 버튼까지만.
💬 D · 개념 풀이 봇 요청 예시
Streamlit으로 '개념 풀이 봇' 첫 화면을 만들어줘. 개념을 넣는 text_input과 수준을 고르는 selectbox(초등·중등·고등), '설명 듣기' 버튼까지만.
📌 요청할 때 꼭 넣을 말
"처리·출력은 빼고 화면까지만"이라고 부탁하면, 오늘 범위에 딱 맞는 코드를 받을 수 있어요. AI에게 범위를 알려주는 게 중요해요.

처음부터 끝까지 — 레시피 추천기로 따라 해보기

한 가지 예시(레시피 추천기)로 오늘 만들 화면을 처음부터 끝까지 따라가 볼게요. 제목 정하기 → 입력 위젯 놓기 → 버튼 놓기 순서예요.

app.py — 레시피 추천기 뼈대 완성본
import streamlit as st

st.title("🍳 재료 레시피 추천기")
items = st.text_input("가진 재료를 쉼표로 적어주세요")
if st.button("추천받기"):
    st.write("여기에 다음 주 추천 결과가 나올 거예요")
▸ 오늘까지의 화면
🍳 재료 레시피 추천기
[ 가진 재료를 쉼표로 적어주세요 ]
[ 추천받기 ]
여기에 다음 주 추천 결과가 나올 거예요
💡 여기까지가 오늘 목표

이렇게 제목 + 입력 + 버튼이 보이면 오늘 미션3 완료예요. 다음 주에 ask_ai()를 붙여 진짜 추천이 나오게 만들어요.

⚠️ 자주 하는 실수
  • 오늘부터 AI 연동까지 하려다 시간 부족 → 오늘은 입력 화면까지만 목표로 해요.
  • 위젯 종류를 고민만 하다 시간 다 씀 → 일단 아무 위젯이나 놓고 실행해본 뒤 바꿔도 돼요.
  • 제목에 이모지를 안 넣어도 괜찮아요 → 기능이 먼저, 꾸미기는 나중에.
  • AI에게 범위를 안 알려줌 → 처리·출력까지 다 만들어 줘서 오늘 범위를 넘겨요.
⚠️ 화면이 안 뜰 때 점검 순서
  • 터미널에 빨간 에러가 있나요? → 있으면 몇 번째 줄인지 먼저 봐요.
  • st.title(...)의 괄호·따옴표가 짝이 맞나요?
  • 파일을 저장했나요? → 저장 후 Rerun을 눌러요.
🔒 힌트 — 입력 위젯 고르는 법

내 앱이 받을 값의 성격으로 위젯을 고르면 돼요.

긴 글→ st.text_area
짧은 한 줄→ st.text_input
정해진 보기→ st.selectbox

다음 주엔 이렇게 완성돼요 — 미리보기

오늘 만든 뼈대에 ask_ai()를 붙이면 다음 주엔 이런 앱이 돼요 — 제목과 입력창 아래로 진짜 요약·변환·추천 결과가 나오게 됩니다. 완성 모습을 미리 그려보면 오늘 화면을 만들 때 방향이 또렷해져요.

📌 오늘과 다음 주의 차이
오늘은 버튼을 눌러도 안내문만 떠요. 다음 주엔 그 자리에 ask_ai()의 진짜 결과가 들어가요. 화면 뼈대는 오늘 것을 그대로 씁니다. 어떤 프로젝트를 골랐든 원리는 같아요.
💡 오늘의 목표를 다시 확인

완성이 아니라 화면 뼈대예요. 제목과 입력 위젯이 뜨고 버튼이 눌리면 오늘은 100점이에요.

다음 주 완성까지 남은 두 조각

오늘 뼈대를 만들었으니, 완성까지 남은 건 딱 두 조각이에요 — 버튼 안에 ask_ai(prompt)를 넣어 처리를 붙이고, 받은 결과를 st.write()로 출력에 연결하는 것.

📌 오늘 잘해두면 다음 주가 쉬워요
화면 뼈대가 깔끔하면 다음 주엔 두 줄만 추가하면 앱이 완성돼요. 그래서 오늘 입력 위젯을 제대로 놓는 게 중요해요.
⚠️ 오늘 자주 빠뜨리는 것
  • 입력값을 변수에 안 담음 → 다음 주에 그 변수를 못 써요.
  • 버튼 라벨을 안 정함 → 무슨 앱인지 헷갈려요. 명확한 이름을 붙여요.
보너스 미션

더 해보고 싶다면

미션 3까지 끝내고 시간이 남는다면 도전해 보세요. 다 못해도 괜찮아요.

보너스 ① system prompt로 AI 성격 정하기

system prompt는 기초에서 이미 배웠죠. 오늘은 그걸 ask_ai() 함수 안에 넣어서, 내 프로젝트의 AI가 항상 같은 태도로 답하게 만들어볼게요.

app.py (system prompt 예시)
def ask_ai(prompt):
    res = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "너는 친절하고 간결하게 답하는 도우미야."},
            {"role": "user", "content": prompt}
        ])
    return res.choices[0].message.content

{"role": "system", ...}는 Claude에게 "너는 이런 성격/역할이야"라고 미리 알려주는 자리예요. 매번 질문할 때마다 반복해서 설명하지 않아도 돼요. 같은 질문이라도 system prompt에 따라 답의 말투와 태도가 달라져요. 세 가지를 비교해 볼게요.

친절한 도우미"너는 친절하고 간결하게 답하는 도우미야."
깐깐한 선생님"너는 꼼꼼한 국어 선생님이야. 틀린 곳을 짚어줘."
재밌는 친구"너는 유머러스한 친구처럼 편하게 말해줘."
▸ "안녕?" 에 대한 답 비교
친절한 도우미 : 안녕하세요! 무엇을 도와드릴까요?
깐깐한 선생님 : 안녕하세요. 오늘은 무엇을 점검해 볼까요?
재밌는 친구   : 오~ 안녕! 오늘 뭐 재밌는 거 없어?
📌 system prompt vs 그냥 프롬프트
옷을 매일 갈아입어도 성격은 그대로인 것과 비슷해요. 그냥 프롬프트(content)는 이번 한 번의 질문이고, system prompt는 대화 내내 유지되는 성격이에요. 그래서 "항상 이렇게 답해줘"는 system에, "이번엔 이걸 물어봐"는 content에 넣어요.
⚠️ system prompt 자주 하는 실수
  • 너무 길게 씀 → 한두 문장이면 충분해요.
  • 질문(content)에 넣을 내용을 system에 넣음 → 역할·태도만 system에.
🔒 힌트 — 내 프로젝트에 맞는 system prompt
요약기"너는 핵심만 뽑는 요약 전문가야."
말투 변환기"너는 문장의 뜻은 지키고 말투만 바꿔줘."
레시피 추천기"너는 초보도 따라 할 수 있게 알려주는 요리사야."

보너스 ② 내 프로젝트 이름 정하고 노션에 기록

정한 문제정의·핵심기능·앱 이름을 노션 포트폴리오 공간에 한 줄씩 정리해보세요. 다음 주 완성본과 비교할 기준이 됩니다.

📌 노션에 이렇게 세 줄만 남겨요
앱 이름: 예) '한입 요약' / ② 문제정의: 예) '긴 글 읽을 시간이 없는 사람을 위해 요약' / ③ 오늘 한 것: 예) '제목·입력창까지 완성'. 세 줄이면 충분해요.
📌 앱 이름 짓기 팁
기능을 담되 짧게. "3줄로 요약해주는 앱"보다 "한입 요약"처럼 두세 글자가 기억에 남아요. AI 도구에게 "이 앱에 어울리는 이름 다섯 개 추천해줘"라고 물어봐도 좋아요.
🎯 성공 기준
system prompt를 넣은 후에도 요약 기능이 정상 작동하거나, 노션에 오늘 정한 내용이 기록되어 있으면 성공이에요.
📌 system prompt는 자세할수록 형식이 일정해져요
"너는 요약가야"보다 "너는 뉴스 요약가야. 각 줄 한 문장, 존댓말, 3줄."처럼 자세히 쓸수록 답의 모양이 일정해져요(번호·존댓말·3줄). 내 앱이 항상 같은 형식으로 답하길 원하면 여기에 규칙을 적어두면 돼요.
⚠️ 보너스에서 자주 하는 실수
  • system을 바꾸고 저장·Rerun을 안 함 → 예전 답이 그대로 보여요.
  • 규칙을 너무 많이 넣음 → 서로 부딪혀서 답이 이상해져요.
🔒 힌트 — 노션에 남길 항목 체크
앱 이름한두 단어로 짧게
문제정의'누구를 위해 무엇을 한다'
핵심기능동사 하나로
오늘 한 것제목·입력 화면까지
📌 내 앱에 어울리는 성격 고르기
공부 앱이면 친절하거나 꼼꼼한 쪽이, 재미 앱이면 유쾌한 쪽이 어울려요. system prompt 한 줄로 앱의 분위기가 정해져요.
⚠️ 페르소나를 정할 때
  • 성격을 너무 세게 잡음(반말·장난) → 정보 전달 앱엔 안 맞을 수 있어요.
  • 매번 성격이 바뀜 → system prompt를 고정해 두면 일관돼요.
정리

오늘의 핵심 정리

1️⃣
구조
웹앱을 입력→처리→출력 세 덩어리로 설계했다
2️⃣
연동
ask_ai()로 API 호출을 완성했다
3️⃣
기획
내 프로젝트의 문제정의·핵심기능을 정하고 화면을 시작했다

오늘 배운 것을 한눈에

입력→처리→출력모든 웹앱의 공통 뼈대
ask_ai(prompt)내 앱이 직접 Claude API를 부르는 표준 함수
st.text_area / input / selectbox입력을 받는 대표 위젯
st.write()처리 결과를 화면에 보여주는 출력
system promptAI의 성격·태도를 정하는 자리(보너스)
📌 오늘 만든 ask_ai()는 앞으로도 계속 써요
다음 주 프로젝트를 완성할 때도, 그 뒤 다른 프로젝트에서도 ask_ai()를 그대로 가져다 써요. 오늘 이 함수를 정확히 이해해 두면 앞으로 훨씬 편해요.

다음 주에 이어서 할 것

1
처리 붙이기
오늘 만든 입력 화면에 ask_ai()를 연결해 진짜 결과가 나오게 해요.
2
출력 다듬기
결과를 보기 좋게 정리하고, 내 앱 성격에 맞게 화면을 꾸며요.
3
배포하기
완성한 앱을 Streamlit Community Cloud에 올려 폰으로도 접속해 봐요.
💡 오늘의 한 줄

"앱은 입력을 받아, AI에게 맡기고, 결과를 보여준다." 이 한 문장이 오늘 배운 전부예요.

오늘 자주 나온 질문 모음

❓ 오늘 앱을 다 완성해야 하나요?
아니에요. 오늘은 화면 뼈대까지가 목표예요. 처리·출력·배포는 다음 주에 이어가요.
❓ 주제를 바꿔도 되나요?
돼요. 다음 주에도 바꿀 수 있어요. 다만 자주 바꾸면 진도가 늦어지니 오늘은 하나로 정해 시작해요.
❓ ask_ai() 코드를 외워야 하나요?
외울 필요는 없어요. 필요할 때 복사해서 재사용하면 돼요. 대신 "이 함수가 AI를 부른다"는 것만 이해하면 충분해요.
❓ 같은 글인데 답이 매번 달라요.
AI의 특성이에요. 정상이에요. 형식을 일정하게 하고 싶으면 프롬프트나 system prompt에 규칙을 적어두세요.
⚠️ 오늘 끝나기 전 마지막 점검
  • 앱이 streamlit run으로 실행되나요?
  • 제목과 입력 위젯이 화면에 보이나요?
  • 문제정의 한 문장을 말할 수 있나요?

🔧 막혔을 때 — 자가 디버깅 4단계

에러가 떠도 당황하지 마세요. 선생님께 묻기 전에 이 순서대로 스스로 해결해 볼게요.

1
에러 메시지 읽기
빨간 글자에서 '몇 번째 줄'과 '무슨 에러'인지 찾아본다.
2
AI에게 보여주기
에러 메시지를 복사해서 "이 에러를 수정해줘"라고 AI에게 요청한다.
3
고쳐서 다시 실행
AI가 준 수정 코드를 적용하고 다시 실행해 본다.
4
선생님께 질문
그래도 안 되면 '에러 메시지 + 내가 시도한 것'을 함께 설명한다.
에러 도감

오늘 자주 만나는 에러 도감

아래는 오늘 실습에서 가장 자주 나오는 에러들이에요. 메시지를 보고 원인을 빠르게 찾아보세요.

▸ ModuleNotFoundError: No module named 'openai'
가상환경에 openai 패키지가 없다는 뜻이에요.
⚠️ 이렇게 고쳐요
  • 터미널 앞에 (venv)가 있는지 확인.
  • pip install openai을 다시 실행.
▸ IndentationError: unexpected indent
들여쓰기(스페이스) 칸 수가 어긋났다는 뜻이에요.
⚠️ 이렇게 고쳐요
  • if st.button(...) 아래 줄은 스페이스 4칸으로 맞춰요.
  • 탭과 스페이스를 섞지 않아요.
▸ NameError: name 'ask_ai' is not defined
ask_ai 함수를 아직 만들지 않았거나, 이름을 잘못 썼어요.
⚠️ 이렇게 고쳐요
  • def ask_ai(prompt): 정의가 부르는 곳보다 위에 있는지 확인.
  • 철자를 ask_ai로 정확히 맞춰요.
▸ SyntaxError: unterminated string literal
따옴표를 한쪽만 쓰고 닫지 않았을 때 나와요.
⚠️ 이렇게 고쳐요
  • 문자열은 "..."처럼 양쪽 따옴표가 짝이 맞아야 해요.
  • 에러가 가리키는 줄의 따옴표를 먼저 봐요.
▸ 화면은 뜨는데 결과가 안 나와요
에러는 아니지만, 출력 줄이 빠졌을 수 있어요.
⚠️ 이렇게 고쳐요
  • 버튼 안에 st.write(...)가 있는지 확인.
  • 입력창이 비어 있지 않은지 확인.
▸ TypeError: 'NoneType' object is not subscriptable
ask_ai가 아무것도 못 돌려줬을 때 생겨요.
⚠️ 이렇게 고쳐요
  • return이 빠지지 않았는지 확인.
  • res.choices[0].message.content까지 정확히 썼는지 확인.
▸ st.button 아래가 늘 실행돼요
버튼과 상관없이 매번 코드가 도는 경우예요.
⚠️ 이렇게 고쳐요
  • 실행할 코드를 if st.button(...): 안쪽으로 들여쓰기.
▸ 브라우저에 아무것도 안 떠요
streamlit이 아직 실행 중이 아닐 수 있어요.
⚠️ 이렇게 고쳐요
  • 터미널에서 streamlit run app.py를 다시 실행.
  • 터미널에 뜬 localhost 주소를 눌러요.

디버깅 순서 한 장 요약

1
어디서
에러가 몇 번째 줄이라고 하는지 본다.
2
무엇을
에러 이름(ModuleNotFound·Indentation 등)을 본다.
3
어떻게
이 도감에서 같은 이름을 찾아 고친다.
4
그래도
안 되면 AI·선생님에게 에러 전체를 보여준다.

에러 메시지는 "여기 이걸 고치면 돼"라는 안내문이에요. 빨간 글자를 무서워하지 말고, 몇 번째 줄인지부터 차분히 읽어보세요. 에러는 실패가 아니에요.