Files
ax_document/AI로 일하는 방법/generate_ai_work_ppt.py
dsyoon b0a2b0eec4 Initial commit
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-25 17:58:49 +09:00

1210 lines
57 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Iterable, Sequence
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE
from pptx.enum.text import PP_ALIGN
from pptx.util import Inches, Pt
@dataclass(frozen=True)
class Theme:
navy: RGBColor
navy_2: RGBColor
bg: RGBColor
white: RGBColor
text: RGBColor
muted: RGBColor
line: RGBColor
accent_yellow: RGBColor
accent_blue: RGBColor
accent_red: RGBColor
accent_green: RGBColor
font: str
font_bold: str
T = Theme(
navy=RGBColor(0x10, 0x1D, 0x2E),
navy_2=RGBColor(0x14, 0x2A, 0x45),
bg=RGBColor(0xF6, 0xF7, 0xFB),
white=RGBColor(0xFF, 0xFF, 0xFF),
text=RGBColor(0x1F, 0x29, 0x37),
muted=RGBColor(0x6B, 0x72, 0x80),
line=RGBColor(0xE5, 0xE7, 0xEB),
accent_yellow=RGBColor(0xF0, 0xB4, 0x3B),
accent_blue=RGBColor(0x3B, 0x82, 0xF6),
accent_red=RGBColor(0xEF, 0x44, 0x44),
accent_green=RGBColor(0x22, 0xC5, 0x5E),
font="Apple SD Gothic Neo",
font_bold="Apple SD Gothic Neo",
)
SLIDE_W = Inches(13.333)
SLIDE_H = Inches(7.5)
def _rgb(hex6: str) -> RGBColor:
h = hex6.lstrip("#")
return RGBColor(int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))
def set_slide_bg(slide, color: RGBColor) -> None:
fill = slide.background.fill
fill.solid()
fill.fore_color.rgb = color
def add_rect(slide, x, y, w, h, *, fill: RGBColor | None, line: RGBColor | None, radius: bool = False):
shape_type = MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE if radius else MSO_AUTO_SHAPE_TYPE.RECTANGLE
shp = slide.shapes.add_shape(shape_type, x, y, w, h)
if fill is None:
shp.fill.background()
else:
shp.fill.solid()
shp.fill.fore_color.rgb = fill
if line is None:
shp.line.fill.background()
else:
shp.line.color.rgb = line
shp.line.width = Pt(1)
return shp
def add_textbox(
slide,
x,
y,
w,
h,
text: str,
*,
size: int,
bold: bool = False,
color: RGBColor | None = None,
align: int = PP_ALIGN.LEFT,
line_spacing: float | None = None,
):
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.clear()
p = tf.paragraphs[0]
run = p.add_run()
run.text = text
f = run.font
f.name = T.font_bold if bold else T.font
f.size = Pt(size)
f.bold = bold
f.color.rgb = color or T.text
p.alignment = align
if line_spacing is not None:
p.line_spacing = line_spacing
return tb
def add_bullets(
slide,
x,
y,
w,
h,
bullets: Sequence[str],
*,
size: int = 18,
color: RGBColor | None = None,
bullet_color: RGBColor | None = None,
line_spacing: float = 1.15,
):
tb = slide.shapes.add_textbox(x, y, w, h)
tf = tb.text_frame
tf.clear()
tf.word_wrap = True
for i, b in enumerate(bullets):
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
p.text = b
p.level = 0
p.font.name = T.font
p.font.size = Pt(size)
p.font.color.rgb = color or T.text
p.line_spacing = line_spacing
p.space_after = Pt(6)
p.bullet = True
if bullet_color is not None:
# python-pptx doesn't support bullet color directly; keep as text color.
pass
return tb
def add_pill(slide, x, y, w, h, text: str, *, fill: RGBColor, fg: RGBColor):
pill = add_rect(slide, x, y, w, h, fill=fill, line=None, radius=True)
tf = pill.text_frame
tf.clear()
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.CENTER
run = p.add_run()
run.text = text
run.font.name = T.font
run.font.size = Pt(12)
run.font.color.rgb = fg
return pill
def add_footer(slide, slide_no: int, *, dark: bool) -> None:
y = SLIDE_H - Inches(0.35)
add_rect(slide, Inches(0), y, SLIDE_W, Inches(0.35), fill=(T.navy if dark else T.bg), line=None, radius=False)
fg = _rgb("#D1D5DB") if dark else T.muted
add_textbox(
slide,
Inches(0.5),
y + Inches(0.06),
Inches(6),
Inches(0.25),
"윤도상 | 2026.03",
size=11,
bold=False,
color=fg,
align=PP_ALIGN.LEFT,
)
add_textbox(
slide,
SLIDE_W - Inches(2.0),
y + Inches(0.06),
Inches(1.5),
Inches(0.25),
f"Slide {slide_no:02d}" if dark else f"{slide_no:02d}",
size=11,
bold=False,
color=fg,
align=PP_ALIGN.RIGHT,
)
def add_title_block(
slide,
title: str,
subtitle: str | None = None,
*,
dark: bool,
y: float = 0.6,
pretitle: str | None = None,
):
fg = T.white if dark else T.text
if pretitle:
add_textbox(
slide,
Inches(0.7),
Inches(y),
Inches(12),
Inches(0.3),
pretitle,
size=14,
bold=True,
color=T.accent_yellow if dark else T.accent_yellow,
)
y += 0.35
add_textbox(
slide,
Inches(0.7),
Inches(y),
Inches(12),
Inches(0.8),
title,
size=40 if len(title) <= 18 else 34,
bold=True,
color=fg,
)
if subtitle:
add_textbox(
slide,
Inches(0.7),
Inches(y + 0.85),
Inches(12),
Inches(0.4),
subtitle,
size=18,
bold=True,
color=T.accent_yellow if dark else T.muted,
)
def add_card(
slide,
x,
y,
w,
h,
*,
title: str,
body: Sequence[str],
accent: RGBColor,
dark_text: bool = True,
):
add_rect(slide, x, y, w, h, fill=T.white, line=T.line, radius=True)
add_rect(slide, x, y, w, Inches(0.08), fill=accent, line=None, radius=False)
add_textbox(
slide,
x + Inches(0.25),
y + Inches(0.4),
w - Inches(0.5),
Inches(0.4),
title,
size=18,
bold=True,
color=T.text if dark_text else T.white,
)
add_bullets(
slide,
x + Inches(0.25),
y + Inches(0.9),
w - Inches(0.5),
h - Inches(1.1),
list(body),
size=14,
color=T.muted,
line_spacing=1.2,
)
def slide_01_cover(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.navy)
add_pill(
s,
Inches(4.2),
Inches(0.35),
Inches(4.9),
Inches(0.42),
"LLM AI 툴 활용 교육",
fill=_rgb("#24364D"),
fg=_rgb("#E5E7EB"),
)
add_textbox(s, Inches(3.6), Inches(2.1), Inches(6.2), Inches(0.9), "AI에게", size=54, bold=True, color=T.white, align=PP_ALIGN.CENTER)
add_textbox(s, Inches(2.9), Inches(3.05), Inches(7.6), Inches(0.9), "잘 시키는 법", size=54, bold=True, color=T.white, align=PP_ALIGN.CENTER)
add_rect(s, Inches(6.1), Inches(4.1), Inches(1.2), Inches(0.05), fill=T.accent_yellow, line=None)
add_textbox(
s,
Inches(2.4),
Inches(4.35),
Inches(8.6),
Inches(0.5),
"실무자를 위한 LLM 프롬프트 & 워크플로우 완전 가이드",
size=18,
bold=True,
color=T.accent_yellow,
align=PP_ALIGN.CENTER,
)
add_footer(s, 1, dark=True)
def slide_02_core_assumptions(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "AI 활용의 핵심 전제 3가지", size=14, bold=True, color=T.accent_yellow)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "이것만 알아도 80%", size=40, bold=True, color=T.text)
add_pill(s, Inches(10.1), Inches(1.1), Inches(2.6), Inches(0.38), "Chapter 1. AI는 어떻게 생각하는가?", fill=_rgb("#EEF2F7"), fg=T.muted)
cw = Inches(3.95)
ch = Inches(2.7)
y = Inches(2.05)
gap = Inches(0.4)
x1 = Inches(0.7)
add_card(
s,
x1,
y,
cw,
ch,
title="AI는 당신이 준\n정보만큼 답한다",
body=["입력(Prompt)의 질이 곧", "출력(Output)의 질을 결정합니다.", "맥락이 없으면 답도 없습니다."],
accent=T.accent_blue,
)
add_card(
s,
x1 + cw + gap,
y,
cw,
ch,
title="AI는 틀린 답을\n자신 있게 말한다",
body=["환각(Hallucination) 현상은", "AI의 구조적 특성입니다.", "절대 맹신하지 마세요."],
accent=T.accent_red,
)
add_card(
s,
x1 + (cw + gap) * 2,
y,
cw,
ch,
title="AI는 도구이지,\n판단자가 아니다",
body=["결과물에 대한 최종 검증과", "책임은 항상 사람(나)에게", "있습니다."],
accent=T.accent_green,
)
bar_y = Inches(5.55)
add_rect(s, Inches(0.7), bar_y, Inches(11.93), Inches(0.85), fill=T.navy_2, line=None, radius=True)
add_pill(s, Inches(0.95), bar_y + Inches(0.18), Inches(1.15), Inches(0.42), "실제 사례", fill=T.accent_yellow, fg=T.navy)
add_pill(s, Inches(2.2), bar_y + Inches(0.18), Inches(3.1), Inches(0.42), "\"세차장에 갑니다\" (중의적)", fill=_rgb("#2B3E59"), fg=_rgb("#E5E7EB"))
add_textbox(s, Inches(5.35), bar_y + Inches(0.18), Inches(0.4), Inches(0.42), "", size=22, bold=True, color=T.accent_yellow, align=PP_ALIGN.CENTER)
add_pill(s, Inches(5.7), bar_y + Inches(0.18), Inches(3.2), Inches(0.42), "\"세차하러 갑니다\" (명확)", fill=_rgb("#2B3E59"), fg=_rgb("#E5E7EB"))
add_textbox(
s,
Inches(9.1),
bar_y + Inches(0.18),
Inches(3.3),
Inches(0.42),
"정보 단 하나(목적) 차이로\nAI의 답변 품질이 완전히 달라집니다!",
size=12,
bold=True,
color=_rgb("#E5E7EB"),
align=PP_ALIGN.RIGHT,
)
add_footer(s, 2, dark=False)
def slide_03_llm(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.navy)
add_title_block(s, "LLM이란 무엇인가?", "Large Language Model — 대규모 언어 모델", dark=True, y=0.5)
add_pill(s, Inches(11.5), Inches(0.6), Inches(1.4), Inches(0.38), "Chapter 1", fill=_rgb("#24364D"), fg=_rgb("#E5E7EB"))
x = Inches(0.7)
y = Inches(2.0)
w = Inches(4.8)
h = Inches(1.05)
gap = Inches(0.35)
def left_item(yy, title, desc):
add_rect(s, x, yy, w, h, fill=_rgb("#1B2A3F"), line=_rgb("#2B3E59"), radius=True)
add_textbox(s, x + Inches(0.3), yy + Inches(0.2), w - Inches(0.6), Inches(0.35), title, size=18, bold=True, color=T.white)
add_textbox(s, x + Inches(0.3), yy + Inches(0.55), w - Inches(0.6), Inches(0.45), desc, size=13, bold=False, color=_rgb("#D1D5DB"))
left_item(y, "확률 기반 언어 예측", "다음에 올 단어를 통계적으로\n예측하는 '확률 기계'입니다.")
left_item(y + h + gap, "\"지식\"이 아닌 \"패턴\"", "사전처럼 정답을 저장한 것이 아니라,\n수많은 문장의 패턴을 학습했습니다.")
left_item(y + (h + gap) * 2, "확률적 답변 생성", "같은 질문에도 매번 확률적으로\n가장 자연스러운 답을 생성합니다.")
# Right diagram card
rx = Inches(5.8)
ry = Inches(2.05)
rw = Inches(7.0)
rh = Inches(4.25)
add_rect(s, rx, ry, rw, rh, fill=_rgb("#1B2A3F"), line=_rgb("#2B3E59"), radius=True)
add_textbox(s, rx + Inches(0.35), ry + Inches(0.25), Inches(4), Inches(0.35), "LLM 작동 프로세스 예시", size=13, bold=True, color=_rgb("#9CA3AF"))
# INPUT box
add_textbox(s, rx + Inches(0.55), ry + Inches(0.8), Inches(1.5), Inches(0.3), "INPUT (입력)", size=11, bold=True, color=_rgb("#9CA3AF"))
add_rect(s, rx + Inches(0.55), ry + Inches(1.15), Inches(2.2), Inches(0.85), fill=_rgb("#132236"), line=_rgb("#2B3E59"), radius=True)
add_textbox(
s,
rx + Inches(0.7),
ry + Inches(1.28),
Inches(1.9),
Inches(0.55),
"\"대한민국의\n수도는\"",
size=16,
bold=True,
color=T.white,
align=PP_ALIGN.CENTER,
)
# Prediction circle
add_textbox(s, rx + Inches(3.0), ry + Inches(0.8), Inches(2.5), Inches(0.3), "PREDICTION (예측)", size=11, bold=True, color=T.accent_yellow, align=PP_ALIGN.CENTER)
circ = s.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.OVAL, rx + Inches(3.2), ry + Inches(1.05), Inches(2.55), Inches(2.55))
circ.fill.background()
circ.line.color.rgb = T.accent_yellow
circ.line.width = Pt(2)
# Prob bars inside
add_textbox(s, rx + Inches(3.35), ry + Inches(1.45), Inches(2.25), Inches(0.25), "서울 92%", size=11, bold=True, color=_rgb("#E5E7EB"))
add_rect(s, rx + Inches(3.35), ry + Inches(1.72), Inches(2.1), Inches(0.08), fill=T.accent_yellow, line=None)
add_textbox(s, rx + Inches(3.35), ry + Inches(1.95), Inches(2.25), Inches(0.25), "부산 5%", size=11, bold=False, color=_rgb("#9CA3AF"))
add_rect(s, rx + Inches(3.35), ry + Inches(2.22), Inches(0.55), Inches(0.08), fill=_rgb("#64748B"), line=None)
add_textbox(s, rx + Inches(3.35), ry + Inches(2.45), Inches(2.25), Inches(0.25), "평양 1%", size=11, bold=False, color=_rgb("#9CA3AF"))
add_rect(s, rx + Inches(3.35), ry + Inches(2.72), Inches(0.25), Inches(0.08), fill=_rgb("#64748B"), line=None)
# OUTPUT box
add_textbox(s, rx + Inches(5.85), ry + Inches(0.8), Inches(1.5), Inches(0.3), "OUTPUT (출력)", size=11, bold=True, color=_rgb("#9CA3AF"), align=PP_ALIGN.RIGHT)
add_rect(s, rx + Inches(5.6), ry + Inches(1.25), Inches(2.15), Inches(0.85), fill=_rgb("#0F2C2A"), line=_rgb("#34D399"), radius=True)
add_textbox(
s,
rx + Inches(5.75),
ry + Inches(1.38),
Inches(1.85),
Inches(0.55),
"\"서울입니다.\"",
size=18,
bold=True,
color=_rgb("#A7F3D0"),
align=PP_ALIGN.CENTER,
)
# Arrows
add_textbox(s, rx + Inches(2.85), ry + Inches(1.45), Inches(0.3), Inches(0.3), "", size=28, bold=True, color=_rgb("#9CA3AF"), align=PP_ALIGN.CENTER)
add_textbox(s, rx + Inches(5.45), ry + Inches(1.45), Inches(0.3), Inches(0.3), "", size=28, bold=True, color=_rgb("#9CA3AF"), align=PP_ALIGN.CENTER)
add_rect(s, rx + Inches(0.45), ry + Inches(3.8), rw - Inches(0.9), Inches(0.55), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(
s,
rx + Inches(0.7),
ry + Inches(3.92),
rw - Inches(1.4),
Inches(0.3),
"ChatGPT, Claude, Gemini 등은 모두 이와 같은 원리로 작동합니다.",
size=12,
bold=True,
color=_rgb("#D1D5DB"),
align=PP_ALIGN.CENTER,
)
add_footer(s, 3, dark=True)
def slide_04_good_vs_bad(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "효율적인 AI 활용을 위한 첫걸음", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI가 잘하는 것 vs 못하는 것", size=40, bold=True, color=T.text)
add_pill(s, Inches(9.9), Inches(1.1), Inches(2.95), Inches(0.38), "Chapter 1. AI의 본질 이해", fill=_rgb("#EEF2F7"), fg=T.muted)
left_x = Inches(0.8)
col_y = Inches(2.0)
col_w = Inches(6.05)
col_h = Inches(4.25)
right_x = Inches(6.45)
add_rect(s, left_x, col_y, col_w, col_h, fill=_rgb("#E9FBF1"), line=None, radius=True)
add_rect(s, right_x, col_y, col_w, col_h, fill=_rgb("#FDECEC"), line=None, radius=True)
add_textbox(s, left_x + Inches(0.35), col_y + Inches(0.3), col_w - Inches(0.7), Inches(0.35), "✓ AI가 잘하는 것", size=20, bold=True, color=_rgb("#15803D"))
add_textbox(s, right_x + Inches(0.35), col_y + Inches(0.3), col_w - Inches(0.7), Inches(0.35), "✕ AI가 못하는 것 / 주의", size=20, bold=True, color=_rgb("#B91C1C"))
good = [
"구조화된 글 작성 및 요약",
"번역 및 언어 변환",
"패턴 인식 및 분류",
"코드 생성 및 디버깅",
"반복 업무 자동화",
"대용량 문서 핵심 추출",
]
bad = [
"최신 실시간 정보 확인 (검색 미연동 시)",
"복잡한 수학 계산·논리적 검증",
"사용자의 숨겨진 의도 자동 파악",
"사실 여부 100% 보장 (환각 위험)",
"인간적 감각·경험 기반의 판단",
"결과물에 대한 법적 책임",
]
add_bullets(s, left_x + Inches(0.55), col_y + Inches(0.9), col_w - Inches(1.1), col_h - Inches(1.2), good, size=16, color=T.text)
add_bullets(s, right_x + Inches(0.55), col_y + Inches(0.9), col_w - Inches(1.1), col_h - Inches(1.2), bad, size=16, color=T.text)
# Center VS bubble
vs = s.shapes.add_shape(MSO_AUTO_SHAPE_TYPE.OVAL, Inches(6.1), Inches(3.8), Inches(0.7), Inches(0.7))
vs.fill.solid()
vs.fill.fore_color.rgb = _rgb("#EEF2F7")
vs.line.color.rgb = T.line
vs.text_frame.text = "VS"
vs.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
vs.text_frame.paragraphs[0].runs[0].font.name = T.font_bold
vs.text_frame.paragraphs[0].runs[0].font.bold = True
vs.text_frame.paragraphs[0].runs[0].font.size = Pt(14)
vs.text_frame.paragraphs[0].runs[0].font.color.rgb = T.muted
# Bottom callout
add_rect(s, Inches(0.7), Inches(6.55), Inches(11.93), Inches(0.65), fill=T.navy_2, line=None, radius=True)
add_textbox(
s,
Inches(0.95),
Inches(6.66),
Inches(11.4),
Inches(0.42),
"AI를 \"잘 쓴다\"는 것은, AI가 못하는 영역을 사람이 보완한다는 뜻입니다.",
size=16,
bold=True,
color=_rgb("#E5E7EB"),
align=PP_ALIGN.CENTER,
)
add_footer(s, 4, dark=False)
def slide_05_hallucination(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "⚠ 왜 AI는 그럴듯하게 거짓말하는가?", size=14, bold=True, color=T.accent_red)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI의 환각(Hallucination) 현상", size=40, bold=True, color=T.text)
add_pill(s, Inches(11.2), Inches(1.05), Inches(1.55), Inches(0.4), "Critical Issue", fill=_rgb("#FEE2E2"), fg=_rgb("#B91C1C"))
# Definition box
add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(1.0), fill=_rgb("#F3F4F6"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(2.05), Inches(11.3), Inches(0.3), "환각(Hallucination)이란?", size=16, bold=True, color=T.text)
add_textbox(
s,
Inches(1.0),
Inches(2.35),
Inches(11.3),
Inches(0.5),
"AI가 사실이 아닌 내용을 마치 사실인 것처럼 자신 있게 답하는 현상입니다.\n"
"AI는 확률적으로 '자연스러운 문장'을 생성하는 과정에서 거짓 정보를 유창하게 만들어낼 수 있습니다.",
size=13,
bold=False,
color=T.muted,
line_spacing=1.2,
)
# Risk cards
x = Inches(0.7)
y = Inches(3.1)
w = Inches(3.82)
h = Inches(1.55)
g = Inches(0.35)
def risk(xx, title, bullets):
add_rect(s, xx, y, w, h, fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
add_textbox(s, xx + Inches(0.25), y + Inches(0.2), w - Inches(0.5), Inches(0.3), title, size=14, bold=True, color=_rgb("#B91C1C"))
add_bullets(s, xx + Inches(0.25), y + Inches(0.55), w - Inches(0.5), h - Inches(0.6), bullets, size=12, color=_rgb("#7F1D1D"))
risk(x, "가짜 정보 생성 사례", ["존재하지 않는 논문·자료 인용", "역사적 사실을 왜곡하여 설명", "없는 기능을 가진 것처럼 설명"])
risk(x + w + g, "수치 오류 사례", ["틀린 계산 결과를 정확한 척 제시", "단위(원, 달러) 혼동하여 표기", "최신 통계가 아닌 과거 데이터 인용"])
risk(x + (w + g) * 2, "법적/규정 위험 사례", ["개정 전 법률이나 규정을 답변", "저작권/라이선스 규정을 무시한 활용", "개인정보 보호 규정을 위반하는 제안"])
add_textbox(s, Inches(0.7), Inches(4.85), Inches(12), Inches(0.3), "✅ 환각을 피하는 3가지 습관", size=16, bold=True, color=_rgb("#15803D"))
# Habits
hy = Inches(5.2)
hw = Inches(3.82)
hh = Inches(1.1)
def habit(xx, title, desc):
add_rect(s, xx, hy, hw, hh, fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, xx + Inches(0.25), hy + Inches(0.25), hw - Inches(0.5), Inches(0.25), title, size=14, bold=True, color=_rgb("#15803D"), align=PP_ALIGN.CENTER)
add_textbox(s, xx + Inches(0.25), hy + Inches(0.55), hw - Inches(0.5), Inches(0.4), desc, size=12, bold=False, color=_rgb("#166534"), align=PP_ALIGN.CENTER, line_spacing=1.2)
habit(Inches(0.7), "원문 대조 확인", "중요한 수치·법률·사실 관계는\n반드시 원문 문서와 대조하세요.")
habit(Inches(0.7) + hw + g, "출처 요청하기", "\"이 정보의 출처(URL)를 알려줘\"라고\n요청하여 근거를 확인하세요.")
habit(Inches(0.7) + (hw + g) * 2, "'초안'으로만 활용", "AI 답변은 최종 결과물이 아닌\n'검토가 필요한 초안'으로 대하세요.")
add_footer(s, 5, dark=False)
def slide_06_prompt_definition(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 입력의 질이 출력의 질을 결정한다", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "프롬프트란 무엇인가?", size=40, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "AI와 소통하는 \"언어\" — 목적·상황·제약·형식을 한 번에 전달하는 지시서", size=16, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(2.1), Inches(12), Inches(0.3), "나쁜 프롬프트 vs 좋은 프롬프트 (예시 3가지)", size=16, bold=True, color=T.text)
rows = [
("보고서 써줘", "대상(누가 읽는지), 목적(왜), 형식(목차/분량)을 포함해서\n\"임원 보고용 1페이지 요약\"으로 작성해줘."),
("요약해줘", "\"다음 글을 3줄 요약 + 핵심 키워드 5개\" 형식으로 요약해줘."),
("분석해줘", "\"표로 정리(열: 문제, 원인, 영향, 개선안)\" 하고,\n결론을 먼저 제시한 뒤 근거를 번호로 달아줘."),
]
y = Inches(2.5)
for i, (bad, good) in enumerate(rows):
yy = y + Inches(1.25) * i
add_rect(s, Inches(0.7), yy, Inches(5.9), Inches(1.05), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
add_rect(s, Inches(6.75), yy, Inches(5.88), Inches(1.05), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(0.95), yy + Inches(0.2), Inches(5.4), Inches(0.25), "❌ 나쁜 프롬프트", size=12, bold=True, color=_rgb("#B91C1C"))
add_textbox(s, Inches(7.0), yy + Inches(0.2), Inches(5.4), Inches(0.25), "✅ 좋은 프롬프트", size=12, bold=True, color=_rgb("#15803D"))
add_textbox(s, Inches(0.95), yy + Inches(0.5), Inches(5.4), Inches(0.5), bad, size=18, bold=True, color=_rgb("#7F1D1D"))
add_textbox(s, Inches(7.0), yy + Inches(0.5), Inches(5.4), Inches(0.6), good, size=14, bold=False, color=_rgb("#166534"), line_spacing=1.15)
add_footer(s, 6, dark=False)
def slide_07_language(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "[사례 1] 언어 선택: 한국어 vs 영어", size=34, bold=True, color=T.text)
add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(2.3), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.15), Inches(11.3), Inches(0.3), "왜 영어 입력이 더 정확한 경우가 있는가?", size=18, bold=True, color=T.text)
add_bullets(
s,
Inches(1.0),
Inches(2.55),
Inches(11.3),
Inches(1.4),
["학습 데이터 불균형 (영어 데이터가 압도적으로 많음)", "전문 용어·기술 용어의 영어 표현이 더 풍부", "일부 모델/도구는 영어 지시에서 더 안정적으로 동작"],
size=16,
color=T.text,
)
add_rect(s, Inches(0.7), Inches(4.45), Inches(11.93), Inches(1.35), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(4.62), Inches(5.8), Inches(0.3), "실무 팁", size=14, bold=True, color=T.accent_yellow)
add_textbox(s, Inches(1.0), Inches(4.92), Inches(6.6), Inches(0.7), "영어로 묻고, 한국어로 출력 요청하기\n예) \"Answer in Korean, and format as a table.\"", size=14, bold=True, color=_rgb("#E5E7EB"), line_spacing=1.2)
add_textbox(s, Inches(8.0), Inches(4.75), Inches(4.4), Inches(0.9), "실습\n동일 질문 한/영 비교 결과 시연", size=16, bold=True, color=_rgb("#E5E7EB"), align=PP_ALIGN.CENTER, line_spacing=1.2)
add_footer(s, 7, dark=False)
def slide_08_context(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "[사례 2] 정보의 완전성 — 맥락이 없으면 중의성이 생긴다", size=28, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "핵심 원리: \"목적 + 상황 + 제약 조건\"을 모두 포함하라", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(1.9), fill=T.white, line=T.line, radius=True)
add_rect(s, Inches(0.7), Inches(2.05), Inches(5.8), Inches(1.9), fill=_rgb("#FFF1F2"), line=None, radius=True)
add_rect(s, Inches(6.83), Inches(2.05), Inches(5.8), Inches(1.9), fill=_rgb("#E9FBF1"), line=None, radius=True)
add_textbox(s, Inches(1.05), Inches(2.25), Inches(5.2), Inches(0.3), "❌ 중의적", size=14, bold=True, color=_rgb("#B91C1C"))
add_textbox(s, Inches(7.15), Inches(2.25), Inches(5.2), Inches(0.3), "✅ 명확", size=14, bold=True, color=_rgb("#15803D"))
add_textbox(s, Inches(1.05), Inches(2.65), Inches(5.2), Inches(0.8), "\"세차장에 갑니다. 걸어갈까요?\"", size=22, bold=True, color=_rgb("#7F1D1D"), line_spacing=1.1)
add_textbox(s, Inches(7.15), Inches(2.65), Inches(5.2), Inches(0.8), "\"세차하러 갑니다. 걸어갈까요?\"", size=22, bold=True, color=_rgb("#166534"), line_spacing=1.1)
add_textbox(s, Inches(1.05), Inches(3.35), Inches(5.2), Inches(0.4), "목적이 빠지면 해석이 여러 개로 갈립니다.", size=14, bold=False, color=_rgb("#7F1D1D"))
add_textbox(s, Inches(7.15), Inches(3.35), Inches(5.2), Inches(0.4), "목적을 넣으면 AI도 명확히 답합니다.", size=14, bold=False, color=_rgb("#166534"))
add_rect(s, Inches(0.7), Inches(4.2), Inches(11.93), Inches(1.85), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(4.35), Inches(11.3), Inches(0.3), "실무 적용", size=14, bold=True, color=T.accent_yellow)
add_bullets(
s,
Inches(1.0),
Inches(4.7),
Inches(11.3),
Inches(1.2),
["보고서/기획서 요청 시: \"누가 읽는지\"(대상) + \"목적\" + \"형식(분량/목차)\"을 함께 제공", "제약 조건(기간/데이터 범위/금지사항)을 명시하면 결과가 안정적으로 개선"],
size=15,
color=_rgb("#E5E7EB"),
)
add_footer(s, 8, dark=False)
def slide_09_5w1h(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "5W1H 프롬프트 프레임", size=40, bold=True, color=T.text)
frame = [
("Who", "역할 설정", "예: \"너는 제약업계 10년 경력의 마케터야\""),
("What", "원하는 산출물", "예: \"임원 보고용 1페이지 요약\""),
("Why", "목적·배경", "예: \"AX 과제 선정 회의 자료로 사용할 거야\""),
("When/Where", "상황·컨텍스트", "예: \"지난 분기 데이터 기준, 국내 시장\""),
("How", "출력 형식", "예: \"표(열: 항목, 근거, 리스크) + 결론 먼저\""),
]
y = Inches(2.0)
row_h = Inches(0.95)
for i, (k, t, ex) in enumerate(frame):
yy = y + row_h * i
add_rect(s, Inches(0.7), yy, Inches(11.93), row_h - Inches(0.12), fill=T.white, line=T.line, radius=True)
add_rect(s, Inches(0.7), yy, Inches(1.6), row_h - Inches(0.12), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(0.7), yy + Inches(0.18), Inches(1.6), Inches(0.3), k, size=16, bold=True, color=T.accent_yellow, align=PP_ALIGN.CENTER)
add_textbox(s, Inches(2.45), yy + Inches(0.18), Inches(3.2), Inches(0.3), t, size=18, bold=True, color=T.text)
add_textbox(s, Inches(2.45), yy + Inches(0.5), Inches(9.9), Inches(0.35), ex, size=14, bold=False, color=T.muted)
add_footer(s, 9, dark=False)
def slide_10_format(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "출력 형식을 지정하라", size=40, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "형식을 안 주면 AI가 알아서 결정 → 원하는 형태가 아닐 수 있음", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.05), Inches(5.9), Inches(3.0), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
add_rect(s, Inches(6.75), Inches(2.05), Inches(5.88), Inches(3.0), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(0.95), Inches(2.25), Inches(5.4), Inches(0.3), "Before", size=14, bold=True, color=_rgb("#B91C1C"))
add_textbox(s, Inches(7.0), Inches(2.25), Inches(5.4), Inches(0.3), "After", size=14, bold=True, color=_rgb("#15803D"))
add_textbox(s, Inches(0.95), Inches(2.65), Inches(5.4), Inches(1.0), "\"이 자료 분석해줘\"", size=22, bold=True, color=_rgb("#7F1D1D"))
add_textbox(
s,
Inches(7.0),
Inches(2.65),
Inches(5.4),
Inches(1.4),
"\"표로 만들어줘 (열: 항목명, 장점, 단점)\"\n\"3줄 요약으로\"\n\"결론 먼저, 근거는 번호 순으로\"",
size=16,
bold=True,
color=_rgb("#166534"),
line_spacing=1.2,
)
add_rect(s, Inches(0.7), Inches(5.25), Inches(11.93), Inches(1.1), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(
s,
Inches(1.0),
Inches(5.4),
Inches(11.3),
Inches(0.8),
"체크포인트\n- 형식(표/글머리/단계)\n- 분량(3줄/1페이지)\n- 순서(결론 먼저)\n- 톤(전문/간결/친절)",
size=14,
bold=True,
color=_rgb("#E5E7EB"),
line_spacing=1.15,
)
add_footer(s, 10, dark=False)
def slide_11_role(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 2. 프롬프트 설계 원칙", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "역할 부여(Role Prompting) 기법", size=36, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "\"너는 ○○이야\" 선언의 효과: 관점·깊이·어조를 통제", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.1), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "예시", size=14, bold=True, color=T.muted)
add_rect(s, Inches(1.0), Inches(2.6), Inches(11.3), Inches(1.35), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(
s,
Inches(1.3),
Inches(2.75),
Inches(10.7),
Inches(1.0),
"너는 대웅제약 CFO야.\n다음 데이터를 분석해줘. (목표: 비용 절감 관점, 리스크 포함, 1페이지 요약)",
size=18,
bold=True,
color=_rgb("#E5E7EB"),
line_spacing=1.2,
)
add_rect(s, Inches(0.7), Inches(4.35), Inches(11.93), Inches(2.0), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(1.0), Inches(4.55), Inches(11.3), Inches(0.3), "실습", size=14, bold=True, color=_rgb("#15803D"))
add_bullets(
s,
Inches(1.0),
Inches(4.9),
Inches(11.3),
Inches(1.3),
["동일 데이터를 영업팀장 / 재무팀장 / CEO 역할로 각각 분석", "출력의 관점·강조점·결론이 어떻게 달라지는지 비교"],
size=16,
color=_rgb("#166534"),
)
add_footer(s, 11, dark=False)
def slide_12_steps(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. AI를 더 똑똑하게 쓰는 고급 기법", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "단계적 사고 유도", size=40, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "복잡한 문제일수록 절차(단계)를 나눠서 요청하면 결과가 좋아집니다.", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.0), Inches(11.93), Inches(1.8), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.2), Inches(11.3), Inches(0.3), "좋은 요청 방식", size=14, bold=True, color=T.muted)
add_bullets(
s,
Inches(1.0),
Inches(2.55),
Inches(11.3),
Inches(1.1),
["\"문제를 단계별로 해결 절차로 나눠서 제시해줘\"", "\"각 단계마다 체크리스트를 만들고, 누락된 정보를 질문해줘\"", "\"최종 답변은 마지막에 요약해줘\""],
size=16,
color=T.text,
)
add_rect(s, Inches(0.7), Inches(4.05), Inches(11.93), Inches(2.3), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(4.25), Inches(11.3), Inches(0.3), "예시 (AX 과제 선정 기준 적용)", size=14, bold=True, color=T.accent_yellow)
add_textbox(
s,
Inches(1.0),
Inches(4.55),
Inches(11.3),
Inches(1.6),
"과제 후보 3개를 아래 체크리스트 7개 기준으로 하나씩 평가해줘.\n"
"1) 목표 명확성 2) 데이터 확보 가능성 3) 기대효과(정량/정성)\n"
"4) 구현 난이도 5) 리스크(보안/규정) 6) 확장성 7) 일정 적합성\n"
"출력: 표(열: 기준, 평가, 근거, 리스크) + 결론(우선순위) 먼저",
size=15,
bold=True,
color=_rgb("#E5E7EB"),
line_spacing=1.2,
)
add_footer(s, 12, dark=False)
def slide_13_fewshot(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "예시 제공 (FewShot Prompting)", size=34, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "\"이런 식으로 해줘\" — 예시 1~3개의 위력", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.0), Inches(11.93), Inches(2.25), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.2), Inches(11.3), Inches(0.3), "효과", size=14, bold=True, color=T.muted)
add_bullets(s, Inches(1.0), Inches(2.55), Inches(11.3), Inches(1.5), ["출력 형식, 어조, 수준을 예시로 통제", "모호한 요구를 '정답 샘플'로 명확히 전달", "팀 내 산출물 스타일을 표준화"], size=16, color=T.text)
add_rect(s, Inches(0.7), Inches(4.45), Inches(11.93), Inches(1.9), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(1.0), Inches(4.65), Inches(11.3), Inches(0.3), "[사례 3] 응용", size=14, bold=True, color=_rgb("#15803D"))
add_textbox(
s,
Inches(1.0),
Inches(4.95),
Inches(11.3),
Inches(1.2),
"`20260223_report_10.doc`를 예시로 제공 → 동일 형식의 보고서를 자동 생성\n"
"프롬프트에 \"예시 문서의 목차/톤/표현을 유지\" 조건을 포함",
size=16,
bold=True,
color=_rgb("#166534"),
line_spacing=1.2,
)
add_footer(s, 13, dark=False)
def slide_14_context_window(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "맥락 누적 활용 (Context Window 관리)", size=30, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "대화가 길어질수록 앞 조건을 잊을 수 있으니, 핵심 조건을 관리해야 합니다.", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(1.8), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "실무 습관", size=14, bold=True, color=T.muted)
add_bullets(
s,
Inches(1.0),
Inches(2.6),
Inches(11.3),
Inches(1.2),
["중요한 조건은 대화 앞부분에 배치", "새 대화 시작 시 \"지금까지 정한 것\" 요약을 먼저 붙여넣기", "긴 문서는 분할(Chunk) + 요약 누적 전략 사용"],
size=16,
color=T.text,
)
add_rect(s, Inches(0.7), Inches(4.05), Inches(11.93), Inches(2.3), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(4.25), Inches(11.3), Inches(0.3), "분할 전략 예시", size=14, bold=True, color=T.accent_yellow)
add_textbox(
s,
Inches(1.0),
Inches(4.55),
Inches(11.3),
Inches(1.6),
"1) 문서를 3~5페이지 단위로 나눠 요약 요청\n"
"2) 각 요약을 '핵심 포인트/결정사항/숫자' 위주로 정리\n"
"3) 마지막에 모든 요약을 합쳐 최종 보고서 작성 요청",
size=16,
bold=True,
color=_rgb("#E5E7EB"),
line_spacing=1.2,
)
add_footer(s, 14, dark=False)
def slide_15_iterative(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "반복 정제 (Iterative Refinement)", size=34, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "첫 번째 답이 완벽할 필요는 없습니다. 초안 → 피드백 → 확정", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.0), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "자주 쓰는 후속 프롬프트", size=14, bold=True, color=T.muted)
add_bullets(
s,
Inches(1.0),
Inches(2.6),
Inches(11.3),
Inches(1.3),
["\"더 간결하게\"", "\"3번 항목을 더 구체적으로\"", "\"전문적 어조로 바꿔줘\"", "\"표로 재구성해줘\"", "\"리스크/반론도 함께 제시해줘\""],
size=16,
color=T.text,
)
add_rect(s, Inches(0.7), Inches(4.25), Inches(11.93), Inches(2.1), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(1.0), Inches(4.45), Inches(11.3), Inches(0.3), "실무 비유", size=14, bold=True, color=_rgb("#15803D"))
add_textbox(
s,
Inches(1.0),
Inches(4.75),
Inches(11.3),
Inches(1.4),
"AI는 탁월한 \"초안 작성자\"입니다.\n"
"사람은 검토자(Reviewer)로서 방향을 잡고, 근거·수치·규정을 확인해 완성도를 올립니다.",
size=18,
bold=True,
color=_rgb("#166534"),
line_spacing=1.2,
)
add_footer(s, 15, dark=False)
def slide_16_files(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 3. 고급 기법", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "파일·데이터 연동 활용", size=40, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "CSV, Excel, Word, PDF 등 정형/반정형 데이터를 먹이면 성능이 크게 개선됩니다.", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.35), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "실무 예시", size=14, bold=True, color=T.muted)
add_bullets(
s,
Inches(1.0),
Inches(2.6),
Inches(11.3),
Inches(1.7),
["채용: 지원서(CSV) + 평가 기준(문서) → 자동 평가 코멘트 생성", "과제 선정: 신청 양식 + 프로세스 문서 → 기준별 점수/근거 표 생성", "성과 평가: KPI 테이블 + 코멘트 → 요약 및 이슈 탐지"],
size=16,
color=T.text,
)
add_rect(s, Inches(0.7), Inches(4.6), Inches(11.93), Inches(1.75), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(4.8), Inches(11.3), Inches(0.3), "포인트: 데이터 구조화", size=14, bold=True, color=T.accent_yellow)
add_textbox(
s,
Inches(1.0),
Inches(5.1),
Inches(11.3),
Inches(1.1),
"AI는 정형 데이터(표/필드)를 더 잘 처리합니다.\n"
"입력 데이터에 컬럼명, 단위, 기간, 정의를 명시하면 오류가 크게 줄어듭니다.",
size=16,
bold=True,
color=_rgb("#E5E7EB"),
line_spacing=1.2,
)
add_footer(s, 16, dark=False)
def slide_17_trust(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 실수하지 않는 AI 활용법", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI를 믿어야 할 때 vs 검증해야 할 때", size=28, bold=True, color=T.text)
add_rect(s, Inches(0.7), Inches(1.9), Inches(5.9), Inches(4.45), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_rect(s, Inches(6.75), Inches(1.9), Inches(5.88), Inches(4.45), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
add_textbox(s, Inches(0.95), Inches(2.15), Inches(5.4), Inches(0.35), "믿어도 되는 경우", size=18, bold=True, color=_rgb("#15803D"))
add_textbox(s, Inches(7.0), Inches(2.15), Inches(5.4), Inches(0.35), "반드시 검증", size=18, bold=True, color=_rgb("#B91C1C"))
add_bullets(s, Inches(0.95), Inches(2.6), Inches(5.4), Inches(3.6), ["형식 작업(문장 다듬기, 문서 구성)", "요약, 번역", "초안 작성(메일/보고서)", "코드 생성(단, 테스트/리뷰 필수)"], size=16, color=_rgb("#166534"))
add_bullets(s, Inches(7.0), Inches(2.6), Inches(5.4), Inches(3.6), ["수치·통계", "법률·규정", "최신 정보", "사람 이름/조직명", "의사결정에 영향을 주는 사실"], size=16, color=_rgb("#7F1D1D"))
add_rect(s, Inches(0.7), Inches(6.55), Inches(11.93), Inches(0.65), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(6.68), Inches(11.3), Inches(0.4), "\"AI가 틀렸다\"가 아니라 \"내가 확인하지 않았다\"", size=18, bold=True, color=_rgb("#E5E7EB"), align=PP_ALIGN.CENTER)
add_footer(s, 17, dark=False)
def slide_18_security(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 보안과 개인정보", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "무엇을 넣으면 안 되는가", size=40, bold=True, color=T.text)
add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(2.45), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
add_textbox(s, Inches(1.0), Inches(2.1), Inches(11.3), Inches(0.3), "입력 금지", size=16, bold=True, color=_rgb("#B91C1C"))
add_bullets(s, Inches(1.0), Inches(2.45), Inches(11.3), Inches(1.8), ["사내 기밀 데이터", "개인식별정보(PII): 이름/주민번호/연락처/계좌/주소 등", "고객·환자·직원 데이터 원문", "계약서/특허 등 민감 문서의 원문"], size=16, color=_rgb("#7F1D1D"))
add_rect(s, Inches(0.7), Inches(4.55), Inches(11.93), Inches(1.8), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(1.0), Inches(4.75), Inches(11.3), Inches(0.3), "대안", size=16, bold=True, color=_rgb("#15803D"))
add_bullets(s, Inches(1.0), Inches(5.1), Inches(11.3), Inches(1.1), ["가명화/익명화 후 활용 (ID 치환, 숫자 범위화)", "내부/사내 AI 툴 사용 여부 확인", "필요 최소 정보만 제공 + 출력은 요약 중심"], size=16, color=_rgb("#166534"))
add_footer(s, 18, dark=False)
def slide_19_copyright(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 저작권과 책임", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI 결과물의 저작권과 책임", size=36, bold=True, color=T.text)
add_rect(s, Inches(0.7), Inches(1.9), Inches(11.93), Inches(4.45), fill=T.white, line=T.line, radius=True)
add_bullets(
s,
Inches(1.0),
Inches(2.2),
Inches(11.3),
Inches(3.8),
["AI 생성물의 법적 지위는 국가/시점/정책에 따라 달라질 수 있음", "출처 표기와 사실 확인의 의무는 사용자에게 있음", "최종 결과물에 대한 책임은 항상 사람에게", "사내 가이드라인(대웅그룹 AI 활용 가이드라인)과 연계해 준수"],
size=18,
color=T.text,
)
add_footer(s, 19, dark=False)
def slide_20_skills(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 4. 역량 재정의", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AI 환경에서의 직무 역량 재정의", size=30, bold=True, color=T.text)
add_rect(s, Inches(0.7), Inches(1.9), Inches(5.9), Inches(4.45), fill=_rgb("#FFF1F2"), line=_rgb("#FECACA"), radius=True)
add_rect(s, Inches(6.75), Inches(1.9), Inches(5.88), Inches(4.45), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(0.95), Inches(2.15), Inches(5.4), Inches(0.35), "상대적으로 약해지는 역량", size=16, bold=True, color=_rgb("#B91C1C"))
add_textbox(s, Inches(7.0), Inches(2.15), Inches(5.4), Inches(0.35), "더 중요해지는 역량", size=16, bold=True, color=_rgb("#15803D"))
add_bullets(s, Inches(0.95), Inches(2.55), Inches(5.4), Inches(3.7), ["단순 요약/정리", "반복 문서 작성", "기본 번역", "정형 보고서 초안"], size=16, color=_rgb("#7F1D1D"))
add_bullets(s, Inches(7.0), Inches(2.55), Inches(5.4), Inches(3.7), ["문제 정의와 목표 설정", "좋은 질문(프롬프트) 설계", "검증·리스크 관리", "의사결정과 책임", "업무 프로세스 설계(워크플로우)"], size=16, color=_rgb("#166534"))
add_rect(s, Inches(0.7), Inches(6.55), Inches(11.93), Inches(0.65), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(6.68), Inches(11.3), Inches(0.4), "\"AI에게 좋은 질문을 하는 능력\" = 새로운 핵심 역량", size=18, bold=True, color=_rgb("#E5E7EB"), align=PP_ALIGN.CENTER)
add_footer(s, 20, dark=False)
def slide_21_scenarios(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 5. 실전 적용 — 대웅 AX 과제와 연결", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "부서별 AI 활용 시나리오 맵", size=40, bold=True, color=T.text)
cards = [
("영업", ["채권 현황 조회", "인사이트 자동 생성"], T.accent_blue),
("마케팅", ["대시보드 결산 자동 작성", "기사/콘텐츠 초안 생성"], T.accent_yellow),
("재무/회계", ["지출 증빙 검토 자동화", "이상 지출 탐지"], T.accent_green),
("연구개발", ["특허·논문 요약", "보고서 초안"], _rgb("#A855F7")),
("HR", ["면접 분석", "교육 콘텐츠 생성"], T.accent_red),
]
x0 = Inches(0.7)
y0 = Inches(2.0)
w = Inches(3.82)
h = Inches(1.75)
g = Inches(0.35)
positions = [
(x0, y0),
(x0 + w + g, y0),
(x0 + (w + g) * 2, y0),
(x0 + w / 2 + g / 2, y0 + h + g),
(x0 + (w + g) * 1.5, y0 + h + g),
]
for (title, lines, accent), (xx, yy) in zip(cards, positions, strict=True):
add_rect(s, xx, yy, w, h, fill=T.white, line=T.line, radius=True)
add_rect(s, xx, yy, w, Inches(0.08), fill=accent, line=None)
add_textbox(s, xx + Inches(0.25), yy + Inches(0.35), w - Inches(0.5), Inches(0.3), title, size=18, bold=True, color=T.text)
add_bullets(s, xx + Inches(0.25), yy + Inches(0.75), w - Inches(0.5), Inches(0.9), lines, size=14, color=T.muted)
add_footer(s, 21, dark=False)
def slide_22_ax_application(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 5. 실전 적용", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "AX 과제 신청 단계에서의 AI 활용", size=32, bold=True, color=T.text)
add_textbox(s, Inches(0.7), Inches(1.55), Inches(12), Inches(0.35), "신청서 작성 → 자기검토 → 평가 기준 정렬까지 한 번에", size=16, bold=True, color=T.muted)
add_rect(s, Inches(0.7), Inches(2.05), Inches(11.93), Inches(2.25), fill=T.white, line=T.line, radius=True)
add_textbox(s, Inches(1.0), Inches(2.25), Inches(11.3), Inches(0.3), "활용 포인트", size=14, bold=True, color=T.muted)
add_bullets(
s,
Inches(1.0),
Inches(2.6),
Inches(11.3),
Inches(1.6),
["신청서 작성 시 AI 도움받기: AsIs → ToBe 구조화", "과제 평가 기준에 맞는 자기검토(누락 항목 질문하도록)", "정량 효과/리스크(보안·규정)까지 포함해 완성도 향상"],
size=16,
color=T.text,
)
add_rect(s, Inches(0.7), Inches(4.55), Inches(11.93), Inches(1.8), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(1.0), Inches(4.75), Inches(11.3), Inches(0.3), "데모 데이터", size=14, bold=True, color=T.accent_yellow)
add_textbox(
s,
Inches(1.0),
Inches(5.05),
Inches(11.3),
Inches(1.2),
"`20260223.csv` + `AX추진프로세스.docx` → 자동 평가 보고서 생성 시연",
size=18,
bold=True,
color=_rgb("#E5E7EB"),
line_spacing=1.2,
)
add_footer(s, 22, dark=False)
def slide_23_routine(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.bg)
add_textbox(s, Inches(0.7), Inches(0.55), Inches(12), Inches(0.3), "PART 5. 실전 적용", size=14, bold=True, color=T.muted)
add_textbox(s, Inches(0.7), Inches(0.9), Inches(12), Inches(0.7), "나만의 AI 활용 루틴 만들기", size=40, bold=True, color=T.text)
cards = [
("Daily", "AI 초안 작성 → 내가 검토·수정", T.accent_blue),
("Weekly", "반복 업무 프롬프트 템플릿화", T.accent_green),
("Monthly", "AI 활용 성과 측정 (시간 절감, 품질)", T.accent_yellow),
]
x = Inches(0.7)
y = Inches(2.05)
w = Inches(3.82)
h = Inches(2.0)
g = Inches(0.35)
for i, (t, d, a) in enumerate(cards):
xx = x + (w + g) * i
add_rect(s, xx, y, w, h, fill=T.white, line=T.line, radius=True)
add_rect(s, xx, y, w, Inches(0.08), fill=a, line=None)
add_textbox(s, xx + Inches(0.25), y + Inches(0.45), w - Inches(0.5), Inches(0.3), t, size=18, bold=True, color=T.text)
add_textbox(s, xx + Inches(0.25), y + Inches(0.85), w - Inches(0.5), Inches(0.9), d, size=16, bold=True, color=T.muted, line_spacing=1.2)
add_rect(s, Inches(0.7), Inches(4.35), Inches(11.93), Inches(2.0), fill=_rgb("#E9FBF1"), line=_rgb("#BBF7D0"), radius=True)
add_textbox(s, Inches(1.0), Inches(4.55), Inches(11.3), Inches(0.3), "권장", size=14, bold=True, color=_rgb("#15803D"))
add_textbox(s, Inches(1.0), Inches(4.85), Inches(11.3), Inches(1.2), "프롬프트 라이브러리를 구축하세요.\n(업무별 템플릿 + 예시 + 검증 체크리스트)", size=20, bold=True, color=_rgb("#166534"), line_spacing=1.2)
add_footer(s, 23, dark=False)
def slide_24_closing(prs: Presentation) -> None:
s = prs.slides.add_slide(prs.slide_layouts[6])
set_slide_bg(s, T.navy)
add_textbox(s, Inches(0.7), Inches(0.7), Inches(12), Inches(0.4), "PART 5. 마무리", size=14, bold=True, color=_rgb("#D1D5DB"))
add_textbox(s, Inches(0.7), Inches(1.1), Inches(12), Inches(0.9), "AI와 함께 일하는 미래", size=46, bold=True, color=T.white)
add_rect(s, Inches(0.7), Inches(2.15), Inches(11.93), Inches(0.05), fill=T.accent_yellow, line=None)
add_textbox(s, Inches(0.7), Inches(2.35), Inches(12), Inches(0.6), "AI는 대체자가 아닌 증폭기(Amplifier)", size=28, bold=True, color=T.accent_yellow)
add_bullets(
s,
Inches(0.9),
Inches(3.2),
Inches(12),
Inches(2.0),
["잘 쓰는 사람과 못 쓰는 사람의 격차는 계속 벌어진다", "지금 시작하는 것이 가장 빠른 것", "핵심은: 목적·맥락·제약·형식 + 검증"],
size=20,
color=_rgb("#E5E7EB"),
)
add_rect(s, Inches(0.7), Inches(5.7), Inches(11.93), Inches(0.9), fill=_rgb("#24364D"), line=None, radius=True)
add_textbox(s, Inches(0.7), Inches(5.9), Inches(11.93), Inches(0.5), "Q&A / 다음 학습 자원 안내", size=26, bold=True, color=T.white, align=PP_ALIGN.CENTER)
add_footer(s, 24, dark=True)
def build_ppt() -> Presentation:
prs = Presentation()
prs.slide_width = SLIDE_W
prs.slide_height = SLIDE_H
# Slides 1-5 (re-created as editable)
slide_01_cover(prs)
slide_02_core_assumptions(prs)
slide_03_llm(prs)
slide_04_good_vs_bad(prs)
slide_05_hallucination(prs)
# Slides 6-24 per outline
slide_06_prompt_definition(prs)
slide_07_language(prs)
slide_08_context(prs)
slide_09_5w1h(prs)
slide_10_format(prs)
slide_11_role(prs)
slide_12_steps(prs)
slide_13_fewshot(prs)
slide_14_context_window(prs)
slide_15_iterative(prs)
slide_16_files(prs)
slide_17_trust(prs)
slide_18_security(prs)
slide_19_copyright(prs)
slide_20_skills(prs)
slide_21_scenarios(prs)
slide_22_ax_application(prs)
slide_23_routine(prs)
slide_24_closing(prs)
return prs
def validate(prs: Presentation) -> None:
if len(prs.slides) != 24:
raise ValueError(f"expected 24 slides, got {len(prs.slides)}")
# Ensure no full-slide raster images are used (editable requirement)
from pptx.enum.shapes import MSO_SHAPE_TYPE
pics = 0
for slide in prs.slides:
for sh in slide.shapes:
if sh.shape_type == MSO_SHAPE_TYPE.PICTURE:
pics += 1
if pics != 0:
raise ValueError(f"expected 0 picture shapes, got {pics}")
def main() -> None:
base_dir = Path(__file__).resolve().parent
out = base_dir / "outputs" / "ai_work.pptx"
out.parent.mkdir(parents=True, exist_ok=True)
prs = build_ppt()
validate(prs)
prs.save(str(out))
print(f"wrote {out} ({out.stat().st_size:,} bytes)")
if __name__ == "__main__":
main()