6주차 실습 - isuho378/2026-1-AI- GitHub Wiki
실습 1. CLaude 시작하기와 첫 대화
첫 프롬프트 입력
원칙 점검
실습 2: 긴 문서 완벽하게 요약하기
6주차-1 교재4장 관계 대수와 SQL1(1~3절)-20260413.pdf
실습 2 심화: 문서 기반 심층 질의응답
질문 패턴 A: 특정 정보 추출
질문 패턴 B: 비판적 사고 훈련
실습 3: 조건이 부여된 복잡한 코드 생성
"""
============================================================
할 일 관리 프로그램 (To-Do List)
- Python으로 만든 초보자용 할 일 관리 앱
- JSON 파일로 데이터를 저장하고 불러옵니다
============================================================
"""
import json # JSON 파일 읽기/쓰기를 위한 모듈
import os # 파일 존재 여부 확인을 위한 모듈
# ─────────────────────────────────────────
# 설정값: 저장 파일 이름
# ─────────────────────────────────────────
FILE_NAME = "todos.json"
# ══════════════════════════════════════════
# 1. 파일 불러오기
# ══════════════════════════════════════════
def load_todos():
"""
JSON 파일에서 할 일 목록을 불러옵니다.
파일이 없으면 빈 리스트를 반환합니다.
반환값(return):
list: 할 일 딕셔너리들의 리스트
예) [{"id": 1, "task": "공부하기", "done": False}, ...]
"""
# 파일이 존재하는지 먼저 확인
if not os.path.exists(FILE_NAME):
return [] # 파일 없으면 빈 목록 반환
try:
# 파일 열기 (읽기 모드, UTF-8 한글 지원)
with open(FILE_NAME, "r", encoding="utf-8") as f:
return json.load(f) # JSON → 파이썬 리스트로 변환
except json.JSONDecodeError:
# 파일 내용이 깨졌을 때 처리
print("⚠️ 저장 파일이 손상되었습니다. 새로 시작합니다.")
return []
except Exception as e:
# 그 외 예상치 못한 오류 처리
print(f"⚠️ 파일 불러오기 오류: {e}")
return []
# ══════════════════════════════════════════
# 2. 파일 저장하기
# ══════════════════════════════════════════
def save_todos(todos):
"""
할 일 목록을 JSON 파일에 저장합니다.
매개변수(parameter):
todos (list): 저장할 할 일 목록
"""
try:
with open(FILE_NAME, "w", encoding="utf-8") as f:
# indent=2: 보기 좋게 들여쓰기
# ensure_ascii=False: 한글이 깨지지 않도록 설정
json.dump(todos, f, indent=2, ensure_ascii=False)
except Exception as e:
print(f"⚠️ 파일 저장 오류: {e}")
# ══════════════════════════════════════════
# 3. 할 일 추가
# ══════════════════════════════════════════
def add_todo(todos):
"""
새로운 할 일을 목록에 추가합니다.
매개변수(parameter):
todos (list): 현재 할 일 목록 (이 함수 안에서 직접 수정됨)
"""
print("\n[ 할 일 추가 ]")
# 사용자 입력 받기 (빈 입력 방지)
task = input("추가할 할 일을 입력하세요: ").strip()
if not task:
# 아무것도 입력하지 않은 경우
print("❌ 할 일 내용을 입력해야 합니다.")
return
# 새 항목 딕셔너리 만들기
# id: 기존 목록 마지막 번호 + 1 (목록이 비어있으면 1부터 시작)
new_id = todos[-1]["id"] + 1 if todos else 1
new_todo = {
"id": new_id,
"task": task,
"done": False # 처음엔 미완료 상태
}
todos.append(new_todo) # 목록에 추가
save_todos(todos) # 파일에 저장
print(f"✅ '{task}' 이(가) 추가되었습니다!")
# ══════════════════════════════════════════
# 4. 목록 보기
# ══════════════════════════════════════════
def view_todos(todos):
"""
현재 할 일 목록을 화면에 출력합니다.
매개변수(parameter):
todos (list): 현재 할 일 목록
"""
print("\n[ 할 일 목록 ]")
print("─" * 40)
# 목록이 비어있는 경우
if not todos:
print(" 📭 할 일이 없습니다. 새로 추가해보세요!")
print("─" * 40)
return
# 목록 출력
for todo in todos:
# 완료 여부에 따라 체크 표시 변경
status = "✔" if todo["done"] else "○"
task_text = todo["task"]
# 완료된 항목은 취소선 느낌으로 표시
if todo["done"]:
task_text = f"[완료] {task_text}"
print(f" {todo['id']:2}. [{status}] {task_text}")
print("─" * 40)
# 완료/전체 통계 출력
done_count = sum(1 for t in todos if t["done"])
print(f" 총 {len(todos)}개 중 {done_count}개 완료")
# ══════════════════════════════════════════
# 5. 완료 표시
# ══════════════════════════════════════════
def complete_todo(todos):
"""
특정 할 일을 완료 상태로 변경합니다.
매개변수(parameter):
todos (list): 현재 할 일 목록
"""
print("\n[ 완료 표시 ]")
if not todos:
print("❌ 완료할 항목이 없습니다.")
return
view_todos(todos) # 목록 먼저 보여주기
try:
# 번호 입력 받기
todo_id = int(input("완료할 항목 번호를 입력하세요: "))
# 입력한 번호와 일치하는 항목 찾기
for todo in todos:
if todo["id"] == todo_id:
if todo["done"]:
# 이미 완료된 항목인 경우
print(f"ℹ️ '{todo['task']}' 은(는) 이미 완료된 항목입니다.")
else:
todo["done"] = True # 완료 상태로 변경
save_todos(todos) # 파일 저장
print(f"✅ '{todo['task']}' 완료 처리되었습니다!")
return
# 해당 번호가 없는 경우
print(f"❌ {todo_id}번 항목을 찾을 수 없습니다.")
except ValueError:
# 숫자가 아닌 값을 입력한 경우
print("❌ 숫자를 입력해주세요.")
# ══════════════════════════════════════════
# 6. 할 일 삭제
# ══════════════════════════════════════════
def delete_todo(todos):
"""
특정 할 일을 목록에서 삭제합니다.
매개변수(parameter):
todos (list): 현재 할 일 목록
"""
print("\n[ 할 일 삭제 ]")
if not todos:
print("❌ 삭제할 항목이 없습니다.")
return
view_todos(todos) # 목록 먼저 보여주기
try:
todo_id = int(input("삭제할 항목 번호를 입력하세요: "))
# 해당 번호의 항목 찾기
for todo in todos:
if todo["id"] == todo_id:
# 실수로 삭제하는 것을 방지하기 위해 확인
confirm = input(f" '{todo['task']}' 을(를) 삭제할까요? (y/n): ").strip().lower()
if confirm == "y":
todos.remove(todo) # 목록에서 제거
save_todos(todos) # 파일 저장
print("🗑️ 삭제되었습니다.")
else:
print("↩️ 삭제를 취소했습니다.")
return
print(f"❌ {todo_id}번 항목을 찾을 수 없습니다.")
except ValueError:
print("❌ 숫자를 입력해주세요.")
# ══════════════════════════════════════════
# 7. 메뉴 출력
# ══════════════════════════════════════════
def print_menu():
"""
사용자에게 선택 메뉴를 출력합니다.
"""
print("\n" + "═" * 40)
print(" 📝 할 일 관리 프로그램")
print("═" * 40)
print(" 1. 할 일 추가")
print(" 2. 목록 보기")
print(" 3. 완료 표시")
print(" 4. 할 일 삭제")
print(" 0. 종료")
print("─" * 40)
# ══════════════════════════════════════════
# 8. 메인 함수 (프로그램 진입점)
# ══════════════════════════════════════════
def main():
"""
프로그램의 시작점입니다.
메뉴를 반복 출력하고 사용자 선택에 따라 기능을 실행합니다.
"""
print("\n🎉 할 일 관리 프로그램을 시작합니다!")
# 프로그램 시작 시 저장된 파일 불러오기
todos = load_todos()
print(f" → 저장된 항목 {len(todos)}개를 불러왔습니다.")
# 메인 루프: 사용자가 0(종료)을 선택할 때까지 반복
while True:
print_menu() # 메뉴 출력
choice = input("메뉴를 선택하세요 (0~4): ").strip()
# 선택에 따라 해당 함수 실행
if choice == "1":
add_todo(todos)
elif choice == "2":
view_todos(todos)
elif choice == "3":
complete_todo(todos)
elif choice == "4":
delete_todo(todos)
elif choice == "0":
print("\n👋 프로그램을 종료합니다. 수고하셨습니다!")
break # while 루프 종료
else:
# 0~4 이외의 입력 처리
print("❌ 0~4 사이의 숫자를 입력해주세요.")
# ─────────────────────────────────────────
# 이 파일이 직접 실행될 때만 main() 호출
# (다른 파일에서 import 될 때는 실행 안 됨)
# ─────────────────────────────────────────
if __name__ == "__main__":
main()
실습 3 심화: 시니어 개발자 수준의 코드 리뷰
Mission 1: 객체지향(OOP) 리팩토링 요청
"""
============================================================
할 일 관리 프로그램 (To-Do List) - OOP 버전
[클래스 구조]
┌─────────────────────────────────────┐
│ TodoItem │ ← 할 일 1개를 표현하는 클래스
│ - id, task, done │
│ - complete(), to_dict(), __str__ │
├─────────────────────────────────────┤
│ TodoManager │ ← 목록 전체를 관리하는 클래스
│ - todos, file_name │
│ - add(), delete(), complete() │
│ - save(), load(), view() │
├─────────────────────────────────────┤
│ TodoApp │ ← UI/메뉴를 담당하는 클래스
│ - manager │
│ - run(), print_menu() │
└─────────────────────────────────────┘
============================================================
"""
import json
import os
# ══════════════════════════════════════════════════════════
# 클래스 1: TodoItem
# - "할 일 한 개"를 표현하는 클래스
# - 데이터(속성)와 그 데이터를 다루는 행동(메서드)을 함께 묶음
# ══════════════════════════════════════════════════════════
class TodoItem:
"""
할 일 항목 하나를 표현하는 클래스.
속성(Attributes):
id (int) : 고유 번호
task (str) : 할 일 내용
done (bool): 완료 여부 (기본값: False)
"""
def __init__(self, id: int, task: str, done: bool = False):
"""
TodoItem 객체를 생성합니다.
매개변수:
id (int) : 고유 번호
task (str) : 할 일 내용
done (bool): 완료 여부 (기본값: False)
"""
self.id = id
self.task = task
self.done = done
# ──────────────────────────────────
# 메서드: 완료 처리
# ──────────────────────────────────
def complete(self):
"""
이 할 일 항목을 완료 상태로 변경합니다.
이미 완료된 경우 False를 반환해 호출자에게 알립니다.
반환값:
bool: 완료 처리에 성공하면 True, 이미 완료였으면 False
"""
if self.done:
return False # 이미 완료 상태
self.done = True
return True # 완료 처리 성공
# ──────────────────────────────────
# 메서드: 딕셔너리로 변환 (JSON 저장용)
# ──────────────────────────────────
def to_dict(self) -> dict:
"""
이 객체를 딕셔너리 형태로 변환합니다.
JSON 파일에 저장할 때 사용합니다.
반환값:
dict: {"id": ..., "task": ..., "done": ...}
"""
return {
"id": self.id,
"task": self.task,
"done": self.done
}
# ──────────────────────────────────
# 메서드: 딕셔너리 → 객체 변환 (JSON 불러오기용)
# @classmethod: 객체 없이 클래스 이름으로 직접 호출 가능
# ──────────────────────────────────
@classmethod
def from_dict(cls, data: dict) -> "TodoItem":
"""
딕셔너리를 TodoItem 객체로 변환합니다.
JSON 파일에서 불러올 때 사용합니다.
사용 예:
item = TodoItem.from_dict({"id": 1, "task": "공부", "done": False})
반환값:
TodoItem: 새 객체
"""
return cls(
id = data["id"],
task = data["task"],
done = data.get("done", False) # done 키가 없으면 기본값 False
)
# ──────────────────────────────────
# 메서드: 출력 형식 정의
# __str__: print(item) 할 때 자동으로 호출됨
# ──────────────────────────────────
def __str__(self) -> str:
"""
할 일 항목을 사람이 읽기 좋은 문자열로 반환합니다.
반환 예:
" 1. [✔] [완료] 공부하기"
" 2. [○] 운동하기"
"""
status = "✔" if self.done else "○"
task_text = f"[완료] {self.task}" if self.done else self.task
return f" {self.id:2}. [{status}] {task_text}"
# ══════════════════════════════════════════════════════════
# 클래스 2: TodoManager
# - 할 일 목록 전체를 관리하는 클래스
# - 추가/삭제/완료/저장/불러오기 등 핵심 비즈니스 로직 담당
# ══════════════════════════════════════════════════════════
class TodoManager:
"""
할 일 목록 전체를 관리하는 클래스.
속성(Attributes):
file_name (str) : JSON 저장 파일 이름
todos (list) : TodoItem 객체들의 리스트
"""
def __init__(self, file_name: str = "todos_oop.json"):
"""
TodoManager 객체를 생성하고 파일에서 데이터를 불러옵니다.
매개변수:
file_name (str): 저장할 JSON 파일 이름
"""
self.file_name = file_name
self.todos: list[TodoItem] = [] # 빈 목록으로 시작
self.load() # 생성과 동시에 파일 불러오기
# ──────────────────────────────────
# 내부 헬퍼: 다음 ID 생성
# (외부에서 직접 호출하지 않도록 _ 접두사 사용)
# ──────────────────────────────────
def _next_id(self) -> int:
"""
새 항목에 부여할 다음 ID를 계산합니다.
목록이 비어있으면 1, 아니면 마지막 ID + 1
반환값:
int: 다음 ID 번호
"""
return self.todos[-1].id + 1 if self.todos else 1
# ──────────────────────────────────
# 내부 헬퍼: ID로 항목 찾기
# ──────────────────────────────────
def _find_by_id(self, todo_id: int) -> "TodoItem | None":
"""
주어진 ID와 일치하는 TodoItem을 찾아 반환합니다.
없으면 None을 반환합니다.
매개변수:
todo_id (int): 찾을 항목의 ID
반환값:
TodoItem | None
"""
for todo in self.todos:
if todo.id == todo_id:
return todo
return None
# ──────────────────────────────────
# 메서드: 할 일 추가
# ──────────────────────────────────
def add(self, task: str) -> TodoItem:
"""
새로운 할 일을 목록에 추가하고 저장합니다.
매개변수:
task (str): 추가할 할 일 내용
반환값:
TodoItem: 새로 생성된 항목
예외:
ValueError: task가 빈 문자열인 경우
"""
task = task.strip()
if not task:
raise ValueError("할 일 내용이 비어 있습니다.")
new_item = TodoItem(id=self._next_id(), task=task)
self.todos.append(new_item)
self.save()
return new_item
# ──────────────────────────────────
# 메서드: 완료 처리
# ──────────────────────────────────
def complete(self, todo_id: int) -> TodoItem:
"""
특정 ID의 항목을 완료 상태로 변경하고 저장합니다.
매개변수:
todo_id (int): 완료 처리할 항목의 ID
반환값:
TodoItem: 완료 처리된 항목
예외:
KeyError : 해당 ID가 없는 경우
ValueError: 이미 완료된 경우
"""
item = self._find_by_id(todo_id)
if item is None:
raise KeyError(f"{todo_id}번 항목을 찾을 수 없습니다.")
if not item.complete():
raise ValueError(f"'{item.task}' 은(는) 이미 완료된 항목입니다.")
self.save()
return item
# ──────────────────────────────────
# 메서드: 삭제
# ──────────────────────────────────
def delete(self, todo_id: int) -> TodoItem:
"""
특정 ID의 항목을 목록에서 삭제하고 저장합니다.
매개변수:
todo_id (int): 삭제할 항목의 ID
반환값:
TodoItem: 삭제된 항목
예외:
KeyError: 해당 ID가 없는 경우
"""
item = self._find_by_id(todo_id)
if item is None:
raise KeyError(f"{todo_id}번 항목을 찾을 수 없습니다.")
self.todos.remove(item)
self.save()
return item
# ──────────────────────────────────
# 메서드: JSON 파일에 저장
# ──────────────────────────────────
def save(self):
"""
현재 todos 목록을 JSON 파일에 저장합니다.
각 TodoItem의 to_dict() 메서드를 활용합니다.
"""
try:
data = [item.to_dict() for item in self.todos]
with open(self.file_name, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
except Exception as e:
print(f"⚠️ 저장 오류: {e}")
# ──────────────────────────────────
# 메서드: JSON 파일에서 불러오기
# ──────────────────────────────────
def load(self):
"""
JSON 파일에서 데이터를 불러와 TodoItem 객체 리스트로 변환합니다.
파일이 없으면 조용히 넘어갑니다.
"""
if not os.path.exists(self.file_name):
return # 파일 없으면 그냥 빈 목록 유지
try:
with open(self.file_name, "r", encoding="utf-8") as f:
data = json.load(f)
# 딕셔너리 → TodoItem 객체로 변환 (from_dict 활용)
self.todos = [TodoItem.from_dict(d) for d in data]
except json.JSONDecodeError:
print("⚠️ 저장 파일이 손상되었습니다. 새로 시작합니다.")
self.todos = []
except Exception as e:
print(f"⚠️ 불러오기 오류: {e}")
self.todos = []
# ──────────────────────────────────
# 프로퍼티: 통계 정보
# @property: 메서드를 속성처럼 접근 가능 (괄호 없이 호출)
# ──────────────────────────────────
@property
def total_count(self) -> int:
"""전체 할 일 개수"""
return len(self.todos)
@property
def done_count(self) -> int:
"""완료된 할 일 개수"""
return sum(1 for item in self.todos if item.done)
# ══════════════════════════════════════════════════════════
# 클래스 3: TodoApp
# - 사용자 인터페이스(UI)와 메뉴를 담당하는 클래스
# - TodoManager를 "사용"하여 실제 작업을 위임
# - 화면 출력·입력 처리만 이 클래스가 담당
# ══════════════════════════════════════════════════════════
class TodoApp:
"""
사용자 인터페이스를 담당하는 클래스.
TodoManager를 내부에 보유하여 실제 로직은 위임합니다.
속성(Attributes):
manager (TodoManager): 할 일 목록 관리 객체
"""
def __init__(self):
"""
TodoApp 객체를 생성합니다.
내부적으로 TodoManager를 생성하여 데이터를 불러옵니다.
"""
# TodoManager 객체를 생성 — 파일 불러오기도 자동 실행됨
self.manager = TodoManager()
# ──────────────────────────────────
# 메서드: 메뉴 출력
# ──────────────────────────────────
def _print_menu(self):
"""메인 메뉴를 화면에 출력합니다."""
print("\n" + "═" * 40)
print(" 📝 할 일 관리 프로그램 (OOP)")
print("═" * 40)
print(" 1. 할 일 추가")
print(" 2. 목록 보기")
print(" 3. 완료 표시")
print(" 4. 할 일 삭제")
print(" 0. 종료")
print("─" * 40)
# ──────────────────────────────────
# 메서드: 목록 출력
# ──────────────────────────────────
def _print_todos(self):
"""현재 할 일 목록을 화면에 출력합니다."""
print("\n[ 할 일 목록 ]")
print("─" * 40)
if self.manager.total_count == 0:
print(" 📭 할 일이 없습니다. 새로 추가해보세요!")
else:
# TodoItem의 __str__ 메서드가 자동으로 호출됨
for item in self.manager.todos:
print(item)
print("─" * 40)
print(f" 총 {self.manager.total_count}개 중 "
f"{self.manager.done_count}개 완료")
# ──────────────────────────────────
# 메서드: 할 일 추가 화면
# ──────────────────────────────────
def _handle_add(self):
"""할 일 추가 화면을 처리합니다."""
print("\n[ 할 일 추가 ]")
task = input("추가할 할 일을 입력하세요: ")
try:
new_item = self.manager.add(task)
print(f"✅ '{new_item.task}' 이(가) 추가되었습니다!")
except ValueError as e:
# manager.add()에서 발생한 ValueError 처리
print(f"❌ {e}")
# ──────────────────────────────────
# 메서드: 완료 처리 화면
# ──────────────────────────────────
def _handle_complete(self):
"""완료 처리 화면을 처리합니다."""
print("\n[ 완료 표시 ]")
if self.manager.total_count == 0:
print("❌ 완료할 항목이 없습니다.")
return
self._print_todos()
try:
todo_id = int(input("완료할 항목 번호를 입력하세요: "))
item = self.manager.complete(todo_id)
print(f"✅ '{item.task}' 완료 처리되었습니다!")
except ValueError as e:
# int() 변환 실패 또는 이미 완료된 경우
print(f"❌ {e}")
except KeyError as e:
# 해당 ID가 없는 경우
print(f"❌ {e}")
# ──────────────────────────────────
# 메서드: 삭제 화면
# ──────────────────────────────────
def _handle_delete(self):
"""할 일 삭제 화면을 처리합니다."""
print("\n[ 할 일 삭제 ]")
if self.manager.total_count == 0:
print("❌ 삭제할 항목이 없습니다.")
return
self._print_todos()
try:
todo_id = int(input("삭제할 항목 번호를 입력하세요: "))
item = self.manager.delete.__func__ # 먼저 존재 확인
# 삭제 전 확인
found = self.manager._find_by_id(todo_id)
if found is None:
print(f"❌ {todo_id}번 항목을 찾을 수 없습니다.")
return
confirm = input(f" '{found.task}' 을(를) 삭제할까요? (y/n): ").strip().lower()
if confirm == "y":
deleted = self.manager.delete(todo_id)
print(f"🗑️ '{deleted.task}' 이(가) 삭제되었습니다.")
else:
print("↩️ 삭제를 취소했습니다.")
except ValueError:
print("❌ 숫자를 입력해주세요.")
except KeyError as e:
print(f"❌ {e}")
# ──────────────────────────────────
# 메서드: 메인 루프 실행
# ──────────────────────────────────
def run(self):
"""
프로그램의 메인 루프를 실행합니다.
사용자가 0을 입력할 때까지 메뉴를 반복 출력합니다.
"""
print("\n🎉 할 일 관리 프로그램을 시작합니다! (OOP 버전)")
print(f" → 저장된 항목 {self.manager.total_count}개를 불러왔습니다.")
# 메뉴 선택지와 실행할 메서드를 딕셔너리로 매핑
# → if/elif 없이 깔끔하게 처리 가능
menu_actions = {
"1": self._handle_add,
"2": self._print_todos,
"3": self._handle_complete,
"4": self._handle_delete,
}
while True:
self._print_menu()
choice = input("메뉴를 선택하세요 (0~4): ").strip()
if choice == "0":
print("\n👋 프로그램을 종료합니다. 수고하셨습니다!")
break
action = menu_actions.get(choice) # 딕셔너리에서 함수 가져오기
if action:
action() # 해당 메서드 실행
else:
print("❌ 0~4 사이의 숫자를 입력해주세요.")
# ──────────────────────────────────────────
# 프로그램 진입점
# ──────────────────────────────────────────
if __name__ == "__main__":
# TodoApp 객체 하나 생성 후 실행
# → 모든 상태(데이터)가 객체 안에 캡슐화됨
app = TodoApp()
app.run()
Mission 2: 내 코드 분석 받기
실습 4: ChatGPT vs Claude 블라인드 테스트
테스트 1: 논리적 분석력'
Chat GPT
Claude
테스트 2: 창의적 글쓰기
Chat GPT
Claude
평가
체계성
Chat GPT가 Claude에 비해 배경 설명이나 인과관계가 충분히 드러나지 않아 체계성은 Claude가 더 우세하다
흥미도
Claude의 글은 문장이 항상 ~다. 로 끝나 비교적 단조롭게 느껴진다. Chat GPT는 짧지만 단조롭지않은 문장 구성으로 이미지가 잘 떠오르는 편이다. 흥므도는 Chat GPT가 더 우세하다.
응답스타일
Chat GPT는 간결하고 과한 설명 없이 메시지를 전달하는 방식, Claude는 대화처럼 자연스럽게 짧은 질문엔 짧게 답하고, 복잡한 주제엔 필요한 만큼 답한다.
중간고사 대비 AI활용 과제 및 문의
AI 기술의 진화와 역사 (Week 1~2)
디지털 전환(DX) 3단계:
[Digitization]: 아날로그 정보를 디지털 형태로 변환.
[Digitalization]: 개별 업무 프로세스를 디지털화.
[Digital Transformation]: AI를 통해 비즈니스 모델 자체를 혁신하는 최종 단계.
AI의 역사적 흐름: 1956년 다트머스 회의(AI 용어 탄생) → 두 번의 AI 겨울 → 2012년 AlexNet(딥러닝 시대 개막) → 2022년 ChatGPT(AI 대중화).
기술의 4단계 진화: [규칙 기반] (If-Then) → [머신러닝] (데이터 학습) → [딥러닝] (인공신경망) → [LLM] (거대 언어 모델).
머신러닝과 딥러닝의 이해 (Week 3)
머신러닝의 3가지 학습 방법 지도학습 (Supervised Learning): 정답(Label)이 있는 데이터로 학습합니다. (예: 이미지 분류, 스팸 필터)
비지도학습 (Unsupervised Learning): 정답 없이 데이터의 패턴이나 규칙을 스스로 발견합니다. (예: 고객 군집화, 이상 탐지)
강화학습 (Reinforcement Learning): 행동에 따른 보상과 벌칙을 통해 최적의 방법을 찾아갑니다. (예: 알파고, 자율주행)
딥러닝과 신경망 딥러닝: 인간의 뇌 구조를 모방한 인공신경망을 여러 층(Layer)으로 쌓아 복잡한 패턴을 학습하는 기술입니다.
주요 신경망 구조:
CNN (합성곱 신경망): 이미지 처리에 특화되어 있으며, 사물의 위치가 바뀌어도 인식 가능한 특징이 있습니다.
Transformer: 문장 내 단어 간의 관계를 파악하는 데 강점이 있어 언어 모델의 핵심 기술로 쓰입니다.
LLM(대규모 언어 모델)의 원리 (Week 4)
LLM의 정의 및 특징 수십억 개 이상의 매개변수를 가진 모델로, 방대한 텍스트를 학습하여 다음 단어를 예측하는 방식으로 문장을 생성합니다.
Transformer 아키텍처: 문장 전체를 한 번에 처리하며 '어텐션(Attention)' 메커니즘을 통해 중요한 단어에 집중합니다.
핵심 개념 토큰화(Tokenization): 텍스트를 최소 단위인 토큰으로 나누는 과정입니다. 한국어는 영어보다 토큰을 더 많이 사용하는 경향이 있어 비용과 처리 시간에 영향을 줍니다.
환각(Hallucination): AI가 사실이 아닌 정보를 마치 사실인 것처럼 자신 있게 말하는 현상입니다.
RAG (검색 증강 생성): 외부 데이터베이스에서 정보를 검색하여 응답에 활용함으로써 환각 현상을 줄이는 기술입니다.
ChatGPT 활용 및 프롬프트 엔지니어링 (Week 5)
프롬프트 엔지니어링 5대 원칙 원하는 결과를 얻기 위해 프롬프트를 설계하는 기술입니다.
명확하게: 모호한 표현을 피하고 정확한 지시를 내립니다.
구체적으로: 분량, 형식, 대상 등을 상세히 지정합니다.
맥락 제공: 배경 정보와 현재 상황을 설명합니다.
역할 부여: AI에게 전문가의 페르소나를 부여합니다. (예: "당신은 10년 차 마케터입니다.")
예시 제공 (Few-shot): 원하는 출력 형식의 예시를 1~3개 제공하여 패턴을 파악하게 합니다.
고급 기법 단계별 사고 (Chain-of-Thought): "단계별로 생각해봐"라고 요청하여 복잡한 문제의 정확도를 높입니다.
Claude 활용 및 도구별 비교 (Week 6)
Claude의 특징 Anthropic 사에서 개발하였으며, AI의 안전성과 윤리성을 강조하는 Constitutional AI 기술이 적용되었습니다.
Claude Opus 4.5: 200K 토큰(약 500페이지)의 방대한 컨텍스트 창을 지원하여 긴 문서 분석에 매우 유리하며, 코딩 능력(SWE-bench 1위)이 뛰어납니다.
도구별 선택 가이드 ChatGPT: 창의적 글쓰기, 이미지 생성(DALL-E 3), 풍부한 플러그인 생태계와 한국어 성능이 강점입니다.
Claude: 논리적 분석, 복잡한 코딩, 긴 문서 요약 및 분석, 정직한 답변(모르는 것은 모른다고 인정)이 강점입니다.
Gemini: Google 서비스와의 연동, 실시간 웹 검색 및 멀티모달 기능이 뛰어납니다.
중간고사 대비 예상 문제
Q1. 다음 중 비지도학습의 사례로 가장 적절한 것은? ① 개와 고양이 사진을 구분하는 AI 생성 ② 스팸 메일을 자동으로 분류하는 필터 제작 ③ 쇼핑몰 고객들의 구매 패턴을 분석하여 비슷한 그룹으로 묶기 ④ 체스 게임에서 승리하기 위한 전략 학습
Q2. 프롬프트 엔지니어링에서 'Few-shot Learning'이란 무엇을 의미하나요? (정답: AI에게 원하는 결과의 예시를 몇 가지 제공하여 출력의 품질과 형식을 일관되게 유지하는 기법)
Q3. Claude가 ChatGPT와 비교했을 때 가지는 독보적인 강점 두 가지는? (정답: 긴 문서 분석 능력(대용량 컨텍스트 윈도우)과 높은 수준의 코딩 및 논리적 추론 능력)
Q4. LLM이 거짓 정보를 생성하는 '환각' 현상을 방지하기 위한 기술적 대안은? (정답: RAG - Retrieval-Augmented Generation / 검색 증강 생성)