<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:media="http://search.yahoo.com/mrss/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>program &#8211; 투데이즈.kr</title>
	<atom:link href="https://2days.kr/category/it/program/feed/" rel="self" type="application/rss+xml" />
	<link>https://2days.kr</link>
	<description>투데이즈</description>
	<lastBuildDate>Sun, 16 Nov 2025 13:07:04 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8</generator>

<image>
	<url>https://2days.kr/wp-content/uploads/2025/10/cropped-simbol-1-32x32.png</url>
	<title>program &#8211; 투데이즈.kr</title>
	<link>https://2days.kr</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>X 게시물을 내 노션에 스크랩하는 코드</title>
		<link>https://2days.kr/10/11/09/69832/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Mon, 10 Nov 2025 00:55:42 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=69832</guid>

					<description><![CDATA[X.com에 노션 스크랩하는 코드를 올려 놓습니다 X 게시물을 내 노션에 스크랩하는 코드 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ X(Twitter) → Notion 자동 파이프라인 (macOS, 최종판) - 창 열림 + 로그인 대기(콘솔 Enter) 후 수집 시작 - macOS Chrome 프로필 자동 감지 + 잠금 시 임시 프로필 복제(B 방안) - webdriver_manager의 THIRD_PARTY_NOTICES.chromedriver 경로 보정 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>X.com에 노션 스크랩하는 코드를 올려 놓습니다</p>
<h2><strong>X 게시물을 내 노션에 스크랩하는 코드</strong></h2>
<figure id="attachment_69834" aria-describedby="caption-attachment-69834" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-69834 size-large" fifu-data-src="https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1" alt="X 게시물을 내 노션에 스크랩하는 코드" width="696" height="696" loading="lazy" title="X 게시물을 내 노션에 스크랩하는 코드 1"><figcaption id="caption-attachment-69834" class="wp-caption-text">X 게시물을 내 노션에 스크랩하는 코드</figcaption></figure>
<div>
<pre>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
X(Twitter) → Notion 자동 파이프라인 (macOS, 최종판)
- 창 열림 + 로그인 대기(콘솔 Enter) 후 수집 시작
- macOS Chrome 프로필 자동 감지 + 잠금 시 임시 프로필 복제(B 방안)
- webdriver_manager의 THIRD_PARTY_NOTICES.chromedriver 경로 보정
- 무한 스크롤로 TARGET_COUNT 까지 수집
- 이미지/동영상 다운로드 → 5MiB 이하 자동 압축 → Notion 업로드(새 File Upload API)
- DB 스키마 유연 적응: Title 자동 탐색, 기타 속성은 있으면 매핑/없으면 생략
- Media(files) 없으면 생성 시도 → 실패 시 file 블록(children)로 첨부
- 중복 방지: 페이지 재활용, 동일 파일명 재업로드 방지
- 업로드 성공 파일은 즉시 로컬 삭제
"""

import os, re, csv, time, stat, json, logging, io, subprocess, shutil, tempfile
from pathlib import Path
from typing import Dict, Any, List, Optional, Tuple

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from urllib.parse import urlparse, parse_qsl, urlencode, urlunparse

from PIL import Image

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.common.exceptions import SessionNotCreatedException, WebDriverException
from webdriver_manager.chrome import ChromeDriverManager
import yt_dlp

# ===================== 설정 =====================
ACCOUNT       = "<span style="color: #ff0000;">수집대상"</span>      # 수집 대상 X 계정
TARGET_COUNT  = 8000                  # 원하는 수집 개수
MAX_SCROLL    = 100000                 # 최대 스크롤 시도
SCROLL_PAUSE  = 7.5                  # 스크롤 간 대기(안정성)
HEADLESS      = False                # 창 열림 권장(True면 로그인 대기 비활성)
WAIT_FOR_LOGIN= True                 # 창 뜬 뒤 로그인하고 콘솔 Enter로 시작

OUT_DIR       = Path("./NatureIsAmazing_v3")

# Notion (개인용, 하드코딩 요청 반영)
NOTION_API_KEY         = "<span style="color: #ff0000;">노션API</span>"
NOTION_DATABASE_ID_RAW = "<span style="color: #ff0000;">노션DP</span>"  # 하이픈 없어도 허용
NOTION_VERSION         = "2022-06-28"

# 선택: X 로그인 쿠키(Netscape 형식, yt-dlp용)
COOKIES_FILE = ""  # 예) "/Users/<span style="color: #ff0000;">아이디(영문이름)/</span>cookies_twitter.txt"

UA = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/537.36 "
      "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")

MAX_UPLOAD_BYTES = 5 * 1024 * 1024  # 5 MiB

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s | %(levelname)s | %(message)s",
                    datefmt="%H:%M:%S")

# ===================== 공통 유틸 =====================
def ensure_executable(path: str):
    if not os.access(path, os.X_OK):
        os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
                       stat.S_IRGRP | stat.S_IXGRP |
                       stat.S_IROTH | stat.S_IXOTH)

def build_http_session() -&gt; requests.Session:
    s = requests.Session()
    retries = Retry(total=5, connect=5, read=5, backoff_factor=0.6,
                    status_forcelist=(429,500,502,503,504),
                    allowed_methods=["GET","HEAD","OPTIONS"])
    s.headers.update({"User-Agent": UA, "Accept": "*/*"})
    s.mount("http://", HTTPAdapter(max_retries=retries))
    s.mount("https://", HTTPAdapter(max_retries=retries))
    return s

def normalize_x_url(u: str) -&gt; str:
    return u.replace("x.com", "twitter.com")

def force_orig(url: str) -&gt; str:
    if "twimg.com/media" not in url:
        return url
    parts = list(urlparse(url))
    qs = dict(parse_qsl(parts[4]))
    qs["name"] = "orig"
    parts[4] = urlencode(qs)
    return urlunparse(parts)

def hyphenate_uuid(s: str) -&gt; str:
    s = re.sub(r"[^0-9a-fA-F]", "", s)
    return f"{s[0:8]}-{s[8:12]}-{s[12:16]}-{s[16:20]}-{s[20:32]}" if len(s)==32 else s

NOTION_DATABASE_ID = hyphenate_uuid(NOTION_DATABASE_ID_RAW)

# ===================== macOS Chrome 프로필 감지/복제 =====================
def _profile_locked(profile_path: Path) -&gt; bool:
    for name in ("SingletonLock","SingletonCookie","SingletonSocket"):
        if (profile_path / name).exists():
            return True
    return False

def _make_ephemeral_profile(base_dir: Path, profile_dir: str) -&gt; Tuple[str,str]:
    """
    원본 프로필에서 핵심 데이터만 복사하여 임시 user-data-dir 생성.
    큰 캐시류는 제외해 충돌 최소화.
    """
    src = base_dir / profile_dir
    tmp_root = Path(tempfile.mkdtemp(prefix="chrome-epi-"))
    dst = tmp_root / "Default"
    dst.mkdir(parents=True, exist_ok=True)

    whitelist = [
        "Cookies","Cookies-journal","Network","Preferences","Secure Preferences",
        "Local Storage","History","Favicons","Visited Links","Bookmarks","Session Storage"
    ]
    blacklist = {"Cache","Code Cache","GPUCache","Service Worker","ShaderCache","GrShaderCache"}

    def _copy_entry(name: str):
        s = src / name
        d = dst / name
        if not s.exists(): return
        if s.is_dir():
            if name in blacklist: return
            shutil.copytree(s, d, dirs_exist_ok=True)
        else:
            try: shutil.copy2(s, d)
            except Exception: pass

    for entry in whitelist: _copy_entry(entry)
    for name in os.listdir(src):
        if name in whitelist or name in blacklist: continue
        sp = src / name
        dp = dst / name
        try:
            if sp.is_file() and sp.stat().st_size &lt;= 5*1024*1024:
                shutil.copy2(sp, dp)
        except Exception:
            pass

    return str(tmp_root), "Default"

def find_chrome_profile_on_macos() -&gt; Tuple[Optional[str], Optional[str]]:
    home = Path.home()
    base = home / "Library" / "Application Support" / "Google" / "Chrome"
    local_state = base / "Local State"
    try:
        if local_state.is_file():
            data = json.loads(local_state.read_text(encoding="utf-8"))
            last_used = data.get("profile", {}).get("last_used")
            if last_used and (base / last_used).is_dir():
                return str(base), last_used
    except Exception:
        pass
    for name in ["Default"]+[f"Profile {i}" for i in range(1,12)]:
        if (base / name).is_dir():
            return str(base), name
    return None, None

# ===================== 압축기 =====================
def compress_image_to_limit(src: Path, dst: Path, max_bytes: int = MAX_UPLOAD_BYTES) -&gt; bool:
    try:
        img = Image.open(src).convert("RGB")
    except Exception as e:
        logging.error(f"이미지 열기 실패: {src} -&gt; {e}")
        return False

    def resize(img, max_side):
        w, h = img.size
        if max(w,h) &lt;= max_side: return img
        ratio = max_side / max(w,h)
        return img.resize((int(w*ratio), int(h*ratio)), Image.LANCZOS)

    for ms in [1600, 1400, 1200, 1000, 800, 640, 560, 480]:
        test = resize(img, ms)
        for q in [85,80,72,65,57,50,42,35,30,25]:
            buf = io.BytesIO()
            test.save(buf, format="JPEG", quality=q, optimize=True, progressive=True)
            data = buf.getvalue()
            if len(data) &lt;= max_bytes:
                dst.write_bytes(data); return True
    buf = io.BytesIO()
    resize(img, 432).save(buf, format="JPEG", quality=24, optimize=True, progressive=True)
    dst.write_bytes(buf.getvalue())
    return dst.stat().st_size &lt;= max_bytes

def _run_ffmpeg(args: List[str]) -&gt; bool:
    try:
        res = subprocess.run(args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
        return res.returncode == 0
    except Exception:
        return False

def compress_video_to_limit(src: Path, dst: Path, max_bytes: int = MAX_UPLOAD_BYTES) -&gt; bool:
    steps = [
        ("scale='min(720,iw)':-2", 28, 64),
        ("scale='min(640,iw)':-2", 30, 56),
        ("scale='min(540,iw)':-2", 32, 48),
        ("scale='min(480,iw)':-2", 35, 40),
    ]
    for vf, crf, a_kbps in steps:
        args = ["ffmpeg","-y","-i",str(src),
                "-vf",vf,"-c:v","libx264","-preset","veryfast","-crf",str(crf),
                "-c:a","aac","-b:a",f"{a_kbps}k","-movflags","+faststart",
                "-fs",str(max_bytes-1024), str(dst)]
        if _run_ffmpeg(args) and dst.exists() and dst.stat().st_size &lt;= max_bytes:
            return True
    args = ["ffmpeg","-y","-i",str(src),
            "-vf","scale='min(432,iw)':-2","-c:v","libx264","-preset","veryfast","-crf","38",
            "-c:a","aac","-b:a","40k","-movflags","+faststart","-fs",str(max_bytes-1024), str(dst)]
    return _run_ffmpeg(args) and dst.exists() and dst.stat().st_size &lt;= max_bytes

# ===================== Selenium / Driver (안정화 리트라이) =====================
def _system_chrome_binary() -&gt; Optional[str]:
    candidates = [
        "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
        str(Path.home() / "Applications/Google Chrome.app/Contents/MacOS/Google Chrome"),
    ]
    for c in candidates:
        if os.path.exists(c):
            return c
    return None

def _resolve_chromedriver_path(raw_path: str) -&gt; str:
    path = raw_path
    if os.path.basename(path) == "THIRD_PARTY_NOTICES.chromedriver":
        d = os.path.dirname(path)
        for f in os.listdir(d):
            p = os.path.join(d, f)
            if f.startswith("chromedriver") and os.path.isfile(p):
                path = p; break
    if not os.path.isfile(path) or not os.access(path, os.X_OK):
        d = os.path.dirname(path)
        for f in os.listdir(d):
            p = os.path.join(d, f)
            if f.startswith("chromedriver") and os.path.isfile(p) and os.access(p, os.X_OK):
                path = p; break
    ensure_executable(path)
    return path

def _base_options(headless: bool) -&gt; Options:
    opts = Options()
    # 공통 옵션
    opts.add_argument("--no-sandbox")
    opts.add_argument("--disable-dev-shm-usage")
    opts.add_argument("--disable-gpu")
    opts.add_argument("--window-size=1280,2400")
    opts.add_argument("--disable-notifications")
    opts.add_argument("--disable-extensions")
    opts.add_argument("--mute-audio")
    opts.add_argument("--log-level=3")
    opts.add_argument(f"--user-agent={UA}")
    if headless:
        opts.add_argument("--headless=new")
        opts.add_argument("--disable-software-rasterizer")
        opts.add_argument("--disable-features=VizDisplayCompositor")
    # 시스템 Chrome 바이너리 지정
    sys_bin = _system_chrome_binary()
    if sys_bin:
        opts.binary_location = sys_bin
        logging.info(f"Using system Chrome binary: {sys_bin}")
    else:
        logging.warning("System Chrome binary not found. Relying on default.")
    return opts

def _start_driver_with(opts: Options) -&gt; webdriver.Chrome:
    raw = ChromeDriverManager().install()
    path = _resolve_chromedriver_path(raw)
    return webdriver.Chrome(service=Service(path), options=opts)

def setup_driver(headless: bool = False):
    """
    부팅 전략(순차 재시도):
    1) 시스템 프로필 사용
    2) 시스템 프로필 잠금/충돌 → 임시 복제 프로필 사용
    3) 프로필 없이 기본 실행
    4) headless 최소 옵션
    """
    # 1) 시스템 프로필 시도
    base, prof = find_chrome_profile_on_macos()
    if base and prof:
        profile_path = Path(base) / prof
        opts = _base_options(headless=headless)
        if _profile_locked(profile_path):
            logging.info("Profile locked → try ephemeral clone")
        else:
            opts.add_argument(f"--user-data-dir={base}")
            opts.add_argument(f"--profile-directory={prof}")
            try:
                logging.info(f"Launching Chrome with profile: {prof}")
                return _start_driver_with(opts)
            except (SessionNotCreatedException, WebDriverException) as e:
                logging.warning(f"Profile launch failed: {e}")

        # 2) 임시 복제 프로필
        try:
            epi_dir, epi_prof = _make_ephemeral_profile(Path(base), prof)
            opts = _base_options(headless=headless)
            opts.add_argument(f"--user-data-dir={epi_dir}")
            opts.add_argument(f"--profile-directory={epi_prof}")
            logging.info("Launching Chrome with ephemeral profile")
            return _start_driver_with(opts)
        except (SessionNotCreatedException, WebDriverException) as e:
            logging.warning(f"Ephemeral profile launch failed: {e}")

    # 3) 프로필 없이
    try:
        opts = _base_options(headless=headless)
        logging.info("Launching Chrome without user profile")
        return _start_driver_with(opts)
    except (SessionNotCreatedException, WebDriverException) as e:
        logging.warning(f"No-profile launch failed: {e}")

    # 4) 최후: headless 최소 옵션
    try:
        opts = _base_options(headless=True)
        logging.info("Launching Chrome headless (fallback)")
        return _start_driver_with(opts)
    except Exception as e:
        logging.error(f"All launch strategies failed: {e}")
        raise

# ===================== 로그인 대기 =====================
def wait_for_login_and_keypress(driver, account: str) -&gt; bool:
    try:
        # 대상 프로필 페이지로 포커스
        target = f"https://x.com/{account}"
        if "x.com" not in driver.current_url and "twitter.com" not in driver.current_url:
            driver.get(target)
            time.sleep(2)

        print("\n==============================================")
        print(" 로그인 후 계속 진행 안내")
        print("----------------------------------------------")
        print(" 1) 열린 Chrome 창에서 X(Twitter)에 로그인하세요.")
        print(" 2) 프로필/타임라인이 정상 로드되는지 확인하세요.")
        print(" 3) 여기 콘솔에서 Enter를 누르면 스크랩을 시작합니다.")
        print("    (s 입력 후 Enter: 즉시 시작)")
        print("==============================================\n")
        _ = input("로그인 완료 후 Enter(또는 s 입력 후 Enter)를 눌러 계속: ").strip().lower()
        return True
    except Exception as e:
        logging.warning(f"로그인 대기 중 경고: {e}")
        return True

# ===================== 스크랩 =====================
def download_file(session: requests.Session, url: str, dest: Path) -&gt; bool:
    try:
        tmp = dest.with_suffix(dest.suffix + ".part")
        with session.get(url, stream=True, timeout=30) as r:
            r.raise_for_status()
            with open(tmp, "wb") as f:
                for chunk in r.iter_content(8192):
                    if chunk: f.write(chunk)
        os.replace(tmp, dest)
        return True
    except Exception as e:
        logging.warning(f"이미지 다운로드 실패: {url} -&gt; {e}")
        return False

def find_video_links(card) -&gt; Optional[str]:
    links = [a.get_attribute("href") for a in card.find_elements(By.TAG_NAME, "a")]
    for l in links:
        if l and ("/video/" in l or "/i/status/" in l or "/status/" in l):
            return l
    return None

def download_video(tweet_url: str, dest: Path) -&gt; bool:
    try:
        url = normalize_x_url(tweet_url)
        ydl_opts = {
            "quiet": True,
            "no_warnings": True,
            "format": "bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]/bv*+ba/b",
            "merge_output_format": "mp4",
            "outtmpl": str(dest),
            "retries": 5,
            "fragment_retries": 10,
            "socket_timeout": 20,
            "user_agent": UA,
            "geo_bypass": True,
            "concurrent_fragment_downloads": 3,
        }
        if COOKIES_FILE and Path(COOKIES_FILE).exists():
            ydl_opts["cookiefile"] = COOKIES_FILE
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])
        return True
    except Exception as e:
        logging.warning(f"영상 다운로드 실패: {url} -&gt; {e}")
        return False

def scrape(account: str, out_dir: Path, max_scroll: int, scroll_pause: float,
           headless: bool, target_count: int = 100) -&gt; Dict[str, Any]:
    out_dir.mkdir(exist_ok=True)
    media_dir = out_dir / "media"; media_dir.mkdir(exist_ok=True)
    csv_path = out_dir / "tweets.csv"

    driver = setup_driver(headless=headless)
    driver.get(f"https://x.com/{account}")
    time.sleep(5)

    # 로그인 대기
    if WAIT_FOR_LOGIN and not headless:
        if not wait_for_login_and_keypress(driver, account):
            logging.error("로그인 대기 실패"); driver.quit()
            return {"tweets": {}, "csv": csv_path, "media_dir": media_dir, "account": account}

    tweets: Dict[str, Dict[str, Any]] = {}
    last_height = driver.execute_script("return document.body.scrollHeight")
    stalls, stall_limit = 0, 12
    session = build_http_session()

    logging.info(f"@{account} 수집 시작… (목표 {target_count}개)")
    for _ in range(max_scroll):
        cards = driver.find_elements(By.XPATH, "//article[@data-testid='tweet']")
        new_count = 0
        for c in cards:
            try:
                link = c.find_element(By.XPATH, ".//a[contains(@href,'status')]")
                tid = link.get_attribute("href").split("/")[-1]
                if not tid or not tid.isdigit() or tid in tweets:
                    continue
                text = c.text.replace("\n", " ")
                imgs = [force_orig(i.get_attribute("src")) for i in c.find_elements(By.XPATH, ".//img[contains(@src,'twimg.com/media')]")]
                vids = [v.get_attribute("src") for v in c.find_elements(By.XPATH, ".//video") if v.get_attribute("src")]
                orig_video = find_video_links(c)
                tweets[tid] = {"id": tid, "text": text, "images": imgs, "videos": vids, "orig_video": orig_video}
                new_count += 1
            except Exception:
                pass

        if len(tweets) &gt;= target_count:
            logging.info(f"목표 {target_count}개 달성, 스크랩 종료"); break

        # 스크롤 지그재그
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(scroll_pause)
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight*0.85);")
        time.sleep(scroll_pause)

        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height and new_count == 0:
            stalls += 1
            if stalls &gt;= stall_limit:
                logging.info("더 이상 컨텐츠 로드 없음 → 종료"); break
        else:
            stalls = 0
        last_height = new_height

    driver.quit()
    logging.info(f"트윗 {len(tweets)}개 수집 완료")

    # CSV
    with open(csv_path, "w", newline="", encoding="utf-8") as f:
        w = csv.writer(f)
        w.writerow(["id", "text", "image_count", "video_count", "orig_video"])
        for t in tweets.values():
            w.writerow([t["id"], t["text"], len(t["images"]), len(t["videos"]), t["orig_video"]])
    logging.info(f"CSV 저장: {csv_path}")

    # 미디어 다운로드
    logging.info("미디어 다운로드…")
    for tid, t in tweets.items():
        tweet_url = normalize_x_url(t.get("orig_video") or f"https://x.com/{account}/status/{tid}")
        for idx, m in enumerate(t["images"], 1):
            dest = media_dir / f"{tid}_img{idx}.jpg"
            if not dest.exists():
                download_file(session, m, dest)
        if bool(t.get("videos")) or bool(t.get("orig_video")):
            dest = media_dir / f"{tid}_video.mp4"
            if not dest.exists():
                download_video(tweet_url, dest)

    logging.info(f"미디어 저장 완료: {media_dir}")
    return {"tweets": tweets, "csv": csv_path, "media_dir": media_dir, "account": account}

# ===================== Notion (유연 매핑) =====================
def notion_headers() -&gt; Dict[str, str]:
    h = {"Authorization": f"Bearer {NOTION_API_KEY}",
         "Content-Type": "application/json"}
    if NOTION_VERSION: h["Notion-Version"] = NOTION_VERSION
    return h

def notion_get_db() -&gt; Dict[str, Any]:
    r = requests.get(f"https://api.notion.com/v1/databases/{NOTION_DATABASE_ID}",
                     headers=notion_headers(), timeout=30)
    r.raise_for_status(); return r.json()

def find_title_prop(db: Dict[str, Any]) -&gt; str:
    for name, meta in db.get("properties", {}).items():
        if meta.get("type") == "title": return name
    raise RuntimeError("이 DB에는 Title 속성이 없습니다. (제목 속성 1개 필요)")

def map_optional_props(db: Dict[str, Any]) -&gt; Dict[str, Optional[str]]:
    props = db.get("properties", {})
    def norm(s): return re.sub(r"[\s_]+","",s.lower())
    candidates = {
        "text": ["text","tweettext","본문","내용"],
        "image_count": ["imagecount","images","imgcount","이미지개수","이미지수"],
        "video_count": ["videocount","videos","vidcount","동영상개수","비디오개수"],
        "tweet_url": ["tweeturl","url","링크","원문","원본url"],
        "media": ["media","files","attachments","첨부","파일"],
    }
    found = {"text":None,"image_count":None,"video_count":None,"tweet_url":None,"media":None}
    for name, meta in props.items():
        t = meta.get("type"); n = norm(name)
        if t=="rich_text" and found["text"] is None and (n in candidates["text"]): found["text"]=name
        if t=="number"    and found["image_count"] is None and (n in candidates["image_count"]): found["image_count"]=name
        if t=="number"    and found["video_count"] is None and (n in candidates["video_count"]): found["video_count"]=name
        if t=="url"       and found["tweet_url"] is None and (n in candidates["tweet_url"]): found["tweet_url"]=name
        if t=="files"     and found["media"] is None and (n in candidates["media"]): found["media"]=name
    # 타입 기반 폴백
    if not found["text"]:
        for n,m in props.items():
            if m.get("type")=="rich_text": found["text"]=n; break
    if not found["tweet_url"]:
        for n,m in props.items():
            if m.get("type")=="url": found["tweet_url"]=n; break
    if not found["media"]:
        for n,m in props.items():
            if m.get("type")=="files": found["media"]=n; break
    if not found["image_count"]:
        for n,m in props.items():
            if m.get("type")=="number": found["image_count"]=n; break
    if not found["video_count"]:
        for n,m in props.items():
            if m.get("type")=="number" and n!=found["image_count"]: found["video_count"]=n; break
    return found

def ensure_media_property(db: Dict[str, Any]) -&gt; Optional[str]:
    for name, meta in db.get("properties", {}).items():
        if meta.get("type")=="files": return name
    patch = {"properties":{"Media":{"name":"Media","type":"files","files":{}}}}
    r = requests.patch(f"https://api.notion.com/v1/databases/{NOTION_DATABASE_ID}",
                       headers=notion_headers(), json=patch, timeout=30)
    if r.status_code in (200,202): return "Media"
    logging.warning(f"DB files 속성 생성 실패: {r.status_code} {r.text}")
    return None

def notion_query_by_title(title_prop: str, value: str) -&gt; Optional[str]:
    payload = {"filter":{"property":title_prop,"title":{"equals":value}},"page_size":1}
    r = requests.post(f"https://api.notion.com/v1/databases/{NOTION_DATABASE_ID}/query",
                      headers=notion_headers(), json=payload, timeout=30)
    r.raise_for_status(); res = r.json().get("results", [])
    return res[0]["id"] if res else None

def notion_create_page(row: Dict[str, Any], title_prop: str, opt: Dict[str, Optional[str]]) -&gt; str:
    props: Dict[str, Any] = {title_prop: {"title":[{"text":{"content":row["id"]}}]}}
    if opt["text"]:
        txt = (row.get("text") or "")[:2000]
        props[opt["text"]] = {"rich_text":[{"text":{"content":txt}}]} if txt else {"rich_text":[]}
    if opt["image_count"]:
        props[opt["image_count"]] = {"number": len(row.get("images", []))}
    if opt["video_count"]:
        props[opt["video_count"]] = {"number": len(row.get("videos", []))}
    if opt["tweet_url"]:
        props[opt["tweet_url"]] = {"url": row["tweet_url"]}

    payload = {"parent":{"database_id":NOTION_DATABASE_ID},
               "properties": props,
               "children":[{"object":"block","type":"bookmark","bookmark":{"url":row["tweet_url"]}}]}
    r = requests.post("https://api.notion.com/v1/pages", headers=notion_headers(), json=payload, timeout=30)
    if r.status_code &gt;= 400:
        logging.error(f"페이지 생성 실패: {r.status_code} {r.text}\nPayload: {payload}")
    r.raise_for_status()
    return r.json()["id"]

def notion_get_page_media_names(page_id: str, media_prop: Optional[str]) -&gt; List[str]:
    if not media_prop: return []
    r = requests.get(f"https://api.notion.com/v1/pages/{page_id}", headers=notion_headers(), timeout=30)
    r.raise_for_status()
    items = r.json().get("properties", {}).get(media_prop, {}).get("files", [])
    return [i.get("name") for i in items if i.get("name")]

# --- File Upload API ---
def mime_from_suffix(p: Path) -&gt; str:
    ext = p.suffix.lower()
    if ext in [".jpg",".jpeg"]: return "image/jpeg"
    if ext == ".png": return "image/png"
    if ext == ".gif": return "image/gif"
    if ext == ".mp4": return "video/mp4"
    return "application/octet-stream"

def notion_create_file_upload(name: str, mime: str) -&gt; Dict[str, Any]:
    r = requests.post("https://api.notion.com/v1/file_uploads",
                      headers=notion_headers(),
                      json={"file_name": name, "file_mime_type": mime}, timeout=60)
    r.raise_for_status(); return r.json()

def notion_send_file_upload(file_upload_id: str, filepath: Path):
    headers = {k:v for k,v in notion_headers().items() if k!="Content-Type"}
    with open(filepath, "rb") as fh:
        r = requests.post(f"https://api.notion.com/v1/file_uploads/{file_upload_id}/send",
                          headers=headers, files={"file": (filepath.name, fh)}, timeout=600)
    r.raise_for_status(); return r.json()

def as_uploaded_file_obj(file_upload_id: str, name: str) -&gt; Dict[str, Any]:
    return {"name": name, "type": "file_upload", "file_upload": {"id": file_upload_id}}

def notion_update_media_property(page_id: str, media_prop: str, files: List[Dict[str, Any]]):
    payload = {"properties": {media_prop: {"files": files}}}
    r = requests.patch(f"https://api.notion.com/v1/pages/{page_id}",
                       headers=notion_headers(), json=payload, timeout=60)
    if r.status_code &gt;= 400:
        logging.error(f"Media 속성 업데이트 실패: {r.status_code} {r.text}\nPayload: {payload}")
    r.raise_for_status()

def notion_append_file_blocks(page_id: str, files: List[Dict[str, Any]]):
    children = []
    for f in files:
        children.append({"object":"block","type":"file",
                         "file":{"type":"file_upload","file_upload":{"file_upload_id": f["file_upload"]["id"]}}})
    r = requests.patch(f"https://api.notion.com/v1/blocks/{page_id}/children",
                       headers=notion_headers(), json={"children": children}, timeout=60)
    if r.status_code &gt;= 400:
        logging.error(f"파일 블록 첨부 실패: {r.status_code} {r.text}")
    r.raise_for_status()

# ===================== 파이프라인 =====================
def run_pipeline(account: str, out_dir: Path, target_count: int, max_scroll: int, headless: bool):
    result = scrape(account, out_dir, max_scroll, SCROLL_PAUSE, headless, target_count=target_count)
    tweets = result["tweets"]; media_dir: Path = result["media_dir"]

    if not (NOTION_API_KEY and NOTION_DATABASE_ID):
        logging.error("NOTION_API_KEY/NOTION_DATABASE_ID 필요"); return

    db = notion_get_db()
    title_prop = find_title_prop(db)
    opt_props  = map_optional_props(db)
    if not opt_props["media"]:
        created = ensure_media_property(db)
        if created: opt_props["media"] = created

    for tid, t in tweets.items():
        row = {
            "id": tid,
            "text": t.get("text",""),
            "images": t.get("images",[]),
            "videos": t.get("videos",[]),
            "tweet_url": normalize_x_url(t.get("orig_video") or f"https://x.com/{account}/status/{tid}"),
        }

        page_id = notion_query_by_title(title_prop, row["id"])
        if not page_id:
            try:
                page_id = notion_create_page(row, title_prop, opt_props)
            except requests.HTTPError as e:
                logging.error(f"[{tid}] 페이지 생성 실패 → 스킵: {e}")
                continue
        time.sleep(0.25)

        existing_names = set()
        if opt_props["media"]:
            try:
                existing_names = set(notion_get_page_media_names(page_id, opt_props["media"]))
            except Exception as e:
                logging.warning(f"[{tid}] 기존 Media 조회 실패(무시): {e}")

        uploaded_files: List[Dict[str, Any]] = []

        # 이미지
        for p in sorted(media_dir.glob(f"{tid}_img*.jpg")):
            if not p.exists() or p.name in existing_names: continue
            temp = p.with_suffix(".upload.jpg")
            if not compress_image_to_limit(p, temp, MAX_UPLOAD_BYTES):
                logging.error(f"[{tid}] 이미지 5MiB 이하 압축 실패: {p.name}")
                if temp.exists(): temp.unlink(missing_ok=True)
                continue
            try:
                meta = notion_create_file_upload(p.name, mime_from_suffix(temp))
                notion_send_file_upload(meta["id"], temp)
                uploaded_files.append(as_uploaded_file_obj(meta["id"], p.name))
                temp.unlink(missing_ok=True); p.unlink(missing_ok=True)
                logging.info(f"[{tid}] 이미지 업로드 성공 → {p.name}")
            except Exception as e:
                logging.error(f"[{tid}] 이미지 업로드 실패({p.name}): {e}")
                if temp.exists(): temp.unlink(missing_ok=True)
            time.sleep(0.12)

        # 동영상
        v = media_dir / f"{tid}_video.mp4"
        if v.exists() and v.name not in existing_names:
            tempv = v.with_suffix(".upload.mp4")
            if compress_video_to_limit(v, tempv, MAX_UPLOAD_BYTES):
                try:
                    meta = notion_create_file_upload(v.name, mime_from_suffix(tempv))
                    notion_send_file_upload(meta["id"], tempv)
                    uploaded_files.append(as_uploaded_file_obj(meta["id"], v.name))
                    tempv.unlink(missing_ok=True); v.unlink(missing_ok=True)
                    logging.info(f"[{tid}] 동영상 업로드 성공 → {v.name}")
                except Exception as e:
                    logging.error(f"[{tid}] 동영상 업로드 실패({v.name}): {e}")
                    if tempv.exists(): tempv.unlink(missing_ok=True)
            else:
                logging.error(f"[{tid}] 동영상 5MiB 이하 압축 실패: {v.name}")
                if tempv.exists(): tempv.unlink(missing_ok=True)

        # 반영
        if uploaded_files:
            try:
                if opt_props["media"]:
                    notion_update_media_property(page_id, opt_props["media"], uploaded_files)
                    logging.info(f"[{tid}] Media 속성에 {len(uploaded_files)}개 설정")
                else:
                    notion_append_file_blocks(page_id, uploaded_files)
                    logging.info(f"[{tid}] 파일 블록으로 {len(uploaded_files)}개 첨부")
            except Exception as e:
                logging.error(f"[{tid}] 파일 반영 실패: {e}")
        else:
            logging.info(f"[{tid}] 신규 업로드 없음")

# ===================== 엔트리포인트 =====================
def main():
    run_pipeline(ACCOUNT, OUT_DIR, TARGET_COUNT, MAX_SCROLL, HEADLESS)

if __name__ == "__main__":
    main()</pre>
</div>
]]></content:encoded>
					
		
		
		<media:content url="https://i2.wp.com/2days.kr/wp-content/uploads/2025/11/제목을-입력해주세요__-복사본-001-79-1024x1024.jpg?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>2025년 원스트라이크 아웃제도 전면 시행! 자본시장에 닥친 경고</title>
		<link>https://2days.kr/17/07/11/64708/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Thu, 17 Jul 2025 02:11:02 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64708</guid>

					<description><![CDATA[2025년 원스트라이크 아웃제도 전면 시행! 자본시장에 닥친 경고 &#8220;주가조작 한 번이면 끝!&#8221; 이제 자본시장에선 진짜로 기회가 단 한 번뿐입니다. 안녕하세요, 요즘 뉴스 보셨나요? 저는 며칠 전 친구와 카페에서 자산운용 이야기를 하다가 ‘원스트라이크 아웃제도’ 소식을 처음 접했어요. 한 번의 불공정거래만으로 자본시장에서 퇴출될 수 있다니, 그야말로 판도가 확 바뀌는 느낌이더라구요. 특히나 요즘처럼 투자자들이 유튜브나 커뮤니티에서 정보 찾다 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h3 style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size23"><span style="color: #000000; font-size: 15px;">2025년 원스트라이크 아웃제도 전면 시행! 자본시장에 닥친 경고 &#8220;주가조작 한 번이면 끝!&#8221; 이제 자본시장에선 진짜로 기회가 단 한 번뿐입니다.</span></h3>
<p style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16"><span style="color: #000000;">안녕하세요, 요즘 뉴스 보셨나요? 저는 며칠 전 친구와 카페에서 자산운용 이야기를 하다가 ‘원스트라이크 아웃제도’ 소식을 처음 접했어요. 한 번의 불공정거래만으로 자본시장에서 퇴출될 수 있다니, 그야말로 판도가 확 바뀌는 느낌이더라구요. 특히나 요즘처럼 투자자들이 유튜브나 커뮤니티에서 정보 찾다 피해보는 경우가 많다 보니, 이런 강력한 제재가 오히려 신뢰를 줄 수 있을지도 모르겠단 생각이 들었죠. 그래서 이번 글에서는 2025년부터 시행되는 이 제도가 뭔지, 우리 투자자에게 어떤 의미인지 차근차근 정리해보려고 해요.</span></p>
<h3 style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size23"><b><span style="color: #000000;">2025년 원스트라이크 아웃제도 전면 시행! 자본시장에 닥친 경고</span></b></h3>
<figure id="attachment_64709" aria-describedby="caption-attachment-64709" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64709 size-large" fifu-data-src="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1" alt="2025년 원스트라이크 아웃제도 전면 시행! 자본시장에 닥친 경고" width="696" height="380" loading="lazy" title="2025년 원스트라이크 아웃제도 전면 시행! 자본시장에 닥친 경고 2"><figcaption id="caption-attachment-64709" class="wp-caption-text">2025년 원스트라이크 아웃제도 전면 시행! 자본시장에 닥친 경고</figcaption></figure>

<div style="background: linear-gradient(135deg, #f5f0ff, #f0e6ff); border-radius: 8px; padding: 20px; margin: 20px 0; box-shadow: 0 4px 10px rgba(106, 27, 154, 0.08); font-family: 'Noto Sans KR', sans-serif; border-left: 4px solid #9c27b0;">
<div style="margin-bottom: 15px;">
<h3 style="font-weight: bold; color: #4a148c; font-size: 18px; margin: 0;">목차</h3>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;"><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#what-is-out">원스트라이크 아웃제도란 무엇인가?</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#why-now">왜 지금 ‘원스트라이크 아웃’인가?</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#ai-system">AI 기반 감시 시스템, 무엇이 달라졌나</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#penalty">주가조작 시, 어떤 제재가 가해질까?</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#delisting">부실 상장사 퇴출 기준도 강화된다</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#reporting">불공정거래를 목격했다면 이렇게 신고하세요</a></div>
</div>
<h2 id="what-is-out" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">원스트라이크 아웃제도란 무엇인가?</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">2025년부터 시행되는 &#8216;원스트라이크 아웃제도&#8217;는 자본시장 내 불공정거래를 한 번만 저질러도 즉시 퇴출될 수 있는 매우 강력한 제재 방식입니다. 과거에는 수차례 적발되어야 실질적인 퇴출로 이어졌지만, 이제는 주가조작, 내부자거래, 허위공시 등의 위반이 단 한 번만 있어도 심각한 불이익이 따르게 되죠.</p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">특히 이번 제도에는 <b>불법이익 계좌의 즉시 지급정지, 과징금 최대 2배 부과, 임원 선임 및 금융거래 제한</b> 같은 복합적인 조치가 포함되어 있어요. 단순한 경고 수준이 아니라, 자본시장에서의 생명줄 자체를 끊는 셈이죠.</p>
<h2 id="why-now" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">왜 지금 ‘원스트라이크 아웃’인가?</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">최근 몇 년 사이, SNS와 유튜브를 통한 허위 정보 유포와 AI 기반 시세조종 같은 수법이 급증하면서 기존 제도로는 이를 감당하기 어려운 상황이었어요. 이런 배경 속에서 &#8216;한두 번쯤은 괜찮겠지&#8217;라는 생각 자체를 차단하고, 반복 범죄의 뿌리를 뽑기 위해 ‘원스트라이크 아웃제도’가 도입된 것입니다.</p>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">기존 제도</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">신설 제도</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">다수 위반 시 누적 제재</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">한 번의 위반으로 즉시 퇴출</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">조사 이후 제재 조치</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">수사 전 단계에서 선제 차단</td>
</tr>
</tbody>
</table>
<h2 id="ai-system" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">AI 기반 감시 시스템, 무엇이 달라졌나</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">이번 제도 시행과 함께 자본시장 감시 시스템도 크게 바뀌었어요. 기존에는 계좌 단위의 감시였다면 이제는 <b>‘개인 식별 기반’</b> 분석으로 전환되었고, AI가 이상 거래를 정밀하게 탐지할 수 있게 되었죠.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">동일인 식별 기술로 연관 계좌 추적 가능</li>
<li style="margin-bottom: 0.5em; position: relative;">AI로 시세 관여율 분석 및 예측 가능</li>
<li style="margin-bottom: 0.5em; position: relative;">수사 전 단계에서 지급정지 등 선제 조치 가능</li>
</ul>
<h2 id="penalty" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">주가조작 시, 어떤 제재가 가해질까?</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">주가조작이 적발되면 이제는 단순한 과징금 수준에서 끝나지 않아요. ‘생활 전체를 뒤흔들 만큼의 제재’가 가해집니다. 말 그대로, 한 번의 위반이 인생의 큰 전환점이 될 수 있는 거죠.</p>
<h2 id="delisting" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">부실 상장사 퇴출 기준도 강화된다</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">‘원스트라이크 아웃제도’는 단지 불공정거래 적발자만 겨냥하는 것이 아닙니다. 부실 상장사들도 이제는 더 엄격한 기준에 따라 퇴출될 수 있어요. 투자자 입장에서는 보다 안전한 환경에서 거래하게 되는 거죠.</p>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">강화 항목</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">내용</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">시가총액·매출액 기준</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">기존보다 상향 조정되어 일정 수준 미달 시 퇴출</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">감사의견</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">2년 연속 비적정 의견 시 즉시 상장폐지</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">코스닥 퇴출 심사</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">단심제로 간소화되어 신속한 조치 가능</td>
</tr>
</tbody>
</table>
<h2 id="reporting" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">불공정거래를 목격했다면 이렇게 신고하세요</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">혹시 주가조작이나 허위 정보 유포 같은 장면을 직접 목격했다면? 지금 바로 아래 경로로 신고할 수 있습니다. 신고자는 철저히 보호되고, 보상금도 지급되니 적극적인 참여가 필요해요.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">인터넷 접수: 시장감시위원회 불공정거래신고센터</li>
<li style="margin-bottom: 0.5em; position: relative;">전화 접수: 1577-0088</li>
<li style="margin-bottom: 0.5em; position: relative;">익명 보장 + 보상금 제도 운영 중</li>
</ul>
<div style="margin: 2em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; font-size: 1.5rem; margin-bottom: 1em;">자주 묻는 질문 (FAQ)</div>
<div style="margin-bottom: 2em;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> &#8216;원스트라이크 아웃제도&#8217;는 모든 자본시장 범죄에 적용되나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">아니요. 주가조작, 허위공시, 내부자거래 등 중대 불공정거래 행위에만 적용됩니다. 단순 실수나 행정 오류는 제외돼요.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 적용 대상은 중대한 자본시장 범죄</div>
</div>
<div style="margin-bottom: 2em;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 제보자가 보복을 당할 위험은 없나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">불공정거래 신고 시스템은 익명성을 보장하며, 신원 노출 시 법적으로도 보호 조치가 적용됩니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 제보자는 철저히 보호됩니다</div>
</div>
<div style="margin-bottom: 2em;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 과거 범죄 이력도 적용 대상인가요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">2025년 7월 이후 발생한 범죄에 대해서만 적용되며, 과거 이력은 참고자료로만 활용됩니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 시행일 이후 사건만 해당됩니다</div>
</div>
<div style="margin-bottom: 2em;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 상장사 퇴출은 누가 결정하나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">한국거래소에서 심사 기준에 따라 단심제로 결정하며, 이의제기 절차는 제한됩니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 거래소 단심제로 신속 결정</div>
</div>
<div style="margin-bottom: 2em;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 금융감독원도 수사권이 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">수사권은 없지만, 금융위·거래소·검찰과 협조하여 강제조사 요청 및 자료 공유가 가능합니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 협조 기반 강제조사 요청 가능</div>
</div>
<div style="margin-bottom: 2em;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 실수로 위반한 경우도 퇴출되나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">고의성이 입증되지 않은 경우 경고 또는 시정명령 수준으로 그칩니다. 단, 반복 실수는 예외가 될 수 있어요.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 단순 실수는 유예될 수 있음</div>
</div>
</div>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">2025년부터 전면 시행된 ‘원스트라이크 아웃제도’는 단순히 규제를 강화한 수준이 아닙니다. 시장의 체질을 바꾸는 강력한 선언이자, 투자자 보호를 위한 결정적 수단이죠. 이제는 투자자 스스로도 더욱 책임 있는 판단이 필요해졌어요. 여러분은 어떻게 생각하시나요? 댓글로 여러분의 생각을 나눠주세요. 그리고 이 글이 유익했다면, 주변에도 꼭 공유해 주세요!</p>
<p style="font-size: 0.9rem; line-height: 1.6; color: #666; font-family: 'Noto Sans KR', sans-serif;">투자자 보호, 자본시장 개혁, 주가조작, 불공정거래, 원스트라이크아웃, 상장폐지, 감시제도, 금융정책, AI감시, 코스닥기준</p>
<p style="font-size: 0.9rem; line-height: 1.6; color: #666; font-family: 'Noto Sans KR', sans-serif;"><a style="background-color: #e6f5ff; color: #0070d1; text-align: start;" href="https://aboda.kr/entry/%EC%BD%94%EC%8A%A4%ED%94%BC-%EB%A7%A4%EB%8F%84-%EC%82%AC%EC%9D%B4%EB%93%9C%EC%B9%B4-%EB%B0%9C%EB%8F%99-%EB%A7%A4%EB%8F%84-%EC%8B%A4%EB%A6%AC-%EC%97%84%EC%B2%AD%EB%82%98" target="_blank" rel="noopener">2025.04.07 &#8211; [경제상식/주식] &#8211; 코스피 매도 사이드카 발동, 매도 실리 엄청나</a></p>
<p><a href="https://2days.kr/27/08/20/45946/lifestyle/whats-hot/">주식의 기초정보(코스피와 코스닥,지수)</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-68-1024x559.png?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>키보드 입력 한 줄로 만드는 게임? Mirage AI 실시간 게임 생성의 미래</title>
		<link>https://2days.kr/14/07/12/64637/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Mon, 14 Jul 2025 03:35:28 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64637</guid>

					<description><![CDATA[키보드 입력 한 줄로 만드는 게임? Mirage AI 실시간 게임 생성의 미래 게임 만드는 게 코딩보다 쉬운 세상? 이제는 한 문장만으로도 게임을 만들 수 있어요! 안녕하세요, 요즘 기술 뉴스 볼 때마다 놀랄 일이 너무 많지 않나요? 특히 저는 게임을 좋아하는 사람으로서 Mirage AI라는 이름을 처음 들었을 때, 솔직히 &#8216;또 뻔한 데모겠지&#8217; 싶었어요. 근데요, 진짜 해보고 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="font-size: 1.1rem; line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;"><span style="color: #000000;">키보드 입력 한 줄로 만드는 게임? Mirage AI 실시간 게임 생성의 미래 게임 만드는 게 코딩보다 쉬운 세상? 이제는 한 문장만으로도 게임을 만들 수 있어요!</span></p>
<p style="font-size: 1.1rem; line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;"><span style="color: #000000;">안녕하세요, 요즘 기술 뉴스 볼 때마다 놀랄 일이 너무 많지 않나요? 특히 저는 게임을 좋아하는 사람으로서 Mirage AI라는 이름을 처음 들었을 때, 솔직히 &#8216;또 뻔한 데모겠지&#8217; 싶었어요. 근데요, 진짜 해보고 나니까&#8230; 완전 충격! 😲 그냥 키보드에 &#8220;도시가 폭발하는 게임 보여줘&#8221;라고 치니까 GTA 느낌의 장면이 눈앞에 펼쳐지더라고요. 여러분도 저처럼 게임을 직접 만들어보는 게 꿈이었다면, 이 글 꼭 끝까지 읽어주세요. 뭔가 새로운 세상이 열리고 있다는 느낌, 진짜예요.</span></p>
<h3 style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size23"><b><span style="color: #000000;">키보드 입력 한 줄로 만드는 게임? Mirage AI 실시간 게임 생성의 미래</span></b></h3>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter">
<p><figure id="attachment_64639" aria-describedby="caption-attachment-64639" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64639 size-large" fifu-data-src="https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1" alt="키보드 입력 한 줄로 만드는 게임? Mirage AI 실시간 게임 생성의 미래" width="696" height="380" loading="lazy" title="키보드 입력 한 줄로 만드는 게임? Mirage AI 실시간 게임 생성의 미래 3"><figcaption id="caption-attachment-64639" class="wp-caption-text">키보드 입력 한 줄로 만드는 게임? Mirage AI 실시간 게임 생성의 미래</figcaption></figure></figure>
<div style="background: linear-gradient(135deg, #f5f0ff, #f0e6ff); border-radius: 8px; padding: 20px; margin: 20px 0; box-shadow: 0 4px 10px rgba(106, 27, 154, 0.08); font-family: 'Noto Sans KR', sans-serif; border-left: 4px solid #9c27b0;">
<div style="margin-bottom: 15px;">
<h3 style="font-weight: bold; color: #4a148c; font-size: 18px; margin: 0;">목차</h3>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;"><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#what-is-mirage">Mirage AI란 무엇인가?</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#key-features">Mirage AI의 핵심 기능 살펴보기</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#demo-experience">직접 체험해본 데모 소개</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#current-limitations">아직은 아쉬운 점들</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#future-potential">Mirage AI의 미래 가능성</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#final-thoughts">정리하며: 게임 제작의 새로운 시대</a></div>
</div>
<h2 id="what-is-mirage" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">Mirage AI란 무엇인가?</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">Mirage AI는 Dynamics Lab에서 개발한 혁신적인 실시간 AI 게임 생성 플랫폼입니다. 간단히 말해서, 사용자가 한 문장 정도의 텍스트나 키보드 조작만으로도 게임 세계를 만들어낼 수 있는 기술이에요. 기존의 게임 제작은 엄청난 리소스와 시간이 필요했죠. 그런데 Mirage AI는 그런 제작 과정을 생략하고, <b>즉석에서 게임 콘텐츠를 생성해주는</b> 거예요. 예를 들면, &#8220;좀비가 등장하는 폐허 도시를 보여줘!&#8221;라고 입력하면 바로 그런 장면이 펼쳐집니다. 뭔가 영화 속 기술이 현실로 나타난 느낌이에요.</p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;"><a href="https://blog.dynamicslab.ai/" target="_blank" rel="noopener">https://blog.dynamicslab.ai/</a></p>
<figure id="og_1752462714826" contenteditable="false" data-ke-type="opengraph" data-ke-align="alignCenter" data-og-type="website" data-og-title="Mirage: AI UGC game engine" data-og-description="The future of gaming isn't built level by level by expert designers—it's imagined, generated, and played by anyone, in real time. Meet Mirage: the world's first real-time generative engine enabling live UGC gameplay through state-of-the-art AI World Mode" data-og-host="blog.dynamicslab.ai" data-og-source-url="https://blog.dynamicslab.ai/" data-og-url="https://blog.dynamicslab.ai/" data-og-image="https://scrap.kakaocdn.net/dn/u80B0/hyZjz96lAy/TfBrK469cERDHWFjUV8h00/img.png?width=1070&amp;height=601&amp;face=0_0_1070_601,https://scrap.kakaocdn.net/dn/b7BxaB/hyZjwMj6LB/90yddMyMSLU7Gv6if2KoC0/img.png?width=960&amp;height=540&amp;face=0_0_960_540,https://scrap.kakaocdn.net/dn/bkH3QF/hyZjFoYr2H/CPJ76USRRiltAPOoJTgnBk/img.png?width=960&amp;height=540&amp;face=0_0_960_540">
<div class="og-image"></div>
<div class="og-text">
<p class="og-title">Mirage: AI UGC game engine</p>
<p class="og-desc">The future of gaming isn&#8217;t built level by level by expert designers—it&#8217;s imagined, generated, and played by anyone, in real time. Meet Mirage: the world&#8217;s first real-time generative engine enabling live UGC gameplay through state-of-the-art AI World Mode</p>
<p class="og-host">blog.dynamicslab.ai</p>
</div>
</figure>
<h2 id="key-features" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">Mirage AI의 핵심 기능 살펴보기</h2>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter"><figcaption>

</figcaption></figure>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">기능</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">설명</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">실시간 생성</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">플레이 도중에도 환경, 객체 등을 즉시 생성</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">포토리얼 그래픽</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">현실감 있는 그래픽과 물리 기반 렌더링 제공</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">프롬프트 기반 인터랙션</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">자연어 한 줄로 장면 및 시나리오 구현 가능</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Transformer + Diffusion</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">시간 흐름과 시각 묘사 동시 처리</td>
</tr>
</tbody>
</table>
<h2 id="demo-experience" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">직접 체험해본 데모 소개</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">제가 실제로 체험해본 데모는 <b>Urban Chaos</b>와 <b>Coastal Drift</b> 두 가지였어요. 각각 도심 속 혼돈과 해안 드라이브를 테마로 하는 게임인데, 모두 Mirage AI가 실시간으로 생성해주는 거예요.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">Urban Chaos: GTA 스타일, 도시 파괴 및 차량 조작 가능 <a href="https://demo.dynamicslab.ai/chaos" target="_blank" rel="noopener">https://demo.dynamicslab.ai/chaos</a></li>
<li style="margin-bottom: 0.5em; position: relative;">Coastal Drift: Forza Horizon 느낌, 해안 도로에서 질주 체험 <a href="https://demo.dynamicslab.ai/drift" target="_blank" rel="noopener">https://demo.dynamicslab.ai/drift</a></li>
</ul>
<h2 id="current-limitations" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">아직은 아쉬운 점들</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">Mirage AI는 정말 인상적인 기술이지만, 아직 완벽하다고 보기엔 조금 이른 단계입니다. 특히 해상도나 프레임 속도는 현재 SD급에 머물러 있고, 복잡한 장면에서는 약간의 딜레이도 느껴져요. 그리고 <b>개발자 도구(API, SDK)</b>가 제공되지 않아 일반 유저 이상의 활용은 불가능한 상황입니다.</p>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">제한 요소</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">현재 상황</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">해상도/프레임</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">SD급, 약 16FPS</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">시각적 일관성</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">단기적 연결은 양호하나 장기성 부족</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">개발자 접근성</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">API/SDK 미공개</td>
</tr>
</tbody>
</table>
<h2 id="future-potential" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">Mirage AI의 미래 가능성</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">Dynamics Lab은 Mirage를 단순한 체험형 AI가 아닌, <b>진짜 ‘창작 플랫폼’</b>으로 키우고자 하고 있어요. 그 비전이 정말 멋있더라고요. 공식 블로그에서도 &#8220;Not just PLAY—but CREATE&#8221;라는 문장을 강조하듯이, 단순한 플레이를 넘어 함께 만들어가는 환경을 지향합니다.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">모바일, VR/AR, 콘솔 확장 계획</li>
<li style="margin-bottom: 0.5em; position: relative;">멀티 유저 협업 기능 및 공동 프롬프트 편집 가능성</li>
<li style="margin-bottom: 0.5em; position: relative;">베타 API/SDK 공개 예정 소식</li>
</ul>
<h2 id="final-thoughts" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">정리하며 게임 제작의 새로운 시대</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">Mirage AI는 단순한 AI 데모를 넘어서, 우리가 알고 있던 게임 제작 패러다임을 완전히 뒤집는 기술이에요. 물론 아직은 부족한 점도 많지만, 분명히</p>
<p><mark style="background-color: #e1bee7; color: #6a1b9a; padding: 0 3px; border-radius: 2px; font-family: 'Noto Sans KR', sans-serif;">우리가 기대해온 미래에 가장 가까운 게임 도구</mark></p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">중 하나입니다.</p>
<div style="margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Mirage AI는 일반 사용자가 게임을 만들 수 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">네, 가능합니다. 현재는 데모 환경 위주이지만, 키보드 입력이나 간단한 명령어로 누구나 게임을 생성할 수 있어요.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Mirage AI는 무료인가요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">현재 공개된 데모 버전은 무료로 체험 가능합니다. 향후 유료화 여부는 아직 발표되지 않았어요.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 데모를 사용하려면 설치가 필요한가요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">아니요, 별도 설치 없이 브라우저에서 바로 실행됩니다. WebRTC 기반의 스트리밍 방식이에요.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Mirage AI는 어떤 기술로 만들어졌나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">Transformer 기반 시퀀스 모델과 Diffusion 시각 생성기를 혼합한 구조를 사용하고 있어요.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 다른 사람과 함께 게임을 만들 수 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">아직은 멀티 유저 기능은 없지만, 향후 협업형 콘텐츠 제작 기능이 도입될 가능성이 있습니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Mirage AI 데모 링크는 어디서 확인할 수 있나요?</div>
<div style="margin-left: 32px;">
<p style="margin: 0; line-height: 1.6;">공식 데모 페이지에서 확인할 수 있어요. <a style="color: #8e24aa; text-decoration: none; font-weight: bold;" href="https://demo.dynamicslab.ai/chaos" target="_blank" rel="noopener">Urban Chaos</a>, <a style="color: #8e24aa; text-decoration: none; font-weight: bold;" href="https://demo.dynamicslab.ai/drift" target="_blank" rel="noopener">Coastal Drift</a>를 직접 플레이해보세요!</p>
</div>
</div>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">요즘은 기술이라는 게 하루가 다르게 발전하잖아요. 근데 그 중심에 Mirage AI 같은 도구가 있다는 사실, 솔직히 좀 놀랍지 않나요? 이 글을 통해 저처럼 &#8216;게임은 해봤지만 만들어본 적은 없는&#8217; 분들에게도 새로운 세상이 열리고 있다는 걸 느끼셨길 바래요. 한 문장만으로도 상상하던 세계가 펼쳐지는 경험, 꼭 한 번 해보세요. 그리고 댓글이나 이메일로 여러분의 체험담도 공유해 주세요! 우리 함께 이 미래를 만들어가요. 💜</p>
<p style="font-size: 0.95rem; color: #666; font-family: 'Noto Sans KR', sans-serif;">Mirage AI, 게임 생성 AI, 실시간 게임 제작, 프롬프트 기반 게임, Dynamics Lab, Urban Chaos 데모, Coastal Drift 데모, 게임 엔진 혁신, AI</p>
<p><a href="https://aboda.kr/entry/GPT%EC%99%80-MCP-%EC%97%B0%EB%8F%99-Notion%EC%9D%84-%EB%B6%84%EC%84%9D%ED%95%98%EB%8A%94-AI-%EB%8F%84%EA%B5%AC-%EB%A7%8C%EB%93%A4%EA%B8%B0" target="_blank" rel="noopener">2025.07.10 &#8211; [제품추천/IT] &#8211; GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기</a></p>
<p><a href="https://2days.kr/24/06/10/64187/contents/">Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-62-1024x559.png?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>텍스트로 포토샵까지? OmniGen2로 이미지 생성과 편집까지 한 번에</title>
		<link>https://2days.kr/14/07/12/64632/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Mon, 14 Jul 2025 03:08:20 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64632</guid>

					<description><![CDATA[텍스트로 포토샵까지? OmniGen2로 이미지 생성과 편집까지 한 번에 이제 텍스트 한 줄이면 놀랍도록 정밀한 이미지 수정까지? OmniGen2로 가능한 마법 같은 작업, 지금 시작해보세요! 안녕하세요, 여러분 요즘 생성형 AI에 관심 많으시죠? 저도 디자인이나 콘텐츠 작업할 때마다 &#8220;아, 이런 기능이 자동으로 되면 얼마나 좋을까&#8221; 하는 생각 자주 했는데요. 최근 OmniGen2라는 모델을 알게 되면서 그런 상상이 현실이 되는 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size18"><span style="color: #000000;">텍스트로 포토샵까지? OmniGen2로 이미지 생성과 편집까지 한 번에 이제 텍스트 한 줄이면 놀랍도록 정밀한 이미지 수정까지? OmniGen2로 가능한 마법 같은 작업, 지금 시작해보세요!</span></p>
<p style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size18"><span style="color: #000000;">안녕하세요, 여러분 요즘 생성형 AI에 관심 많으시죠? 저도 디자인이나 콘텐츠 작업할 때마다 &#8220;아, 이런 기능이 자동으로 되면 얼마나 좋을까&#8221; 하는 생각 자주 했는데요. 최근 OmniGen2라는 모델을 알게 되면서 그런 상상이 현실이 되는 걸 직접 경험했답니다. 단순한 이미지 생성이 아니라, 진짜 포토샵처럼 원하는 부분만 텍스트로 수정할 수 있다는 점에서 정말 충격적이었어요. 오늘은 제가 직접 테스트해본 OmniGen2 설치법부터, 이미지 생성과 편집까지 전 과정을 알차게 공유해볼게요.</span></p>
<h3 style="line-height: 1.8; margin-bottom: 1.2em; color: #333333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size23"><b>텍스트로 포토샵까지? OmniGen2로 이미지 생성과 편집까지 한 번에</b></h3>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter">
<p><figure id="attachment_64633" aria-describedby="caption-attachment-64633" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64633 size-large" fifu-data-src="https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1" alt="텍스트로 포토샵까지? OmniGen2로 이미지 생성과 편집까지 한 번에" width="696" height="696" loading="lazy" title="텍스트로 포토샵까지? OmniGen2로 이미지 생성과 편집까지 한 번에 5"><figcaption id="caption-attachment-64633" class="wp-caption-text">텍스트로 포토샵까지? OmniGen2로 이미지 생성과 편집까지 한 번에</figcaption></figure></figure>
<div style="background: linear-gradient(135deg, #f5f0ff, #f0e6ff); border-radius: 8px; padding: 20px; margin: 20px 0; box-shadow: 0 4px 10px rgba(106, 27, 154, 0.08); font-family: 'Noto Sans KR', sans-serif; border-left: 4px solid #9c27b0;">
<div style="margin-bottom: 15px;">
<h3 style="font-weight: bold; color: #4a148c; font-size: 18px; margin: 0;">목차</h3>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;"><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#setup-environment">1. OmniGen2 설치 및 실행 환경</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#download-location">2. 모델 다운로드 및 위치 설정</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#image-generation">3. 텍스트로 이미지 생성하기</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#image-editing">4. 기존 이미지 텍스트로 수정하기</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#workflow-tips">5. ComfyUI 워크플로우 팁</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#performance-review">6. 성능 테스트 및 사용 후기</a></div>
</div>
<h2 id="setup-environment" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">1. OmniGen2 설치 및 실행 환경</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">설치를 시작하기 전에, 제 시스템 환경을 먼저 공유드릴게요. 저는 Windows 11에서 테스트했고, GPU는 RTX 4060 Ti 모델이에요. ComfyUI는 0.3.44 버전, torch는 2.7.1에 cu128 환경이었습니다. OmniGen2는 약 14.5GB의 VRAM을 요구하므로, 최소 RTX 3060 이상은 있어야 쾌적하게 돌아가요.</p>
<h2 id="download-location" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">2. 모델 다운로드 및 위치 설정</h2>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">모델 종류</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">파일명</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">이동 경로</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">diffusion 모델</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">omnigen2_fp16.safetensors</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">models/diffusion_model</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">text_encoder 모델</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">qwen_2.5_vl_fp16.safetensors</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">models/text_encoders</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">vae 모델</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">as.safetensors</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">models/vae</td>
</tr>
</tbody>
</table>
<h2 id="image-generation" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">3. 텍스트로 이미지 생성하기</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">이미지를 생성할 때 사용한 프롬프트는 꽤 디테일하게 구성했어요. 예를 들어, “A cat with a crown lounging on a velvet throne…” 식으로요. 부정 프롬프트도 꼭 함께 설정해서 퀄리티 낮은 요소를 방지했구요.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">긍정 프롬프트: 왕좌에 앉은 고양이, 벨벳 질감, 왕관, 드라마틱한 조명 등</li>
<li style="margin-bottom: 0.5em; position: relative;">부정 프롬프트: blurry, low quality, deformed, ugly 등</li>
</ul>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">이렇게 구성한 프롬프트를 ComfyUI에 입력하고 실행하면, 약 80초 내외로 한 장의 이미지가 생성되며 퀄리티는 정말 인상적이었어요.</p>
<h2 id="image-editing" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">4. 기존 이미지 텍스트로 수정하기</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">기존 이미지를 수정하는 작업은 진짜 OmniGen2의 진가를 보여주는 순간이었어요. 한 장의 원본 이미지를 기반으로, 프롬프트만 바꿔서 완전히 다른 분위기나 디테일을 구현할 수 있었죠. VRAM은 약 14GB 정도 사용됐고, 2분 40초 정도 시간이 소요됐습니다.</p>
<h2 id="workflow-tips" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">5. ComfyUI 워크플로우 팁</h2>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">작업 요소</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">추천 노드</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">특징</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">텍스트 기반 생성</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Prompt + Sampler + KSampler</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">빠른 이미지 생성 가능</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">이미지 수정</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Image Input + Masking + VAE Decode</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">정밀한 영역 수정 가능</td>
</tr>
</tbody>
</table>
<h2 id="performance-review" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">6. 성능 테스트 및 사용 후기</h2>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">복잡한 재질(크리스탈, 유리 등)도 잘 표현됨</li>
<li style="margin-bottom: 0.5em; position: relative;">머리카락 색상, 배경, 소품 등 세부 수정 정확도 높음</li>
<li style="margin-bottom: 0.5em; position: relative;">부정 프롬프트의 품질 제어 능력 매우 우수</li>
</ul>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">솔직히 말하면, 이 정도 수준이면 포토샵 초보자보다 훨씬 더 정교하게 이미지를 만질 수 있을 정도였어요. 이제는 텍스트만 입력해도 원하는 장면을 만들 수 있는 시대니까요. 진짜 놀랍습니다.</p>
<div style="margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> OmniGen2는 무료로 사용할 수 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">네, OmniGen2는 Apache 2.0 라이선스 하에 공개된 오픈소스 프로젝트입니다. 상업적 이용도 가능합니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> OmniGen2는 어떤 운영체제에서 실행되나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">현재는 Windows 환경에서 가장 안정적으로 작동하며, ComfyUI를 활용할 경우 로컬 환경에서도 잘 돌아갑니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> GPU 없이도 OmniGen2를 사용할 수 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">아쉽게도 현재로서는 GPU가 반드시 필요합니다. 최소 VRAM 12GB 이상을 권장합니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 텍스트 프롬프트 작성 시 주의할 점이 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">되도록 구체적인 단어와 문장을 사용하고, 긍정 프롬프트와 부정 프롬프트를 함께 작성하는 것이 좋습니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> OmniGen2로 어떤 이미지 수정이 가능한가요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">질감 변경, 헤어스타일 수정, 배경 변경, 조명 조절 등 세부적인 편집이 가능하며, 기존 스타일을 유지한 변화도 만들 수 있습니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 초보자도 설치와 사용이 쉬운가요?</div>
<div style="margin-left: 32px;">
<p style="margin: 0; line-height: 1.6;">ComfyUI와 공식 워크플로우를 이용하면 초보자도 비교적 쉽게 따라할 수 있습니다. 관련 커뮤니티 문서도 잘 갖춰져 있어요.</p>
</div>
</div>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">OmniGen2는 정말 매력적인 이미지 생성 도구예요. 단순한 텍스트 입력만으로 이렇게 디테일하고 자연스러운 결과를 만들어낼 수 있다는 게 아직도 좀 놀랍네요. 여러분도 한 번 도전해보세요! 혹시 설치하다 막히거나 궁금한 게 생기면 언제든 댓글로 남겨주세요. 함께 해결해봐요 😊</p>
<p style="font-size: 0.95rem; line-height: 1.6; margin-bottom: 1.2em; color: #666; font-family: 'Noto Sans KR', sans-serif;">OmniGen2, ComfyUI, 이미지 생성 AI, AI 이미지 편집, 오픈소스 AI, 텍스트 이미지 생성, 인공지능 툴, 로컬 AI 설치, 이미지 프롬프트, AI 디자인 도구</p>
<p><a style="background-color: #e6f5ff; color: #0070d1; text-align: start;" href="https://aboda.kr/entry/2025%EB%85%84-%EC%B5%9C%EC%8B%A0-AI-%EB%8F%84%EA%B5%AC-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%B4%9D%EC%A0%95%EB%A6%AC-PDF-%ED%8C%8C%EC%9D%BC%EB%A1%9C-%EB%B0%9B%EC%95%84%EA%B0%80%EC%84%B8%EC%9A%94" target="_blank" rel="noopener">2025.06.22 &#8211; [부동산/자동화 프로젝트] &#8211; 2025년 최신 AI 도구 리스트 총정리 (PDF 파일로 받아가세요!)</a></p>
<p><a href="https://2days.kr/11/07/08/64577/coding/">AI 가상 피팅 앱 &amp;#8216;Doppl&amp;#8217; 완전 해부! 구글이 만든 미래형 옷 입기 체험</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://i2.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-14-1024x1024.jpg?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>AI 가상 피팅 앱 &#8216;Doppl&#8217; 완전 해부! 구글이 만든 미래형 옷 입기 체험</title>
		<link>https://2days.kr/11/07/08/64577/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Thu, 10 Jul 2025 23:14:11 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64577</guid>

					<description><![CDATA[AI 가상 피팅 앱 &#8216;Doppl&#8217; 완전 해부! 구글이 만든 미래형 옷 입기 체험 여러분, 이제 온라인 쇼핑할 때 &#8216;이 옷이 나한테 어울릴까?&#8217; 걱정 안 해도 돼요. 단 한 장의 사진으로 내가 옷을 입은 모습을 미리 볼 수 있다면, 믿으시겠어요? 안녕하세요, 요즘 온라인 쇼핑 많이들 하시죠? 저도 요즘은 거의 택배로 옷을 주문하는데요, 항상 &#8220;핏이 어떨까, 사이즈 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="font-size: 1.1rem; line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;">AI 가상 피팅 앱 &#8216;Doppl&#8217; 완전 해부! 구글이 만든 미래형 옷 입기 체험 여러분, 이제 온라인 쇼핑할 때 &#8216;이 옷이 나한테 어울릴까?&#8217; 걱정 안 해도 돼요. 단 한 장의 사진으로 내가 옷을 입은 모습을 미리 볼 수 있다면, 믿으시겠어요?</p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">안녕하세요, 요즘 온라인 쇼핑 많이들 하시죠? 저도 요즘은 거의 택배로 옷을 주문하는데요, 항상 &#8220;핏이 어떨까, 사이즈 괜찮을까?&#8221; 고민이 많았어요. 그런데 최근에 정말 신기한 앱을 발견했답니다. 바로 구글이 만든 AI 가상 피팅 서비스, Doppl이에요. 딱 한 장의 전신 사진만으로 내가 원하는 옷을 &#8216;진짜 입은 것처럼&#8217; 보여주는 이 놀라운 앱을 직접 써보고 나서, 이건 꼭 블로그에 소개해야겠다고 생각했어요. 오늘은 Doppl 앱의 기능부터 활용법, 그리고 개인정보 보호까지, 제가 직접 체험한 느낌을 바탕으로 하나하나 자세히 알려드릴게요!</p>
<h3 style="line-height: 1.8; margin-bottom: 1.2em; color: #333333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size23"><b>AI 가상 피팅 앱 &#8216;Doppl&#8217; 완전 해부! 구글이 만든 미래형 옷 입기 체험</b></h3>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter">
<p><figure id="attachment_64578" aria-describedby="caption-attachment-64578" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64578 size-large" fifu-data-src="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1" alt="AI 가상 피팅 앱 &#039;Doppl&#039; 완전 해부! 구글이 만든 미래형 옷 입기 체험" width="696" height="380" loading="lazy" title="AI 가상 피팅 앱 &#039;Doppl&#039; 완전 해부! 구글이 만든 미래형 옷 입기 체험 6"><figcaption id="caption-attachment-64578" class="wp-caption-text">AI 가상 피팅 앱 &#8216;Doppl&#8217; 완전 해부! 구글이 만든 미래형 옷 입기 체험</figcaption></figure></figure>
<div style="background: linear-gradient(135deg, #f5f0ff, #f0e6ff); border-radius: 8px; padding: 20px; margin: 20px 0; box-shadow: 0 4px 10px rgba(106, 27, 154, 0.08); font-family: 'Noto Sans KR', sans-serif; border-left: 4px solid #9c27b0;">
<div style="margin-bottom: 15px;">
<h3 style="font-weight: bold; color: #4a148c; font-size: 18px; margin: 0;">목차</h3>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;"><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#what-is-doppl">Doppl이란 무엇인가요?</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#main-features">Doppl의 주요 기능 한눈에 보기</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#how-to-use">Doppl 사용법 가이드</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#privacy-policy">사진은 안전할까? 개인정보 처리 방식</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#user-feedback">실제 사용자 반응과 기술적 한계</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#future-of-doppl">Doppl의 미래와 한국 출시 기대</a></div>
</div>
<h2 id="what-is-doppl" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">Doppl이란 무엇인가요?</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">Doppl은 2025년 6월 26일, 구글이 Google Labs를 통해 실험적으로 출시한 <b>AI 기반 가상 피팅 앱</b>입니다. 한 장의 전신 사진만으로 사용자의 디지털 아바타를 생성하고, 여기에 원하는 옷 사진을 입히는 방식으로 작동해요. 특히 일반적인 착용 이미지뿐 아니라 <b>움직이는 동영상</b>까지 생성할 수 있어 실감 나는 피팅이 가능하다는 게 특징이죠. 사용자는 옷 사진을 직접 올릴 수 있고, SNS나 중고 거래 앱에서 가져온 이미지도 활용할 수 있어요. 지금은 미국에서만 사용 가능하지만, 향후 글로벌 출시도 예고되어 있어 기대를 모으고 있어요.</p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;"><a href="https://labs.google/doppl" target="_blank" rel="noopener noreferrer noopener">https://labs.google/doppl</a></p>
<figure id="og_1752188202018" contenteditable="false" data-ke-type="opengraph" data-ke-align="alignCenter" data-og-type="website" data-og-title="LABS.GOOGLE" data-og-description="Stay up to date with the latest Google AI experiments, innovative tools, and technology. Explore the future of AI responsibly with Google Labs." data-og-host="labs.google" data-og-source-url="https://labs.google/doppl" data-og-url="https://labs.google/" data-og-image="https://scrap.kakaocdn.net/dn/DRzzI/hyZjwLwD6V/mLbTtJDAN84xUUWznXhrzk/img.jpg?width=1074&amp;height=1074&amp;face=0_0_1074_1074,https://scrap.kakaocdn.net/dn/2B8HE/hyZjkqGqs7/v3nsrZt94WWbdaro35xDB1/img.jpg?width=1074&amp;height=1074&amp;face=0_0_1074_1074">
<div class="og-image"></div>
<div class="og-text">
<p class="og-title">LABS.GOOGLE</p>
<p class="og-desc">Stay up to date with the latest Google AI experiments, innovative tools, and technology. Explore the future of AI responsibly with Google Labs.</p>
<p class="og-host">labs.google</p>
</div>
</figure>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter">
<p></figure>
<h2 id="main-features" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">Doppl의 주요 기능 한눈에 보기</h2>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">기능</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">설명</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">가상 착용</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">전신 사진 하나로 AI가 디지털 아바타를 생성해 옷을 입혀줍니다.</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">영상 생성</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">실제 사람이 입은 듯한 자연스러운 움직임의 동영상 출력</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">이미지 활용</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">스크린샷, 중고 의류 사진 등 자유롭게 옷 이미지 업로드 가능</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">공유 및 저장</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">마음에 드는 룩을 저장하거나 SNS로 바로 공유 가능</td>
</tr>
</tbody>
</table>
<h2 id="how-to-use" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">Doppl 사용법 가이드</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">앱은 아직 미국에서만 다운로드가 가능하지만, 사용하는 방법은 아주 간단해요. 순서대로 따라 하면 누구나 쉽게 체험할 수 있어요.</p>
<ol style="margin-bottom: 1.2em; padding-left: 2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">Doppl 앱을 설치하고 실행합니다.</li>
<li style="margin-bottom: 0.5em; position: relative;">전신 사진을 업로드하거나 기본 AI 모델을 선택해요.</li>
<li style="margin-bottom: 0.5em; position: relative;">마음에 드는 옷 사진이나 스크린샷을 불러옵니다.</li>
<li style="margin-bottom: 0.5em; position: relative;">AI가 생성한 가상 착용 이미지 및 영상을 확인합니다.</li>
</ol>
<ul style="list-style-type: circle; color: #333333; text-align: start;" data-ke-list-type="circle">
<li style="list-style-type: circle;"><b>Ap</b><span style="color: #333333; text-align: left;"><b>p Store :</b> </span><a href="https://apps.apple.com/us/app/doppl-google/id6741596720" target="_blank" rel="noopener">https://apps.apple.com/us/app/doppl-google/id6741596720</a></li>
<li style="list-style-type: circle;"><b>Google Play :</b> <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.labs.glam" target="_blank" rel="noopener">https://play.google.com/store/apps/details?id=com.google.android.apps.labs.glam</a></li>
</ul>
<h2 id="privacy-policy" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">사진은 안전할까? 개인정보 처리 방식</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">요즘은 사진 하나만 올려도 개인정보가 유출될까 걱정이죠. 특히 얼굴과 몸 전체가 나온 전신 사진이라면 더욱 그렇구요. Doppl은 이 부분에서 꽤 철저한 정책을 갖추고 있어요. <b>업로드된 사진은 최대 90일간만 저장</b>되고, 사람이 보는 경우도 아주 일부, 식별 불가능한 상태에서만 검토된다고 합니다. 또한 <b>모든 데이터는 암호화 저장</b>되며, 사용자가 직접 앱 내에서 삭제할 수 있어요.</p>
<h2 id="user-feedback" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">실제 사용자 반응과 기술적 한계</h2>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; background-color: #9c27b0; color: white; font-weight: bold;">사용자 반응</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; background-color: #9c27b0; color: white; font-weight: bold;">의견 요약</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">긍정</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">“너무 신기하다”, “Z세대 감성 딱!”, “SNS에 올리기 좋음”</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">부정</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">“핏이 좀 부자연스러움”, “조금 어색한 부분 있음”</td>
</tr>
</tbody>
</table>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<h2 id="future-of-doppl" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">Doppl의 미래와 한국 출시 기대</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">지금은 미국에서만 이용 가능하지만, Doppl의 가능성은 무궁무진해요. 구글이 지속적으로 개선 중이고, 패션 시장이 큰 한국에서도 분명 활용도가 클 거라 예상됩니다. 특히 아래와 같은 측면에서 기대를 모으고 있어요.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">한국 쇼핑몰 연동으로 직접 구매 기능 추가 가능성</li>
<li style="margin-bottom: 0.5em; position: relative;">체형 데이터 기반 추천 알고리즘 고도화 예상</li>
<li style="margin-bottom: 0.5em; position: relative;">VR/AR 기술과의 결합으로 더 실감 나는 체험 가능</li>
</ul>
<div style="margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Doppl은 한국에서 쓸 수 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">아직은 미국 한정 서비스지만, 향후 다른 국가로 확장될 예정이에요.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 한국 정식 출시 일정은?</div>
<div style="margin-left: 32px;">
<p style="margin: 0; line-height: 1.6;">구체적인 일정은 발표되지 않았지만, 긍정적인 테스트 결과에 따라 빠른 도입이 기대됩니다.</p>
</div>
</div>
<div style="margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Doppl은 무료인가요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">네, 현재는 실험적 단계로 iOS와 Android 앱 모두 무료로 제공되고 있어요.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 결제 유도나 광고가 있나요?</div>
<div style="margin-left: 32px;">
<p style="margin: 0; line-height: 1.6;">현재로서는 없어요. 피드백 수집과 기술 개선에 집중 중이에요.</p>
</div>
</div>
<div style="margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 사진이 유출될 가능성은 없나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">모든 사진은 암호화되어 저장되며, 90일 이후 자동 삭제된다고 합니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 직접 삭제도 가능한가요?</div>
<div style="margin-left: 32px;">
<p style="margin: 0; line-height: 1.6;">네, 앱 내에서 언제든 삭제 가능하고, 계정 삭제 시 모든 데이터도 삭제돼요.</p>
</div>
</div>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">온라인 쇼핑이 점점 보편화되면서, 단순히 &#8216;이 옷 예쁘네&#8217;에서 끝나는 시대는 지난 것 같아요. 이제는 직접 입어본 것 같은 생생한 체험이 중요하죠. Doppl은 그런 면에서 정말 획기적인 앱이에요. 물론 아직 완벽하진 않지만, 기술의 발전 방향을 보여주는 강력한 신호탄이라고 생각해요. 앞으로 한국에서도 사용할 수 있게 된다면, 저도 자주 애용할 것 같아요. 혹시 Doppl에 대해 더 궁금한 점이나 직접 써보신 분들의 의견이 있다면 댓글로 공유해 주세요! 😊</p>
<p style="font-size: 0.95rem; color: #666; font-family: 'Noto Sans KR', sans-serif; margin-top: 2em;">doppl, 구글 랩스, 가상 피팅, ai 착용 앱, 온라인 쇼핑, 디지털 아바타, 구글 신기술, ai 스타일링, 패션 테크, 개인정보 보호</p>
<p><a href="https://aboda.kr/entry/2025%EB%85%84-%EC%B5%9C%EC%8B%A0-AI-%EB%8F%84%EA%B5%AC-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%B4%9D%EC%A0%95%EB%A6%AC-PDF-%ED%8C%8C%EC%9D%BC%EB%A1%9C-%EB%B0%9B%EC%95%84%EA%B0%80%EC%84%B8%EC%9A%94" target="_blank" rel="noopener">2025.06.22 &#8211; [부동산/자동화 프로젝트] &#8211; 2025년 최신 AI 도구 리스트 총정리 (PDF 파일로 받아가세요!)</a></p>
<p><a href="https://2days.kr/24/06/09/64171/coding/">AI 아바타 Hedra 무료 고퀄리티로 만들 수 있어!</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-53-1024x559.png?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기</title>
		<link>https://2days.kr/10/07/21/64569/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Thu, 10 Jul 2025 12:25:36 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64569</guid>

					<description><![CDATA[GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기 &#8220;GPT가 직접 Notion 데이터를 읽고 분석한다면?&#8221; 이제 그게 가능합니다. 실제 MCP 연동 예제로 확인해보세요! 안녕하세요! 요즘 AI와 외부 시스템의 연결이 점점 쉬워지고 있다는 거, 체감하고 계신가요? 저는 최근에 OpenAI의 GPT 모델과 MCP 서버를 연동해서 Notion 프로젝트 데이터를 실시간으로 조회하고 분석하는 기능을 직접 구현해봤어요. 처음엔 &#8220;이게 진짜 가능할까?&#8221; [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16"><span style="color: #000000;">GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기 &#8220;GPT가 직접 Notion 데이터를 읽고 분석한다면?&#8221; 이제 그게 가능합니다. 실제 MCP 연동 예제로 확인해보세요!</span></p>
<p style="line-height: 1.8; margin-bottom: 1.2em; color: #333333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">안녕하세요! 요즘 AI와 외부 시스템의 연결이 점점 쉬워지고 있다는 거, 체감하고 계신가요? 저는 최근에 OpenAI의 GPT 모델과 MCP 서버를 연동해서 Notion 프로젝트 데이터를 실시간으로 조회하고 분석하는 기능을 직접 구현해봤어요. 처음엔 &#8220;이게 진짜 가능할까?&#8221; 싶었는데, 막상 해보니 생각보다 훨씬 자연스럽고 파워풀했습니다. 오늘은 그 구현 과정을 단계별로 소개해보려고 해요. 저처럼 혼자서 AI 실험하는 분들이라면, 분명 흥미롭게 보실 수 있을 거예요!</p>
<h3 style="line-height: 1.8; margin-bottom: 1.2em; color: #333333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size23"><b>GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기</b></h3>
<figure id="attachment_64573" aria-describedby="caption-attachment-64573" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64573 size-large" fifu-data-src="https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1" alt="GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기" width="696" height="380" loading="lazy" title="GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기 8"><figcaption id="caption-attachment-64573" class="wp-caption-text">GPT와 MCP 연동 Notion을 분석하는 AI 도구 만들기</figcaption></figure>
<div style="background: linear-gradient(135deg, #f5f0ff, #f0e6ff); border-radius: 8px; padding: 20px; margin: 20px 0; box-shadow: 0 4px 10px rgba(106, 27, 154, 0.08); font-family: 'Noto Sans KR', sans-serif; border-left: 4px solid #9c27b0;">
<div style="margin-bottom: 15px;">
<h3 style="font-weight: bold; color: #4a148c; font-size: 18px; margin: 0;" data-ke-size="size23">목차</h3>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;"><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#overview">GPT와 MCP 연동의 개요</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#toolcall-streaming">Tool Call과 Streaming API 작동 방식</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#preparation">OpenAI API 키와 Notion 토큰 준비</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#environment-setup">MCP 개발 환경 구성 및 uv 사용법</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#notion-analysis">GPT로 Notion 프로젝트 분석하기</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#expandability">확장 가능성과 향후 활용 아이디어</a></div>
</div>
<h2 id="overview" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size26">GPT와 MCP 연동의 개요</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">GPT가 단순히 질문에 답하는 걸 넘어서 실제 시스템과 상호작용하게 된다면 어떨까요? 바로 그걸 가능하게 해주는 게 MCP(Model Context Protocol)입니다. 이 MCP 서버는 GPT로부터 도구 호출 요청을 받고, 외부 시스템(Notion 등)과 연결해주는 중간 브릿지 역할을 해요. 이 글에서는 MCP 서버를 Python 기반 FastAPI로 구성하고, Gradio 인터페이스를 통해 GPT와 사용자 간 실시간 대화를 구현하는 구조를 소개합니다.</p>
<h2 id="toolcall-streaming" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size26">Tool Call과 Streaming API 작동 방식</h2>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; background-color: #9c27b0; color: white;">기능명</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; background-color: #9c27b0; color: white;">제공 주체</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; background-color: #9c27b0; color: white;">설명</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Tool Call</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">OpenAI</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">GPT가 외부 function을 자동 호출하는 기능. JSON 기반 인자 생성</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Streaming 응답 (GPT)</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">OpenAI</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">GPT 응답을 실시간 스트리밍으로 받기 위한 옵션 (stream=True)</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Streaming 응답 (MCP)</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">FastMCP</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">MCP 실행 결과를 text/event-stream 형식으로 실시간 전달</td>
</tr>
</tbody>
</table>
<h2 id="preparation" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size26">OpenAI API 키와 Notion 토큰 준비</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">이 시스템을 구현하기 위해선 기본적으로 두 가지 인증 키가 필요합니다. 하나는 GPT API를 호출하기 위한 OpenAI API Key, 다른 하나는 Notion 프로젝트 데이터에 접근하기 위한 Integration Token입니다. 이 키들은 <code style="background-color: #f5f5f5; padding: 0.2em 0.4em; border-radius: 3px; font-family: 'Consolas', 'Monaco', monospace; font-size: 0.9em; color: #6a1b9a;">.env</code> 파일에 저장해서 외부 노출 없이 안전하게 사용합니다.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-list-type="disc">
<li style="margin-bottom: 0.5em; position: relative;">OpenAI API Key: OpenAI 플랫폼에서 직접 생성</li>
<li style="margin-bottom: 0.5em; position: relative;"><b>OpenAI API 키 발급</b> (➡️ <a style="color: #0070d1;" href="https://platform.openai.com/api-keys" target="_blank" rel="noopener">OpenAI 플랫폼에서 발급</a>)</li>
<li style="margin-bottom: 0.5em; position: relative;">OpenAI 플랫폼 접속</li>
<li style="margin-bottom: 0.5em; position: relative;">로그인 후 상단 메뉴에서 <b>“API keys”</b> 탭 클릭</li>
<li style="margin-bottom: 0.5em; position: relative;"><b>“Create new secret key”</b> 버튼을 눌러 API 키 생성</li>
<li style="margin-bottom: 0.5em; position: relative;">발급된 <b>Secret Key를 복사하여 안전한 곳에 저장</b><br />
※ 이 키는 <u>.env 파일에 사용되며, 외부에 노출되지 않도록 주의하세요.</u></li>
<li style="margin-bottom: 0.5em; position: relative;">Notion Integration Token: <span style="background-color: #ffffff; color: #1f2328; text-align: left;">(➡️</span><span style="background-color: #ffffff; color: #1f2328; text-align: left;"> </span><a style="background-color: #ffffff; color: #0070d1; text-align: left;" href="https://www.notion.so/profile/integrations" target="_blank" rel="noopener">Notion 개발자 포털에서 발급</a><span style="background-color: #ffffff; color: #1f2328; text-align: left;">)</span></li>
<li style="margin-bottom: 0.5em; position: relative;">Notion 개발자 포털사이트 접속</li>
<li style="margin-bottom: 0.5em; position: relative;">&#8220;새로운 통합(New integration)”<span style="background-color: #ffffff; color: #333333; text-align: left;"> 버튼 클릭</span></li>
<li style="margin-bottom: 0.5em; position: relative;">API 통합 설정 구성 -&gt; 사용 권한 -&gt; 페이지 선택에서 페이지 선택 -&gt; 사용 권한 업데이트 순서로 설정<br />
<span style="background-color: #ffffff; color: #333333; text-align: left;">※ 이 과정에서 선택된 페이지(또는 데이터베이스)에 접근 가능하게 됩니다.</span></li>
<li style="margin-bottom: 0.5em; position: relative;">생성된 <b>Internal Integration Token (프라이빗 API 통합 시트릿)</b>을 복사<br />
※ <span style="background-color: #ffffff; color: #1f2328; text-align: left;">이 키는 <u>.env 파일에 사용되며, 외부에 노출되지 않도록 주의하세요.</u></span></li>
</ul>
<h2 id="environment-setup" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size26">MCP 개발 환경 구성 및 uv 사용법</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">실제 연동을 구현하기 위해서는 Python 개발 환경 설정이 먼저 필요해요. 저는 최근에 <b>uv</b>라는 새로운 패키지 관리 도구를 사용했는데, pip보다 빠르고 효율적이더라고요. 아래 표처럼 구성하면 MCP 서버를 쉽게 셋업할 수 있어요.</p>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white;">환경 구성</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white;">버전</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">운영체제</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Windows 11</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Python</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">3.10.17</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">uv</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">0.6.14</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">fastmcp</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">2.8.1</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h4 style="color: #000000; text-align: start;" data-ke-size="size20"><b>[uv 설치] </b><b><span style="color: #006dd7;">(선택사항)</span></b></h4>
<p style="color: #333333; text-align: start;" data-ke-size="size16" data-start="67" data-end="193">MCP 서버를 Python 환경에서 구성할 때, 패키지 및 가상환경 관리를 위해 uv를 사용하는 것을 권장합니다. uv는 pip과 venv를 대체할 수 있는 <b>더 빠르고 효율적인 패키지 관리 도구</b>입니다. 아래 명령어로 간단히 설치할 수 있습니다.</p>
<p style="color: #333333; text-align: start;" data-ke-size="size16" data-start="67" data-end="193">
<i>※ 선택사항이지만, 향후 개발 및 의존성 관리를 고려하면 설치하는 것을 추천드립니다.</i></p>
<ul style="list-style-type: disc; color: #333333; text-align: start;" data-ke-list-type="disc">
<li style="list-style-type: disc;"><b>uv 깃허브 </b>: <a href="https://github.com/astral-sh/uv" target="_blank" rel="noopener">https://github.com/astral-sh/uv</a></li>
</ul>
<pre id="code_1752149444091" class="hljs mipsasm" style="color: #333333; text-align: start;" contenteditable="false" data-ke-language="bash" data-ke-type="codeblock"><span class="hljs-comment"># Windows PowerShell</span>
powershell -ExecutionPolicy <span class="hljs-keyword">ByPass </span>-c <span class="hljs-string">"irm https://astral.sh/uv/install.ps1 | iex"</span></pre>
<h4 style="color: #000000; text-align: start;" data-ke-size="size20"><b>[가상 환경 생성] <span style="color: #006dd7;">(선택사항)</span></b></h4>
<p style="color: #333333; text-align: start;" data-ke-size="size16">uv 설치가 완료되면, 프로젝트 디렉토리를 초기화하고 가상환경을 생성한 뒤 필요한 패키지를 설치합니다. 가상환경을 사용하는 것을 권장하며, 아래 명령어를 순서대로 실행해 주세요.</p>
<pre id="code_1752149444093" class="hljs jboss-cli" style="color: #333333; text-align: start;" contenteditable="false" data-ke-language="python" data-ke-type="codeblock"><span class="hljs-comment"># Windows PowerShell</span>
<span class="hljs-keyword">cd</span> \path\to\mcp                  <span class="hljs-comment"># 1. 원하는 작업 디렉토리로 이동 (예: D:\mcp)</span>
uv init notion_mcp               <span class="hljs-comment"># 2. 'notion_mcp' uv 프로젝트 폴더 생성</span>
<span class="hljs-keyword">cd</span> gpt_mcp_toolcaller_gradio     <span class="hljs-comment"># 3. 생성된 프로젝트 폴더로 이동</span>
uv venv <span class="hljs-params">--python=python3</span>.10      <span class="hljs-comment"># 4. Python 3.10 기반 가상환경 생성 (.venv 디렉토리 생성)</span>
<span class="hljs-string">.venv</span>\Scripts\activate           <span class="hljs-comment"># 5. 가상환경 활성화 (Windows 기준)</span></pre>
<h3 style="color: #000000; text-align: start;" data-ke-size="size23"><b>코드 및 필요 패키지 다운로드</b></h3>
<p style="color: #333333; text-align: start;" data-ke-size="size16">OpenAI API와 MCP 서버가 연동된 예제 코드를 아래 깃허브에서 제공하고 있습니다. 해당 코드를 다운로드하고 압축을 푼 후, <u>위에서 생성한 gpt_mcp_toolcaller_gradio 폴더 내로 파일을 이동</u>해 줍니다.</p>
<ul style="list-style-type: disc; color: #333333; text-align: start;" data-ke-list-type="disc">
<li style="list-style-type: disc;"><b>깃허브 :</b> <a href="https://github.com/AIMIZING/gpt_mcp_toolcaller_gradio" target="_blank" rel="noopener">https://github.com/AIMIZING/gpt_mcp_toolcaller_gradio</a></li>
</ul>
<p style="color: #333333; text-align: start;" data-end="351" data-start="326" data-ke-size="size16">이제 <b>가상환경을 활성화한 상태에서</b>, 아래 명령어를 실행해 프로젝트에 필요한 패키지를 설치합니다.</p>
<p style="color: #333333; text-align: start;" data-end="351" data-start="326" data-ke-size="size16">※ 가상환경을 사용하지 않는 경우에도, 동일한 명령어로 시스템 환경에 설치할 수 있습니다.</p>
<pre id="code_1752149444097" class="hljs applescript" style="color: #333333; text-align: start;" contenteditable="false" data-ke-type="codeblock" data-ke-language="python"><span class="hljs-comment"># Windows PowerShell</span>
cd \path\<span class="hljs-keyword">to</span>\notion_mcp\gpt_mcp_toolcaller_gradio  <span class="hljs-comment"># 깃허브에서 다운로드한 폴더</span>
uv pip install .                                  <span class="hljs-comment"># 필요한 패키지 설치</span></pre>
<blockquote style="color: #666666; text-align: left;" data-ke-style="style2" data-end="351" data-start="326"><p><b>📌 주의:</b> 프로젝트 폴더(gpt_mcp_toolcaller_gradio)는 반드시 notion_mcp 폴더 내부에 위치해야 합니다. uv는 루트 기준으로 .venv를 자동 인식하기 때문에 디렉토리 구조를 유지하는 것이 중요합니다.</p></blockquote>
<h3 style="color: #000000; text-align: start;" data-ke-size="size23"><b>환경 설정</b></h3>
<p style="color: #333333; text-align: start;" data-end="351" data-start="326" data-ke-size="size16">gpt_mcp_toolcaller_gradio 폴더(깃허브에서 받은 코드) 안에는 환경 변수를 관리하기 위한 <b>.env 파일</b>이 포함되어 있습니다.<br />
이 파일을 메모장 등 텍스트 편집기로 열어, 내부에 있는 <b>OpenAI API 키와 Notion 토큰</b> 값을 본인의 것으로 수정합니다.</p>
<pre id="code_1752149444099" class="hljs ini" style="color: #333333; text-align: start;" contenteditable="false" data-ke-type="codeblock" data-ke-language="python"><span class="hljs-comment"># .env 파일</span>
<span class="hljs-attr">OPENAI_API_KEY</span>=your_openai_api_key  <span class="hljs-comment"># 이 부분은 실제 api key로 변경해야합니다.</span>
<span class="hljs-attr">NOTION_TOKEN</span>=your_notion_token      <span class="hljs-comment"># 이 부분은 실제 notion_token으로 변경해야합니다.</span></pre>
<p style="color: #333333; text-align: start;" data-end="351" data-start="326" data-ke-size="size16">※ <span style="color: #ee2323;"><u><span style="color: #333333;">이 </span>API 키와 토큰은 <b>개인 인증 정보</b>이므로 절대 외부에 노출되면 안 됩니다.</u></span></p>
<h3 style="color: #000000; text-align: start;" data-ke-size="size23"><b>Notion 프로젝트 분석 요청</b></h3>
<p style="color: #333333; text-align: start;" data-ke-size="size16" data-start="326" data-end="351">이제 모든 준비가 완료되었습니다. 아래 명령어를 실행하여 <b>MCP 서버를 먼저 구동</b>하고, 이후 <b>Gradio 인터페이스를 통해 GPT에게 Notion 프로젝트 분석을 요청</b>할 수 있습니다.</p>
<p style="color: #333333; text-align: start;" data-ke-size="size16" data-start="326" data-end="351"><b>[MCP 서버 실행]</b></p>
<pre id="code_1752149444102" class="hljs applescript" style="color: #333333; text-align: start;" contenteditable="false" data-ke-type="codeblock" data-ke-language="python"><span class="hljs-comment"># Windows PowerShell (1)</span>
cd \path\<span class="hljs-keyword">to</span>\notion_mcp\gpt_mcp_toolcaller_gradio  <span class="hljs-comment"># 깃허브에서 다운로드한 폴더</span>
python notion_mcp_server.py                       <span class="hljs-comment"># MCP 서버 실행</span></pre>
<p style="color: #333333; text-align: start;" data-ke-size="size16" data-start="376" data-end="499">MCP 서버가 정상적으로 실행되면, 아래와 같이 &#8220;Uvicorn running on http://0.0.0.0:8000&#8221; 문구가 출력됩니다. 이는 서버가 성공적으로 구동되어 요청을 받을 준비가 되었다는 의미입니다.</p>
<blockquote style="color: #666666; text-align: left;" data-ke-style="style2" data-start="376" data-end="499">
</blockquote>
<p style="color: #333333; text-align: start;" data-end="351" data-start="326" data-ke-size="size16"><b>[Gradio 인터페이스 실행 (GPT모델)]</b></p>
<p style="color: #333333; text-align: start;" data-end="351" data-start="326" data-ke-size="size16">이제 MCP 서버가 실행된 상태에서, GPT와 연동되는 Gradio 인터페이스를 실행해보겠습니다. 아래 명령어를 입력하여 Gradio 앱을 실행합니다.</p>
<pre id="code_1752149444106" class="hljs applescript" style="color: #333333; text-align: start;" contenteditable="false" data-ke-type="codeblock" data-ke-language="python"><span class="hljs-comment"># Windows PowerShell (2)</span>
cd \path\<span class="hljs-keyword">to</span>\notion_mcp\gpt_mcp_toolcaller_gradio  <span class="hljs-comment"># 깃허브에서 다운로드한 폴더</span>
python gpt_mcp_toolcaller_gradio.py               <span class="hljs-comment"># GPT Gradio 실행</span></pre>
<p style="color: #333333; text-align: start;" data-ke-size="size16" data-end="499" data-start="376">Gradio가 정상적으로 실행되면, 아래와 같이 &#8220;Running on local URL:  http://127.0.0.1:7860&#8221; 문구가 출력됩니다. 이 주소를 통해 Gradio 웹을 실행할 수 있습니다.</p>
<p style="color: #333333; text-align: start;" data-ke-size="size16">Gradio 웹 페이지가 정상적으로 실행되었다면, 이제 GPT에게 <b>Notion 프로젝트와 관련된 질문</b>을 직접 해볼 수 있습니다. 아래와 같이 예시 프롬프트를 입력했습니다.</p>
<h2 id="notion-analysis" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size26">GPT로 Notion 프로젝트 분석하기</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">이제 진짜 마법이 시작됩니다. Gradio 인터페이스를 통해 GPT에게 다음과 같은 프롬프트를 던졌어요:</p>
<p><mark style="background-color: #e1bee7; color: #6a1b9a; padding: 0 3px; border-radius: 2px; font-family: 'Noto Sans KR', sans-serif;">&#8220;내 노션 프로젝트 목록 확인해줘.&#8221;</mark></p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">그러자 GPT는 즉시 Tool Call을 통해 MCP 서버를 호출했고, Notion 데이터가 실시간으로 반환됐죠. 이때 주요 기능은 다음과 같아요.</p>
<ol style="margin-bottom: 1.2em; padding-left: 2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-list-type="decimal">
<li style="margin-bottom: 0.5em; position: relative;">프로젝트 목록 실시간 조회</li>
<li style="margin-bottom: 0.5em; position: relative;">진행률, 우선순위, 마감일 통계 분석</li>
<li style="margin-bottom: 0.5em; position: relative;">분석 결과 요약 및 추천</li>
</ol>
<h2 id="expandability" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size26">확장 가능성과 향후 활용 아이디어</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">이번 구현 경험을 통해 GPT는 단순한 대화형 모델을 넘어서 <b>외부 시스템과 상호작용하는 AI 에이전트</b>로 완전히 진화할 수 있다는 걸 느꼈어요. 다음은 제가 실제로 시도해보고 싶은 확장 아이디어들이에요:</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-list-type="disc">
<li style="margin-bottom: 0.5em; position: relative;">캘린더, 메일, 드라이브 등 타 시스템 연동</li>
<li style="margin-bottom: 0.5em; position: relative;">리스크 예측, 일정 지연 자동 감지 등 고급 분석 도구 추가</li>
<li style="margin-bottom: 0.5em; position: relative;">멀티턴 대화 흐름 최적화 및 프롬프트 파이프라인 설계</li>
</ul>
<div style="margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> GPT와 MCP는 꼭 함께 사용해야 하나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;" data-ke-size="size16">아니요, GPT는 단독으로도 훌륭하지만, MCP를 활용하면 외부 시스템 연동이 가능해져 확장성이 훨씬 높아집니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Tool Call은 어떤 방식으로 작동하나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;" data-ke-size="size16">GPT가 질문을 해석해 적절한 도구를 선택하고 JSON 인자를 자동 생성하여 호출합니다. 사용자는 따로 호출 코드를 작성하지 않아도 됩니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Streaming API를 꼭 사용해야 하나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;" data-ke-size="size16">필수는 아니지만, 사용하면 응답을 실시간으로 받을 수 있어 Tool Call 발생 시점을 감지하거나 반응속도를 높이기에 유리합니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Notion 외에도 연동 가능한 시스템이 있을까요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;" data-ke-size="size16">물론입니다. Google 캘린더, Gmail, Slack, 파일 시스템 등 다양한 REST API 기반 외부 시스템과 연동이 가능합니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Gradio 없이도 구현할 수 있나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;" data-ke-size="size16">네, Gradio는 인터페이스 구현 도구일 뿐이며, FastAPI나 Flask 기반의 웹 앱, 또는 데스크탑 UI로도 충분히 구현 가능합니다.</p>
</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> MCP 서버 운영 시 보안 문제는 없나요?</div>
<div style="margin-left: 32px;">
<p style="margin: 0; line-height: 1.6;" data-ke-size="size16">서버는 API 키 및 토큰을 환경 변수로 관리하므로 노출 위험이 줄어들지만, HTTPS 적용, 접근 제한, 토큰 주기적 갱신 등 추가 보안 조치가 필수입니다.</p>
</div>
</div>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16">여기까지 따라오신 여러분, 정말 대단하세요! 😊 GPT와 MCP를 연동해서 Notion 데이터를 분석하는 여정이 쉽지는 않았을 거예요. 하지만 한번 구조를 만들어놓으면 생각보다 많은 일이 자동화되고, 확장 가능성도 무궁무진해집니다. 저도 처음엔 반신반의했지만, 직접 연결해보고 나니 정말 게임 체인저라는 느낌이 들었어요. 앞으로는 더 다양한 시스템과 연결해서 GPT를 진짜 ‘도구를 쓰는 AI’로 진화시켜볼 예정이에요. 여러분도 도전해보세요! 혹시 막히는 부분이 있거나 더 해보고 싶은 게 있다면 댓글로 꼭 남겨주세요.</p>
<p style="font-size: 0.95rem; color: #6a1b9a; font-family: 'Noto Sans KR', sans-serif; margin-top: 2em;" data-ke-size="size16">AI연동, GPT도구호출, MCP서버, OpenAIAPI, ToolCall, StreamingAPI, 노션자동화, 외부도구연동, Gradio인터페이스, 파이썬개발</p>
<p><a href="https://aboda.kr/entry/MCPModel-Context-Protocol%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80" target="_blank" rel="noopener">2025.03.16 &#8211; [분류 전체보기] &#8211; MCP(Model Context Protocol)란 무엇인가?</a></p>
<p><a href="https://2days.kr/19/06/08/63872/aboda/">챗GPT (Chatgpt) AI 개인비서 만들기 </a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://i3.wp.com/2days.kr/wp-content/uploads/2025/07/Image_fx-5-1024x559.png?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>오라클 클라우드 무료 인스턴스로 개인 서버 시작하기</title>
		<link>https://2days.kr/08/07/08/64510/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Mon, 07 Jul 2025 23:38:53 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64510</guid>

					<description><![CDATA[오라클 클라우드 무료 인스턴스로 개인 서버 시작하기 무료로 VPS 서버를 만들 수 있다면? 오라클 클라우드의 퍼포먼스를 체험해보세요! 안녕하세요! 요즘 퍼스널 프로젝트를 위해 서버 하나쯤 갖고 싶은 분들 많으시죠? 저도 이번에 마침 블로그 백엔드를 직접 운영해보고 싶어서 VPS를 알아보다가, 우연히 오라클 클라우드 무료 인스턴스를 발견했어요. 다른 서비스랑 비교해봤는데, 이게 생각보다 꽤 괜찮더라구요. 특히 비용 걱정 없이 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="line-height: 1.8; margin-bottom: 1.2em; color: #6a1b9a; font-weight: 500; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size16"><span style="color: #000000;">오라클 클라우드 무료 인스턴스로 개인 서버 시작하기 무료로 VPS 서버를 만들 수 있다면? 오라클 클라우드의 퍼포먼스를 체험해보세요!</span></p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">안녕하세요! 요즘 퍼스널 프로젝트를 위해 서버 하나쯤 갖고 싶은 분들 많으시죠? 저도 이번에 마침 블로그 백엔드를 직접 운영해보고 싶어서 VPS를 알아보다가, 우연히 오라클 클라우드 무료 인스턴스를 발견했어요. 다른 서비스랑 비교해봤는데, 이게 생각보다 꽤 괜찮더라구요. 특히 비용 걱정 없이 성능 좋은 인스턴스를 계속 사용할 수 있다는 점이 정말 매력적이었어요. 그래서 오늘은 오라클 클라우드 무료 티어로 나만의 서버를 만드는 방법과 SSH로 접속하는 법까지 차근차근 공유해볼게요!</p>
<h3 style="line-height: 1.8; margin-bottom: 1.2em; color: #333333; font-family: 'Noto Sans KR', sans-serif;" data-ke-size="size23"><b>오라클 클라우드 무료 인스턴스로 개인 서버 시작하기</b></h3>
<figure id="attachment_64522" aria-describedby="caption-attachment-64522" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64522 size-large" fifu-data-src="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1" alt="오라클 클라우드 무료 인스턴스로 개인 서버 시작하기" width="696" height="696" loading="lazy" title="오라클 클라우드 무료 인스턴스로 개인 서버 시작하기 10"><figcaption id="caption-attachment-64522" class="wp-caption-text">오라클 클라우드 무료 인스턴스로 개인 서버 시작하기</figcaption></figure>
<div style="background: linear-gradient(135deg, #f5f0ff, #f0e6ff); border-radius: 8px; padding: 20px; margin: 20px 0; box-shadow: 0 4px 10px rgba(106, 27, 154, 0.08); font-family: 'Noto Sans KR', sans-serif; border-left: 4px solid #9c27b0;">
<div style="margin-bottom: 15px;">
<h3 style="font-weight: bold; color: #4a148c; font-size: 18px; margin: 0;">목차</h3>
</div>
<div style="display: flex; flex-direction: column; gap: 10px;"><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#oracle-free-tier">오라클 무료 인스턴스란?</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#account-type">무료 계정과 유료 계정의 차이</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#instance-limit">무료 인스턴스 구성 한도 정리</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#create-instance">오라클 인스턴스 생성하기</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#connect-ssh">SSH로 인스턴스 접속하는 방법</a><a style="color: #6a1b9a; text-decoration: none; font-weight: 500;" href="#bonus-tips">터미널 작업에 유용한 추가 팁</a></div>
</div>
<h2 id="oracle-free-tier" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">오라클 무료 인스턴스란?</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">오라클 클라우드는 퍼블릭 클라우드 중에서도 꽤나 후한 무료 티어를 제공하는 서비스예요. <b>&#8216;Forever Free&#8217;</b>라는 이름처럼, 유료로 전환하지 않아도 기본 인스턴스를 계속 무료로 쓸 수 있다는 게 핵심이죠. AWS나 Azure와 비교해도 꽤 괜찮은 사양의 VM을 제공해주기 때문에 개발자들 사이에서 입소문이 나기 시작했어요.</p>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;"><a href="https://signup.cloud.oracle.com/" target="_blank" rel="noopener noreferrer noopener">https://signup.cloud.oracle.com/</a></p>
<h2 id="account-type" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">무료 계정과 유료 계정의 차이</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">오라클 클라우드를 가입하면 처음에 $300 크레딧이 들어온 Trial 계정을 받게 되는데요, 이건 30일간 유료 기능을 테스트할 수 있는 일시적인 상태예요. 이 기간이 지나면 &#8216;업그레이드&#8217; 버튼만 눌러 유료 계정으로 전환할 수 있는데, 실제로 비용이 청구되진 않고</p>
<p><mark style="background-color: #e1bee7; color: #6a1b9a; padding: 0 3px; border-radius: 2px; font-family: 'Noto Sans KR', sans-serif;">Forever Free 리소스만 사용하는 한 과금은 발생하지 않아요</mark></p>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">계정 타입</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">제공 조건</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left; background-color: #9c27b0; color: white; font-weight: bold;">주의사항</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left;">Trial 계정</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left;">$300 크레딧, 30일간</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left;">기간 만료 후 종료됨</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left;">유료 계정 (무료 티어)</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left;">신용카드 등록만으로 전환</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em; text-align: left;">무료 리소스 초과 시 과금</td>
</tr>
</tbody>
</table>
<h2 id="instance-limit" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">무료 인스턴스 구성 한도 정리</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">이 부분이 핵심이에요. 아무리 무료라 해도 리소스 제한은 존재하니까요. 잘 구성하면 서버 2~3대를 돌릴 수 있을 만큼 넉넉합니다. 아래는 가장 효율적인 무료 구성 예시예요.</p>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">E2.Micro (x86) 인스턴스 2대 – 각각 부트볼륨 75GB 구성</li>
<li style="margin-bottom: 0.5em; position: relative;">A1.Flex (ARM) 인스턴스 1대 – 4 OCPU + 24GB 메모리, 부트볼륨 50GB 기본값</li>
<li style="margin-bottom: 0.5em; position: relative;">총합 약 190 GiB 사용 – 무료 한도(200GiB) 안전하게 관리 가능</li>
</ul>
<h2 id="create-instance" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">오라클 인스턴스 생성하기</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">먼저 오라클 클라우드 대시보드에 로그인한 후, <b>&#8220;인스턴스 생성&#8221;</b> 버튼을 클릭합니다. 운영체제는 <b>우분투 20.04</b>를 추천드려요. 안정적이고 서버 용도로 가장 널리 사용되니까요. VM 타입은 <b>VM.Standard.A1.Flex</b>를 선택하고, 4 OCPU, 24GB 메모리로 구성해보세요.</p>

<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">다음 단계로 넘어가면 SSH 키 페어를 생성하게 되는데, 반드시</p>
<p><mark style="background-color: #e1bee7; color: #6a1b9a; padding: 0 3px; border-radius: 2px; font-family: 'Noto Sans KR', sans-serif;">프라이빗 키와 퍼블릭 키를 미리 저장</mark><mark style="background-color: #e1bee7; color: #6a1b9a; padding: 0 3px; border-radius: 2px; font-family: 'Noto Sans KR', sans-serif;"></mark></p>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter">
<p></figure>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">해두세요. 이게 없으면 나중에 접속을 못 하니까요. 그리고 부트볼륨은 <b>사용자 정의 OFF</b>로 설정해야 무료입니다.</p>
<h2 id="connect-ssh" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">SSH로 인스턴스 접속하는 방법</h2>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">SSH 접속은 Termius 같은 GUI 기반 클라이언트를 쓰면 훨씬 편리합니다. 먼저 Keychain 탭에서 <b>Private Key를 업로드</b>하고, Public Key는 복사해서 붙여넣습니다. 이후 Host 탭으로 이동해 오라클 인스턴스의 퍼블릭 IP를 입력하세요.</p>
<table style="width: 100%; border-collapse: collapse; margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;" data-ke-align="alignLeft">
<thead>
<tr>
<th style="border: 1px solid #e1bee7; padding: 0.5em; background-color: #9c27b0; color: white; font-weight: bold;">단계</th>
<th style="border: 1px solid #e1bee7; padding: 0.5em; background-color: #9c27b0; color: white; font-weight: bold;">설정 내용</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">1</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Termius에서 Keychain 열기</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">2</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">다운로드한 프라이빗 키 업로드</td>
</tr>
<tr>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">3</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Host 탭에서 퍼블릭 IP 입력</td>
</tr>
<tr style="background-color: #f3e5f5;">
<td style="border: 1px solid #e1bee7; padding: 0.5em;">4</td>
<td style="border: 1px solid #e1bee7; padding: 0.5em;">Key 설정에서 업로드한 키 선택</td>
</tr>
</tbody>
</table>
<h2 id="bonus-tips" style="font-size: 1.8rem; font-weight: bold; color: #4a148c; margin-top: 1.5em; margin-bottom: 0.8em; line-height: 1.2; border-left: 5px solid #9c27b0; padding-left: 0.8em; font-family: 'Noto Sans KR', sans-serif;">터미널 작업에 유용한 추가 팁</h2>
<ul style="margin-bottom: 1.2em; padding-left: 2em; list-style-type: none; color: #333; font-family: 'Noto Sans KR', sans-serif;">
<li style="margin-bottom: 0.5em; position: relative;">tmux 설치: SSH 연결 끊김에도 작업 유지 가능</li>
<li style="margin-bottom: 0.5em; position: relative;">screen 사용법 익히기: 복수 세션 분리 작업 가능</li>
<li style="margin-bottom: 0.5em; position: relative;">Termius 계정 연동 시 다른 디바이스에서도 설정 공유 가능</li>
</ul>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter">
<p></figure>
<div style="margin: 1.5em 0; font-family: 'Noto Sans KR', sans-serif;">
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 오라클 클라우드는 왜 무료인가요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">클라우드 시장에서 점유율을 높이기 위한 마케팅 전략입니다. 개발자 유입을 위한 &#8216;Forever Free&#8217; 제공이 핵심입니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 유지 조건이 까다롭지 않고, 기본 사용량 안에서 제한 없이 쓸 수 있습니다.</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Trial이 끝나면 무조건 유료 전환해야 하나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">아니요. Trial 기간 이후에 직접 &#8216;업그레이드&#8217; 버튼을 누르기 전까진 유료 전환되지 않습니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 무료 리소스를 사용 중이면 그대로 유지 가능합니다.</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> SSH 키를 잃어버리면 어떻게 하나요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">재접속이 불가능해질 수 있어 인스턴스를 삭제하고 새로 만들어야 할 수도 있습니다. 반드시 백업해 두세요.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> 백업은 필수! 구글 드라이브나 외장 디스크에 저장해두세요.</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> Termius 없이도 접속 가능한가요?</div>
<div style="margin-left: 32px; margin-bottom: 1em;">
<p style="margin: 0; line-height: 1.6;">네, PuTTY나 Mac/Linux의 기본 터미널에서도 접속 가능합니다. 다만 키 경로와 퍼미션 설정이 필요합니다.</p>
</div>
<div style="font-weight: bold; color: #6a1b9a; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #6a1b9a; color: white; border-radius: 50%; margin-right: 8px;">A</span> Termius는 초보자에게 직관적이라 추천드리는 거예요.</div>
<div style="font-weight: bold; color: #9c27b0; margin-bottom: 0.5em; font-size: 1.1rem;"><span style="display: inline-block; width: 24px; height: 24px; line-height: 24px; text-align: center; background-color: #9c27b0; color: white; border-radius: 50%; margin-right: 8px;">Q</span> 퍼블릭 IP가 바뀌는 경우는 없나요?</div>
<div style="margin-left: 32px;">
<p style="margin: 0; line-height: 1.6;">정적 IP가 아닌 이상, 인스턴스를 중지 후 재시작하면 변경될 수 있습니다. 고정 IP가 필요하면 &#8216;Reserved Public IP&#8217; 설정을 하세요.</p>
</div>
</div>
<p style="font-size: 1rem; line-height: 1.8; margin-bottom: 1.2em; color: #333; font-family: 'Noto Sans KR', sans-serif;">지금까지 오라클 클라우드 무료 인스턴스를 만들어보고 SSH로 접속하는 방법까지 알아봤는데요, 어떠셨나요? 저처럼 처음 VPS나 클라우드 서버에 도전하는 분들에게 이만한 연습용 환경도 없다고 생각해요. <b>무료인데도 성능이 좋고, 실수해도 부담이 없는</b> 이 플랫폼을 활용해서 여러분만의 서버 환경을 만들어보세요! 만약 궁금한 점이 있다면 댓글로 남겨주세요. 같이 이야기 나눠봐요</p>
<p style="font-size: 0.95rem; line-height: 1.6; color: #666; font-family: 'Noto Sans KR', sans-serif; margin-top: 2em;">oracle cloud, 오라클 무료 인스턴스, vps 무료 서버, 리눅스 서버 만들기, termius ssh 접속, 우분투 서버 설치, 개인 서버 구축, 오라클 클라우드 계정, 클라우드 무료 티어, a1 flex 인스턴스</p>
<p style="font-size: 0.95rem; line-height: 1.6; color: #666; font-family: 'Noto Sans KR', sans-serif; margin-top: 2em;"><a style="background-color: #e6f5ff; color: #0070d1; text-align: start;" href="https://aboda.kr/entry/Claude-%ED%81%B4%EB%A1%9C%EB%93%9C-MCP-%EC%99%84%EB%B2%BD-%EC%84%A4%EC%B9%98-%EB%B0%8F-%ED%99%9C%EC%9A%A9-%EA%B0%80%EC%9D%B4%EB%93%9C-%EC%95%8C%EC%95%84-%EB%B3%BC%EA%B2%8C%EC%9A%94" target="_blank" rel="noopener">2025.03.31 &#8211; [분류 전체보기] &#8211; Claude 클로드 MCP 완벽 설치 및 활용 가이드 알아 볼게요</a></p>
<p><a href="https://2days.kr/28/08/21/46771/lifestyle/whats-hot/">애드센스 호스팅 서버에 연결할 수 없음 정책 센터 문제 해결 방법</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://i1.wp.com/2days.kr/wp-content/uploads/2025/07/제목을-입력해주세요__-복사본-001-11-1024x1024.jpg?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>완전 무료 자동화 블로그 어떻게 만드는지 다 알려주는 시리즈 (1/n)</title>
		<link>https://2days.kr/24/06/17/64194/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Tue, 24 Jun 2025 08:30:07 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64194</guid>

					<description><![CDATA[완전 무료 자동화 블로그 어떻게 만드는지 다 알려주는 시리즈 (1/n) 블로그 이미지 생성 및 삽입에 드는 시간을 획기적으로 줄이는 방법이 있을까? 그것도 무료로? 모두 사용할 수 있도록 최종 버전에는 무료로 배포할 생각이예요! N8N, Google Gemini, Unsplash API를 연동하여 AI 기반의 블로그 이미지 자동화 워크플로우를 구축하는 모든 과정을 단계별로 상세히 설명하는 완벽 가이드입니다. 초보자도 쉽게 따라 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="9:1-9:182">완전 무료 자동화 블로그 어떻게 만드는지 다 알려주는 시리즈 (1/n) 블로그 이미지 생성 및 삽입에 드는 시간을 획기적으로 줄이는 방법이 있을까? 그것도 무료로? 모두 사용할 수 있도록 최종 버전에는 무료로 배포할 생각이예요!</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="9:1-9:182">N8N, Google Gemini, Unsplash API를 연동하여 AI 기반의 블로그 이미지 자동화 워크플로우를 구축하는 모든 과정을 단계별로 상세히 설명하는 완벽 가이드입니다. 초보자도 쉽게 따라 할 수 있도록 스크린샷과 설정 예시를 풍부하게 담았습니다.</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="15:1-15:149">디지털 콘텐츠의 홍수 속에서 독자의 시선을 사로잡고 검색 엔진에서 상위 노출되기 위해서는 고품질의 콘텐츠뿐만 아니라, <b>매력적인 시각 자료</b>가 필수적입니다. 하지만 매번 블로그 글에 맞는 이미지를 찾고, 생성하고, 삽입하는 과정은 엄청난 시간과 노력을 요구합니다.</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="17:1-17:213">이러한 반복적인 작업을 자동화할 수 있다면 어떨까요? 여기 그 해답이 있습니다. 이 상세 매뉴얼에서는 <b>N8N이라는 강력한 워크플로우 자동화 도구와 Google의 최신 AI 모델인 Gemini, 그리고 방대한 무료 이미지 라이브러리인 Unsplash API를 연동하여 블로그 이미지를 자동으로 생성하고 게시물에 삽입하는 일련의 과정을 완벽하게 마스터</b>할 수 있도록 도와드립니다.</p>
<h2 data-sourcepos="17:1-17:213"><strong>완전 무료 자동화 블로그 어떻게 만드는지 다 알려주는 시리즈 (1/n)</strong></h2>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter"><figcaption>
<figure id="attachment_64196" aria-describedby="caption-attachment-64196" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64196 size-large" fifu-data-src="https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1" alt="완전 무료 자동화 블로그 어떻게 만드는지 다 알려주는 시리즈 (1/n)" width="696" height="696" loading="lazy" title="완전 무료 자동화 블로그 어떻게 만드는지 다 알려주는 시리즈 (1/n) 14"><figcaption id="caption-attachment-64196" class="wp-caption-text">완전 무료 자동화 블로그 어떻게 만드는지 다 알려주는 시리즈 (1/n)</figcaption></figure>
</figcaption></figure>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="19:1-19:168">이 가이드는 단순히 &#8216;어떻게&#8217; 하는지뿐만 아니라 &#8216;왜&#8217; 그렇게 하는지, 그리고 각 단계에서 발생할 수 있는 문제와 해결책까지 다루어, 여러분이 이 워크플로우를 성공적으로 구축하고 효율성을 극대화할 수 있도록 지원할 것입니다. 지금부터 AI 기반 블로그 이미지 자동화의 세계로 깊이 들어가 보겠습니다!</p>
<h3 style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="23:1-23:57" data-ke-size="size23"><b>1단계: Google Gemini 노드를 활용한 블로그 이미지 설명 생성 (AI의 상상력 활용) &#8211; </b><b>무료 자동화 블로그</b></h3>

<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="25:1-25:220">모든 자동화의 시작은 AI에게 어떤 이미지가 필요한지 정확히 알려주는 것입니다. 이 단계에서는 Google Gemini AI의 강력한 텍스트 생성 능력을 활용하여, 블로그 게시물의 특정 섹션에 맞는 상세한 이미지 설명을 얻습니다. 이 설명은 단순히 &#8220;사과&#8221;가 아니라, &#8220;빛이 잘 드는 주방 식탁 위에 놓인 신선하고 붉은 사과, 배경은 블러 처리되고 따뜻한 색감&#8221;과 같이 구체적인 지침이 됩니다.</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="27:1-27:23"><b>1.1. 노드 추가 및 기본 설정:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="29:3-31:0" data-ke-list-type="disc">
<li data-sourcepos="29:3-29:56"><b>노드 유형:</b> N8N 워크플로우 캔버스에 Google Gemini 노드를 추가합니다.</li>
<li data-sourcepos="30:3-31:0"><b>노드 이름:</b> 가독성을 위해 Google Gemini (Generate Image Descriptions) 정도로 이름을 변경하는 것을 권장합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="32:1-32:29"><b>1.2. 인증 (Authentication):</b></p>

<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="34:3-37:0" data-ke-list-type="disc">
<li data-sourcepos="34:3-34:125">Authentication 드롭다운에서 Google OAuth2 API 또는 Google Cloud Service Account를 선택합니다. 대부분의 경우 Google OAuth2 API가 간편합니다.</li>
<li data-sourcepos="35:3-37:0"><b>Google Credential:</b> 아직 설정하지 않았다면 Create New를 클릭하여 Google Cloud Console에서 발급받은 API Key (또는 OAuth 클라이언트 ID)를 설정합니다. Gemini API 사용을 위해서는 generativelanguage.googleapis.com에 대한 접근 권한이 필요합니다.
<ul style="list-style-type: disc;" data-sourcepos="36:7-37:0" data-ke-list-type="disc">
<li data-sourcepos="36:7-37:0"><b>Tip:</b> API Key를 사용하는 경우 x-goog-api-key 헤더를 통해 안전하게 전달됩니다. (사용자가 이전에 제시한 image_5c109c.png에서 이 설정이 보였습니다.)</li>
</ul>
</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="38:1-38:24"><b>1.3. 작업 (Operation):</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="40:3-41:0" data-ke-list-type="disc">
<li data-sourcepos="40:3-41:0">Operation을 Generate Content로 설정합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="42:1-42:20"><b>1.4. 모델 (Model):</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="44:3-45:0" data-ke-list-type="disc">
<li data-sourcepos="44:3-45:0">Model 드롭다운에서 gemini-pro (텍스트 생성)를 선택합니다. 이미지 생성은 아니므로 gemini-pro-vision은 적합하지 않습니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="46:1-46:26"><b>1.5. 프롬프트 (Prompt) 구성:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="48:3-65:0" data-ke-list-type="disc">
<li data-sourcepos="48:3-48:115">Prompt 필드에 Gemini가 이미지 설명을 생성할 수 있도록 명확하고 구체적인 지시를 내립니다. 이 프롬프트는 이전 노드 (예: 블로그 글을 생성한 노드)에서 받은 데이터를 참조해야 합니다.</li>
<li data-sourcepos="49:3-65:0"><b>예시 (텍스트 기반 블로그 글을 입력으로 받을 때):</b>
<div>
<div style="background-color: #f0f4f9;">
<div>
<pre class="hljs sql" contenteditable="false">You are an AI assistant specialized in generating visual image descriptions for blog posts.
For the following blog section content, provide a concise, vivid, and detailed image description that visually represents the key theme.
The description should be formatted as a numbered list, <span class="hljs-keyword">with</span> <span class="hljs-keyword">each</span> item <span class="hljs-keyword">starting</span> <span class="hljs-keyword">with</span> <span class="hljs-string">"숫자. **설명N: [이미지 설명]**"</span> format.
Focus <span class="hljs-keyword">on</span> elements suitable <span class="hljs-keyword">for</span> image <span class="hljs-keyword">search</span> (e.g., objects, <span class="hljs-keyword">settings</span>, mood, colors, composition).

<span class="hljs-keyword">Content</span>:
{{ $json.blog_section_content }} // 이전 노드의 출력 데이터 (블로그 섹션 내용)

Example <span class="hljs-keyword">Output</span> <span class="hljs-keyword">Format</span>:
<span class="hljs-number">1.</span> **설명<span class="hljs-number">1</span>: AI 편향성을 시각적으로 보여주는 이미지.** 다양한 인종과 성별의 얼굴 이미지가 여러 개의 박스 안에 배치되어 있고, 각 박스는 AI 얼굴 인식 정확도(예: <span class="hljs-number">95</span>%, <span class="hljs-number">70</span>%, <span class="hljs-number">80</span>%)를 나타내는 숫자와 함께, 정확도가 낮은 그룹의 박스는 어둡게 표현된다. 이미지 하단에는 <span class="hljs-string">"AI Bias: Unfair Outcomes"</span> 와 같은 문구를 추가하여 AI 편향성의 부정적 결과를 강조한다. 색상은 차갑고 어두운 색조를 사용하여 불안정함을 시각적으로 표현한다.
<span class="hljs-number">2.</span> **설명<span class="hljs-number">2</span>: 데이터 프라이버시 침해를 묘사하는 이미지.** 한 사람의 실루엣 주변으로 수많은 데이터 포인트(점, 선 등)가 뻗어나가는 모습을 묘사한다. 데이터 포인트들은 다양한 기기(스마트폰, 컴퓨터, CCTV 등)에서 방출되는 것처럼 표현하고, 실루엣의 얼굴은 모자이크 처리하여 익명성을 강조한다. 배경은 어둡고 신비로운 분위기를 연출하며, <span class="hljs-string">"Data Privacy at Risk"</span> 와 같은 문구를 추가하여 위험성을 부각한다.
</pre>
</div>
</div>
</div>
<ul style="list-style-type: disc;" data-sourcepos="63:7-65:0" data-ke-list-type="disc">
<li data-sourcepos="63:7-63:139"><b>{{ $json.blog_section_content }}:</b> 이 부분은 N8N의 표현식(Expression)으로, 이전 노드에서 전달받은 블로그 섹션 내용을 동적으로 가져옵니다. 실제 사용하는 변수명에 맞게 조정해야 합니다.</li>
<li data-sourcepos="64:7-65:0"><b>Gemini에게 출력 형식 가이드 제공:</b> Gemini가 정확히 우리가 원하는 &#8220;숫자. **설명N: [이미지 설명]**&#8221; 형식으로 응답하도록 명시적인 예시를 제공하는 것이 중요합니다. (이전 대화에서 이 형식을 통해 성공적으로 설명을 얻으셨습니다.)</li>
</ul>
</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="66:1-66:16"><b>1.6. 노드 테스트:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="68:3-70:0" data-ke-list-type="disc">
<li data-sourcepos="68:3-68:41">노드를 저장하고, Test Node 버튼을 클릭하여 실행합니다.</li>
<li data-sourcepos="69:3-70:0">Output 탭에서 Gemini가 생성한 이미지 설명이 예상한 JSON 형식으로 출력되는지 확인합니다. 이 출력은 보통 output 필드 내에 문자열로 포함됩니다.</li>
</ul>
<h3 style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="73:1-73:59"><b>2단계: Function 노드를 활용한 이미지 키워드 추출 및 정제 (Unsplash 검색 최적화) </b><b>무료 자동화 블로그</b></h3>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="75:1-75:160">Gemini가 생성한 상세 설명은 훌륭하지만, Unsplash와 같은 이미지 검색 엔진은 주로 간결하고 핵심적인 키워드에 최적화되어 있습니다. 이 단계에서는 N8N의 Function 노드를 사용하여 자바스크립트 코드로 이미지 설명 텍스트에서 검색 가능한 키워드를 추출하고 정제합니다.</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="77:1-77:20"><b>2.1. 노드 추가 및 연결:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="79:3-81:0" data-ke-list-type="disc">
<li data-sourcepos="79:3-79:77">Google Gemini (Generate Image Descriptions) 노드 뒤에 Function 노드를 추가합니다.</li>
<li data-sourcepos="80:3-81:0"><b>노드 이름:</b> Function (Extract Image Descriptions &amp; Keywords)로 이름을 변경합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="82:1-82:37"><b>2.2. Function 노드 코드 (JavaScript):</b></p>
<div>
<div style="background-color: #f0f4f9;">
<div>
<pre class="hljs javascript" contenteditable="false"><span class="hljs-keyword">const</span> outputItems = [];

<span class="hljs-comment">// --- 입력 데이터 유효성 검사 및 텍스트 추출 ---</span>
<span class="hljs-keyword">let</span> rawInputText = <span class="hljs-string">''</span>;

<span class="hljs-comment">// 첫 번째 아이템이 유효한지 확인하고, 'output' 속성에서 텍스트를 가져옵니다.</span>
<span class="hljs-keyword">if</span> (items &amp;&amp; items.length &gt; <span class="hljs-number">0</span> &amp;&amp; items[<span class="hljs-number">0</span>].json &amp;&amp; items[<span class="hljs-number">0</span>].json.output) {
    rawInputText = items[<span class="hljs-number">0</span>].json.output;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Function Node - Successfully extracted text from items[0].json.output.'</span>);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Function Node - Raw Input Text (first 200 chars):'</span>, rawInputText.substring(<span class="hljs-number">0</span>, <span class="hljs-built_in">Math</span>.min(rawInputText.length, <span class="hljs-number">200</span>)) + <span class="hljs-string">'...'</span>);
}
<span class="hljs-comment">// 잘못된 입력 (이미 파싱된 데이터가 들어온 경우 등)</span>
<span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">'Function Node - No valid text found in expected input path (items[0].json.output).'</span>);
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">'Function Node - Input JSON:'</span>, <span class="hljs-built_in">JSON</span>.stringify(items, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>)); <span class="hljs-comment">// 입력 JSON 전체를 로그에 출력하여 확인</span>
    <span class="hljs-keyword">return</span> []; <span class="hljs-comment">// 잘못된 입력이므로 빈 배열 반환</span>
}

<span class="hljs-comment">// --- 이미지 설명 블록 분리 ---</span>
<span class="hljs-comment">// 정규식을 사용하여 '숫자. **제목: 내용**' 패턴으로 시작하는 각 설명 블록을 분리합니다.</span>
<span class="hljs-keyword">const</span> descriptionBlockRegex = <span class="hljs-regexp">/(\d+\.\s*\*\*[^*]+?\*\*:\s*.*?)((?=\d+\.\s*\*\*)|$)/g</span>s;
<span class="hljs-keyword">let</span> match;
<span class="hljs-keyword">let</span> imageIndex = <span class="hljs-number">0</span>;
<span class="hljs-keyword">const</span> processedItems = [];

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Function Node - Starting description block parsing...'</span>);

<span class="hljs-keyword">while</span> ((match = descriptionBlockRegex.exec(rawInputText)) !== <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">const</span> fullDescription = match[<span class="hljs-number">1</span>].trim(); <span class="hljs-comment">// 예: "1. **설명1: AI 편향성...**"</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`  Debug - Found fullDescription (Index <span class="hljs-subst">${imageIndex + <span class="hljs-number">1</span>}</span>):`</span>, fullDescription.substring(<span class="hljs-number">0</span>, <span class="hljs-built_in">Math</span>.min(fullDescription.length, <span class="hljs-number">150</span>)) + <span class="hljs-string">'...'</span>);

    <span class="hljs-keyword">if</span> (fullDescription) {
        imageIndex++;
        <span class="hljs-keyword">const</span> imagePrompt = fullDescription; <span class="hljs-comment">// 전체 설명을 image_prompt로 사용</span>

        <span class="hljs-comment">// --- 키워드 추출 및 정제 로직 ---</span>
        <span class="hljs-keyword">let</span> imageKeywords = <span class="hljs-string">''</span>;
        <span class="hljs-keyword">const</span> keywordCaptureRegex = <span class="hljs-regexp">/\*\*(.+?)\*\*:/</span>; <span class="hljs-comment">// ** 와 **: 사이의 텍스트를 추출</span>
        <span class="hljs-keyword">const</span> keywordMatch = fullDescription.match(keywordCaptureRegex);

        <span class="hljs-keyword">if</span> (keywordMatch &amp;&amp; keywordMatch[<span class="hljs-number">1</span>]) {
            imageKeywords = keywordMatch[<span class="hljs-number">1</span>].trim();
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'    Debug - Raw extracted keywords from bold (Step 1):'</span>, imageKeywords);

            <span class="hljs-comment">// "설명N: " 패턴이 있다면 제거 (예: "설명1: AI 편향성 시각적 이미지" -&gt; "AI 편향성 시각적 이미지")</span>
            <span class="hljs-keyword">const</span> parts = imageKeywords.split(<span class="hljs-string">':'</span>);
            <span class="hljs-keyword">if</span> (parts.length &gt; <span class="hljs-number">1</span> &amp;&amp; parts[<span class="hljs-number">0</span>].startsWith(<span class="hljs-string">'설명'</span>)) {
                imageKeywords = parts.slice(<span class="hljs-number">1</span>).join(<span class="hljs-string">':'</span>).trim();
            }
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'    Debug - After "설명N:" removal (Step 2):'</span>, imageKeywords);

            <span class="hljs-comment">// 불필요한 구두점 및 추가 공백 제거</span>
            imageKeywords = imageKeywords
                .replace(<span class="hljs-regexp">/[.!?,"'()]/g</span>, <span class="hljs-string">''</span>) <span class="hljs-comment">// 마침표, 물음표, 느낌표, 쉼표, 따옴표, 괄호 제거</span>
                .replace(<span class="hljs-regexp">/\s+/g</span>, <span class="hljs-string">' '</span>) <span class="hljs-comment">// 여러 공백을 하나의 공백으로</span>
                .trim();
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'    Debug - After punctuation/space cleanup (Step 3):'</span>, imageKeywords);

            <span class="hljs-comment">// 불필요한 한국어 조사, 어미, 불용어 제거 (정규식 사용)</span>
            <span class="hljs-comment">// '인한' 등 불필요한 단어 추가</span>
            imageKeywords = imageKeywords.replace(<span class="hljs-regexp">/을|를|이|가|은|는|도|만|에|에서|와|과|랑|하고|으로써|으로|에게|께|한테|부터|까지|마저|조차|처럼|만큼|듯이|하고는|거나|든지|다시|모두|같이|인한|시각적|보여주|묘사하|나타내/g</span>, <span class="hljs-string">''</span>).trim();
            imageKeywords = imageKeywords.replace(<span class="hljs-regexp">/\s+/g</span>, <span class="hljs-string">' '</span>).trim(); <span class="hljs-comment">// 조사 제거 후 남은 불필요 공백 제거</span>
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'    Debug - After Korean suffix/particle removal (Step 4):'</span>, imageKeywords);

            <span class="hljs-comment">// Unsplash 검색에 불필요한 일반적인 단어 제거 (소문자로 비교)</span>
            <span class="hljs-keyword">const</span> commonWordsToRemove = [
                <span class="hljs-string">'시각적으로'</span>, <span class="hljs-string">'보여주는'</span>, <span class="hljs-string">'나타내는'</span>, <span class="hljs-string">'묘사하는'</span>, <span class="hljs-string">'상징적으로'</span>, <span class="hljs-string">'표현한'</span>, <span class="hljs-string">'이미지'</span>, <span class="hljs-string">'사진'</span>, <span class="hljs-string">'개념'</span>, <span class="hljs-string">'상징'</span>, <span class="hljs-string">'표현'</span>,
                <span class="hljs-string">'대한'</span>, <span class="hljs-string">'관련된'</span>, <span class="hljs-string">'모습'</span>, <span class="hljs-string">'그림'</span>, <span class="hljs-string">'일러스트'</span>, <span class="hljs-string">'상세'</span>, <span class="hljs-string">'설명'</span>, <span class="hljs-string">'주제'</span>, <span class="hljs-string">'내용'</span>, <span class="hljs-string">'위한'</span>
            ];
            imageKeywords = imageKeywords.split(<span class="hljs-string">' '</span>).filter(<span class="hljs-function"><span class="hljs-params">word</span> =&gt;</span> {
                <span class="hljs-keyword">const</span> lowerWord = word.toLowerCase();
                <span class="hljs-keyword">return</span> !commonWordsToRemove.includes(lowerWord) &amp;&amp; lowerWord.length &gt; <span class="hljs-number">1</span>; <span class="hljs-comment">// 1글자 키워드도 제거</span>
            }).join(<span class="hljs-string">' '</span>);
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'    Debug - After common word removal (Step 5):'</span>, imageKeywords);

            <span class="hljs-comment">// 최종적으로 공백을 쉼표로 변환 (Unsplash 검색을 위해)</span>
            imageKeywords = imageKeywords.replace(<span class="hljs-regexp">/\s+/g</span>, <span class="hljs-string">', '</span>);
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'    Debug - Final image_keywords for Unsplash (Step 6):'</span>, imageKeywords);

        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">`    Debug - Could not find bold text (**...**:) for keywords in: <span class="hljs-subst">${fullDescription.substring(<span class="hljs-number">0</span>, <span class="hljs-built_in">Math</span>.min(fullDescription.length, <span class="hljs-number">50</span>))}</span>...`</span>);
            imageKeywords = <span class="hljs-string">''</span>; <span class="hljs-comment">// 추출 실패 시 빈 문자열</span>
        }
        <span class="hljs-comment">// --- 키워드 추출 및 정제 로직 끝 ---</span>

        processedItems.push({
            <span class="hljs-attr">json</span>: {
                <span class="hljs-attr">image_prompt</span>: imagePrompt,
                <span class="hljs-attr">image_keywords</span>: imageKeywords,
                <span class="hljs-attr">image_index</span>: imageIndex <span class="hljs-comment">// 이미지 순서 (선택 사항)</span>
            }
        });
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`  Function Node - Added item (Index <span class="hljs-subst">${imageIndex}</span>): Prompt [<span class="hljs-subst">${imagePrompt.substring(<span class="hljs-number">0</span>, <span class="hljs-number">30</span>)}</span>...], Keywords [<span class="hljs-subst">${imageKeywords || 'EMPTY'}</span>]`</span>);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">'  Debug - fullDescription was empty after match, skipping item.'</span>);
    }
}

<span class="hljs-keyword">if</span> (processedItems.length === <span class="hljs-number">0</span>) {
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">'Function Node - No output items generated. Please review input text format and regex patterns.'</span>);
}

<span class="hljs-keyword">return</span> processedItems;
</pre>
</div>
</div>
</div>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="190:1-190:22"><b>2.3. 코드 상세 설명 및 팁:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="192:3-202:0" data-ke-list-type="disc">
<li data-sourcepos="192:3-192:124"><b>items 배열 처리:</b> N8N의 Function 노드는 이전 노드의 데이터를 items라는 전역 변수에 배열 형태로 전달받습니다. 각 아이템은 json 속성 내에 실제 데이터를 가지고 있습니다.</li>
<li data-sourcepos="193:3-195:101"><b>정규식 (Regex)의 중요성:</b>
<ul style="list-style-type: disc;" data-sourcepos="194:7-195:101" data-ke-list-type="disc">
<li data-sourcepos="194:7-194:226">descriptionBlockRegex: Gemini의 출력 형식에 맞춰 각 이미지 설명을 개별적인 블록으로 분리하는 데 사용됩니다. (\d+\.\s*\*\*[^*]+?\*\*:\s*.*?)((?=\d+\.\s*\*\*)|$) 패턴은 &#8220;숫자. **제목:** 내용&#8221;으로 시작하는 부분을 정확히 잡아내고, 다음 숫자 시작 지점까지 또는 문자열 끝까지를 하나의 블록으로 인식합니다.</li>
<li data-sourcepos="195:7-195:101">keywordCaptureRegex: /\*\*(.+?)\*\*:/ 이 정규식은 **와 **: 사이의 텍스트를 추출하여 이미지의 핵심 키워드를 얻습니다.</li>
</ul>
</li>
<li data-sourcepos="196:3-198:80"><b>한국어 조사/어미 제거 (Step 4):</b> 이 부분은 한국어 특성상 중요한 정제 과정입니다.
<ul style="list-style-type: disc;" data-sourcepos="197:7-198:80" data-ke-list-type="disc">
<li data-sourcepos="197:7-197:151">imageKeywords.replace(/을|를|이|가|은|는|도|만|에|에서|와|과|랑|하고|으로써|으로|에게|께|한테|부터|까지|마저|조차|처럼|만큼|듯이|하고는|거나|든지|다시|모두|같이|인한|시각적|보여주|묘사하|나타내/g, &#8221;).trim();</li>
<li data-sourcepos="198:7-198:80">여기에 <b>시각적|보여주|묘사하|나타내</b> 등 실제 추출 결과에서 나타났던 어미나 형태들을 추가하여 더욱 정교하게 제거합니다.</li>
</ul>
</li>
<li data-sourcepos="199:3-199:123"><b>불용어(Stop Words) 제거 (Step 5):</b> commonWordsToRemove 배열에 &#8220;이미지&#8221;, &#8220;사진&#8221;, &#8220;묘사하는&#8221; 등 검색에 불필요한 일반적인 단어들을 추가하여 검색 효율을 높입니다.</li>
<li data-sourcepos="200:3-200:169"><b>console.log 디버깅:</b> 코드에 포함된 수많은 console.log 문은 N8N의 Execution Log 탭에서 실행 과정을 단계별로 추적할 수 있게 해줍니다. 키워드 추출이 제대로 되지 않을 때 이 로그를 통해 어느 단계에서 문제가 발생하는지 쉽게 파악할 수 있습니다.</li>
<li data-sourcepos="201:3-202:0"><b>출력 형식:</b> 각 이미지 설명에 대해 { json: { image_prompt: &#8220;&#8230;&#8221;, image_keywords: &#8220;&#8230;&#8221;, image_index: N } } 형태의 개별 아이템을 생성하여 다음 노드로 전달합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="203:1-203:16"><b>2.4. 노드 테스트:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="205:3-208:0" data-ke-list-type="disc">
<li data-sourcepos="205:3-205:106">Google Gemini (Generate Image Descriptions) 노드를 먼저 Test Node로 실행하여 Function 노드에 올바른 입력이 오도록 합니다.</li>
<li data-sourcepos="206:3-206:88">그 다음, Function (Extract Image Descriptions &amp; Keywords) 노드를 Test Node로 실행합니다.</li>
<li data-sourcepos="207:3-208:0">Output 탭과 Execution Log 탭을 면밀히 확인하여, 각 아이템마다 image_prompt와 image_keywords가 의도대로 추출되었는지 검토합니다.</li>
</ul>
<h3 style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="211:1-211:59" data-ke-size="size23"><b>3단계: HTTP Request 노드를 통한 Unsplash 이미지 검색 (방대한 라이브러리 활용) 무료 자동화 블로그</b></h3>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="213:1-213:110">이제 잘 정제된 키워드를 사용하여 Unsplash의 방대한 이미지 라이브러리에서 블로그에 적합한 이미지를 검색할 차례입니다. HTTP Request 노드는 외부 API와 통신하는 데 사용됩니다.</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="215:1-215:20"><b>3.1. 노드 추가 및 연결:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="217:3-219:0" data-ke-list-type="disc">
<li data-sourcepos="217:3-217:90">Function (Extract Image Descriptions &amp; Keywords) 노드 뒤에 HTTP Request 노드를 추가합니다.</li>
<li data-sourcepos="218:3-219:0"><b>노드 이름:</b> HTTP Request (Unsplash Search)로 이름을 변경합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="220:1-220:29"><b>3.2. 인증 (Authentication):</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="222:3-223:0" data-ke-list-type="disc">
<li data-sourcepos="222:3-223:0">Authentication: None으로 설정합니다. Unsplash API는 Client ID를 URL 파라미터로 받기 때문에 별도의 인증 헤더가 필요하지 않습니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="224:1-224:32"><b>3.3. 요청 방식 (Request Method):</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="226:3-227:0" data-ke-list-type="disc">
<li data-sourcepos="226:3-227:0">Method: GET으로 설정합니다. 이미지를 검색하는 것은 데이터를 조회하는 것이므로 GET 요청이 적합합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="228:1-228:18"><b>3.4. URL (경로):</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="230:3-231:0" data-ke-list-type="disc">
<li data-sourcepos="230:3-231:0">URL: <a href="https://api.unsplash.com/search/photos" target="_blank" rel="noopener">https://api.unsplash.com/search/photos</a> 를 입력합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="232:1-232:47"><b>3.5. 쿼리 파라미터 (Query Parameters) 설정 (매우 중요):</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="234:3-257:0" data-ke-list-type="disc">
<li data-sourcepos="234:3-257:0">Query Parameters 섹션에서 Add Parameter 버튼을 클릭하여 필요한 파라미터들을 추가합니다.
<ul style="list-style-type: disc;" data-sourcepos="235:7-257:0" data-ke-list-type="disc">
<li data-sourcepos="235:7-238:167"><b>Parameter 1 (검색어):</b>
<ul style="list-style-type: disc;" data-sourcepos="236:11-238:167" data-ke-list-type="disc">
<li data-sourcepos="236:11-236:27">Name: query</li>
<li data-sourcepos="237:11-238:167">Value: {{ $json.image_keywords }}
<ul style="list-style-type: disc;" data-sourcepos="238:15-238:167" data-ke-list-type="disc">
<li data-sourcepos="238:15-238:167"><b>Explanation:</b> {{ $json.image_keywords }}는 이전 Function 노드에서 추출한 각 아이템의 image_keywords 값을 동적으로 가져와 query 파라미터로 사용합니다. 이 부분이 정확한 이미지 검색의 핵심입니다.</li>
</ul>
</li>
</ul>
</li>
<li data-sourcepos="239:7-248:76"><b>Parameter 2 (Client ID):</b>
<ul style="list-style-type: disc;" data-sourcepos="240:11-248:76" data-ke-list-type="disc">
<li data-sourcepos="240:11-240:31">Name: client_id</li>
<li data-sourcepos="241:11-248:76">Value: [당신의 Unsplash Access Key]
<ul style="list-style-type: disc;" data-sourcepos="242:15-248:76" data-ke-list-type="disc">
<li data-sourcepos="242:15-242:159"><b>Explanation:</b> Unsplash 개발자 계정에서 발급받은 고유한 Access Key를 여기에 직접 붙여넣습니다. 이 키는 Unsplash API를 호출할 수 있는 권한을 부여합니다. <b>이 키는 외부에 노출되지 않도록 주의해야 합니다.</b></li>
<li data-sourcepos="243:15-248:76"><b>Unsplash Access Key 얻는 방법 (재차 강조):</b>
<ol style="list-style-type: decimal;" data-sourcepos="244:17-248:76" data-ke-list-type="decimal">
<li data-sourcepos="244:17-244:117">Unsplash Developers 웹사이트 (<a href="https://unsplash.com/developers" target="_blank" rel="noopener">https://unsplash.com/developers</a>) 방문.</li>
<li data-sourcepos="245:17-245:32">로그인 또는 회원가입.</li>
<li data-sourcepos="246:17-246:70">&#8220;Your apps&#8221; 또는 &#8220;New Application&#8221; 클릭하여 새 애플리케이션 생성.</li>
<li data-sourcepos="247:17-247:69">약관 동의 및 앱 설명 작성 (예: &#8220;N8N Blog Image Automation&#8221;).</li>
<li data-sourcepos="248:17-248:76">생성된 앱 페이지에서 <b>&#8220;Access Key&#8221;</b> (또는 Client ID)를 확인하고 복사합니다.</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li data-sourcepos="249:7-252:216"><b>Parameter 3 (페이지당 결과 수 &#8211; 권장 1개):</b>
<ul style="list-style-type: disc;" data-sourcepos="250:11-252:216" data-ke-list-type="disc">
<li data-sourcepos="250:11-250:30">Name: per_page</li>
<li data-sourcepos="251:11-252:216">Value: 1
<ul style="list-style-type: disc;" data-sourcepos="252:15-252:216" data-ke-list-type="disc">
<li data-sourcepos="252:15-252:216"><b>Explanation:</b> 블로그 게시물 각 섹션에 대해 하나의 대표 이미지만 필요한 경우가 많으므로 1로 설정하는 것이 효율적입니다. Unsplash API는 per_page의 최대값을 30으로 제한합니다. 240을 입력하셨더라도 실제로는 30개까지만 반환됩니다. 한 번에 여러 이미지를 가져와 선택하고 싶다면 더 높은 값을 설정할 수 있습니다.</li>
</ul>
</li>
</ul>
</li>
<li data-sourcepos="253:7-257:0"><b>Parameter 4 (이미지 방향 &#8211; 선택 사항):</b>
<ul style="list-style-type: disc;" data-sourcepos="254:11-257:0" data-ke-list-type="disc">
<li data-sourcepos="254:11-254:33">Name: orientation</li>
<li data-sourcepos="255:11-257:0">Value: landscape (가로형 이미지를 선호하는 경우) 또는 portrait (세로형), squarish (정사각형) 등
<ul style="list-style-type: disc;" data-sourcepos="256:15-257:0" data-ke-list-type="disc">
<li data-sourcepos="256:15-257:0"><b>Explanation:</b> 블로그 레이아웃에 맞춰 이미지의 방향을 지정하여 검색 결과를 필터링할 수 있습니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="258:1-258:33"><b>3.6. 응답 형식 (Response Format):</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="260:3-261:0" data-ke-list-type="disc">
<li data-sourcepos="260:3-261:0">Response Format: JSON (기본값)으로 설정되어 있는지 확인합니다. Unsplash API는 JSON 형식으로 결과를 반환합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="262:1-262:16"><b>3.7. 노드 테스트:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="264:3-266:0" data-ke-list-type="disc">
<li data-sourcepos="264:3-264:73">HTTP Request (Unsplash Search) 노드를 클릭하고 Test Node 버튼을 클릭하여 실행합니다.</li>
<li data-sourcepos="265:3-266:0">Output 탭에서 Unsplash API로부터 받은 JSON 응답을 확인합니다. results 배열 안에 검색된 이미지들의 정보가 잘 들어있는지 확인하는 것이 중요합니다. total, total_pages, results 배열이 정상적으로 보이는지 확인하세요.</li>
</ul>
<h3 style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="269:1-269:46" data-ke-size="size23"><b>4단계: Set 노드를 활용한 최종 이미지 URL 추출 (게시물 삽입 준비) </b><b>무료 자동화 블로그</b></h3>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="271:1-271:152">Unsplash API 응답은 이미지의 ID, 설명, 사용자 정보, 다양한 크기의 URL 등 복잡한 정보를 담고 있습니다. 최종적으로 블로그에 사용할 특정 이미지 URL만을 추출하여 다음 단계에서 쉽게 사용할 수 있도록 image_url이라는 새로운 필드를 생성합니다.</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="273:1-273:20"><b>4.1. 노드 추가 및 연결:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="275:3-277:0" data-ke-list-type="disc">
<li data-sourcepos="275:3-275:59">HTTP Request (Unsplash Search) 노드 뒤에 Set 노드를 추가합니다.</li>
<li data-sourcepos="276:3-277:0"><b>노드 이름:</b> Set (Extract Image URL)로 이름을 변경합니다.</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="278:1-278:23"><b>4.2. 값 (Values) 설정:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="280:3-296:0" data-ke-list-type="disc">
<li data-sourcepos="280:3-280:40">Values 섹션에서 Add Value 버튼을 클릭합니다.</li>
<li data-sourcepos="281:3-282:27"><b>새로운 필드 이름:</b>
<ul style="list-style-type: disc;" data-sourcepos="282:7-282:27" data-ke-list-type="disc">
<li data-sourcepos="282:7-282:27">Name: image_url</li>
</ul>
</li>
<li data-sourcepos="283:3-296:0"><b>추출할 URL 경로 설정:</b>
<ul style="list-style-type: disc;" data-sourcepos="284:7-296:0" data-ke-list-type="disc">
<li data-sourcepos="284:7-284:67">Value 필드 옆의 <b>톱니바퀴 아이콘</b> (Expression)을 클릭하여 표현식 편집기를 엽니다.</li>
<li data-sourcepos="285:7-294:81">다음과 같은 표현식을 입력합니다: {{ $json.results[0].urls.regular }}
<ul style="list-style-type: disc;" data-sourcepos="286:11-294:81" data-ke-list-type="disc">
<li data-sourcepos="286:11-286:49"><b>$json:</b> 현재 노드의 입력 데이터 전체를 나타냅니다.</li>
<li data-sourcepos="287:11-287:124"><b>results[0]:</b> Unsplash API 검색 결과는 results라는 배열 안에 이미지 객체들을 담고 있습니다. [0]은 그중 첫 번째(가장 관련성이 높은) 이미지를 의미합니다.</li>
<li data-sourcepos="288:11-294:81"><b>urls.regular:</b> 이미지 객체 안의 urls 필드는 다양한 크기의 이미지 URL을 제공합니다.
<ul style="list-style-type: disc;" data-sourcepos="289:15-294:81" data-ke-list-type="disc">
<li data-sourcepos="289:15-289:40">raw: 원본 이미지 URL (매우 큼)</li>
<li data-sourcepos="290:15-290:37">full: 원본에 가까운 큰 이미지</li>
<li data-sourcepos="291:15-291:47">regular: 블로그 게시물에 적합한 일반적인 크기</li>
<li data-sourcepos="292:15-292:30">small: 작은 크기</li>
<li data-sourcepos="293:15-293:31">thumb: 썸네일 크기</li>
<li data-sourcepos="294:15-294:81"><b>권장:</b> 대부분의 블로그 게시물에는 regular 또는 small이 적합합니다. 필요에 따라 선택하세요.</li>
</ul>
</li>
</ul>
</li>
<li data-sourcepos="295:7-296:0">Add 버튼을 클릭하여 표현식을 적용합니다.</li>
</ul>
</li>
</ul>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="297:1-297:16"><b>4.3. 노드 테스트:</b></p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="299:3-301:0" data-ke-list-type="disc">
<li data-sourcepos="299:3-299:66">Set (Extract Image URL) 노드를 클릭하고 Test Node 버튼을 클릭하여 실행합니다.</li>
<li data-sourcepos="300:3-301:0">Output 탭을 확인합니다. 이제 각 블로그 섹션에 해당하는 아이템에 image_prompt, image_keywords와 더불어 <b>image_url 필드가 추가되고 Unsplash에서 가져온 이미지 URL이 포함</b>되어 있어야 합니다.</li>
</ul>
<h3 style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="304:1-304:39"><b>무료 자동화 블로그 이미지 워크플로우, 이제 시작입니다! </b></h3>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="306:1-306:125">이 상세 매뉴얼을 통해 N8N, Google Gemini, Unsplash API를 연동하여 블로그 이미지 자동화 워크플로우를 성공적으로 구축하셨기를 바랍니다. 여러분은 이제 다음과 같은 혁신적인 시스템을 갖추게 되었습니다:</p>
<ol style="list-style-type: decimal; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="308:1-311:0" data-ke-list-type="decimal">
<li data-sourcepos="308:1-308:63"><b>AI 기반 이미지 설명 생성:</b> 블로그 내용에 맞춰 AI가 자동으로 시각적인 이미지를 구상해 줍니다.</li>
<li data-sourcepos="309:1-309:60"><b>스마트 키워드 추출:</b> 복잡한 설명을 Unsplash 검색에 최적화된 핵심 키워드로 변환합니다.</li>
<li data-sourcepos="310:1-311:0"><b>자동 이미지 검색 및 연결:</b> 생성된 키워드를 바탕으로 방대한 Unsplash 라이브러리에서 적절한 이미지를 찾아 매칭합니다.</li>
</ol>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="312:1-312:161">이 워크플로우는 여러분의 콘텐츠 제작 시간을 획기적으로 단축시켜 줄 뿐만 아니라, 각 글에 맞는 고품질의 이미지를 일관성 있게 제공하여 블로그의 시각적 매력과 전문성을 높여줄 것입니다. 이는 궁극적으로 독자의 참여율을 높이고, Google SEO 측면에서도 긍정적인 영향을 미칠 것입니다.</p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="314:1-314:17"><b>다음 단계는 무엇인가요?</b></p>
<p style="background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="316:1-316:41">이제 여러분은 image_url을 확보했습니다. 이 URL을 활용하여</p>
<ul style="list-style-type: disc; background-color: #ffffff; color: #1b1c1d; text-align: start;" data-sourcepos="318:3-321:0" data-ke-list-type="disc">
<li data-sourcepos="318:3-318:160"><b>블로그 플랫폼 연동:</b> WordPress, Notion, Medium, Ghost 등 여러분이 사용하는 블로그 플랫폼의 API를 N8N의 HTTP Request 또는 특정 노드 (예: WordPress 노드)와 연동하여 자동으로 게시물에 이미지를 삽입할 수 있습니다.</li>
<li data-sourcepos="319:3-319:78"><b>HTML 생성:</b> 블로그 글의 최종 HTML을 만들 때 &lt;img&gt; 태그 안에 이 URL을 동적으로 넣어줄 수 있습니다.</li>
<li data-sourcepos="320:3-321:0"><b>이미지 다운로드 및 업로드:</b> 경우에 따라 이미지를 직접 다운로드하여 서버나 CDN에 업로드하는 워크플로우를 추가할 수도 있습니다.</li>
</ul>
<p>n8n을 아직 잘 모르신다면 이 글을 먼저 읽어보세요!</p>
<p><a href="https://aboda.kr/entry/n8n-%EC%8B%9C%EB%86%80%EB%A1%9C%EC%A7%80-%EB%A1%9C%EC%BB%AC-%EC%84%A4%EC%B9%98-%EC%89%BD%EA%B2%8C-%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95" target="_blank" rel="noopener">2024.12.15 &#8211; [제품추천/소프트웨어] &#8211; n8n 시놀로지 로컬 설치 쉽게 하는 방법</a></p>
<p><a href="https://2days.kr/23/06/15/64144/industry/it/">Google Veo3 와 MusicGPT 콜라보로 만드는 AI 영상</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://i2.wp.com/2days.kr/wp-content/uploads/2025/06/제목을-입력해주세요_-001-4-1-1024x1024.jpg?ssl=1" medium="image"></media:content>
            	</item>
		<item>
		<title>Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기</title>
		<link>https://2days.kr/24/06/10/64187/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Tue, 24 Jun 2025 01:09:20 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64187</guid>

					<description><![CDATA[Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기 복잡한 코드 하나 몰라도, 단 몇 분 만에 세련된 웹사이트를 만들 수 있는 시대가 왔습니다. 상상하기 힘들 수 있지만, 인공지능 기술의 발달로 이젠 누구나 웹사이트를 제작할 수 있어요. Lovable.dev 같은 AI 툴을 사용하면, 기존 수백만 원짜리 웹사이트와 견줄 만한 결과물을 단시간에 구현할 수 있답니다. 개발자의 손길 없이도 원하는 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기 복잡한 코드 하나 몰라도, 단 몇 분 만에 세련된 웹사이트를 만들 수 있는 시대가 왔습니다. 상상하기 힘들 수 있지만, 인공지능 기술의 발달로 이젠 누구나 웹사이트를 제작할 수 있어요. <b>Lovable.dev</b> 같은 AI 툴을 사용하면, 기존 수백만 원짜리 웹사이트와 견줄 만한 결과물을 단시간에 구현할 수 있답니다. 개발자의 손길 없이도 원하는 기능과 레이아웃을 AI가 자동으로 생성해주기 때문이죠.</p>
<h3 data-ke-size="size23"><b>Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기</b></h3>
<figure id="attachment_64191" aria-describedby="caption-attachment-64191" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64191 size-large" fifu-data-src="https://i0.wp.com/2days.kr/wp-content/uploads/2025/06/20250624_095828-1024x517.png?ssl=1" alt="Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기" width="696" height="351" loading="lazy" title="Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기 16"><figcaption id="caption-attachment-64191" class="wp-caption-text">Lovable 웹사이트 AI 몇 분 만에 프로 수준으로 만들기</figcaption></figure>

<h3 style="color: #000000; text-align: start;" data-ke-size="size23"><b>Lovable </b>누구에게 가장 유용할까요?</h3>
<p>자영업자, 예비 창업자, 프리랜서, 개인 콘텐츠 제작자까지, 자신의 아이디어를 빠르게 서비스로 구현하고 싶은 분들께 딱 맞는 도구입니다. 예를 들어, 스타트업 초기 단계에서 투자자에게 보여줄 MVP(최소 기능 제품)를 손쉽게 만들어볼 수도 있고요. 수강생 관리, 상담 예약, 정보 제공 등 다양한 목적의 웹사이트를 구현하는 데도 아주 효과적입니다.</p>
<p><a href="https://lovable.dev/" target="_blank" rel="noopener noreferrer noopener">https://lovable.dev/</a></p>
<h3>간단한 설명이나 이미지 한 장이면 충분하다고요?</h3>
<p>이제는 글 몇 줄 혹은 스케치 하나만으로도 웹사이트 디자인이 자동 생성됩니다. 예를 들어, 상담 예약이 가능한 웹페이지를 만들고 싶다면, &#8216;상담 스케줄러를 위한 사용자 인터페이스&#8217;라고 입력만 해보세요. AI는 이를 해석해 달력 기능과 예약 버튼이 포함된 페이지를 제작합니다. 이미지 파일을 업로드해 ‘이런 느낌의 사이트를 만들어줘’라고 하면 그 스타일을 반영한 레이아웃도 자동 구성됩니다. 정말 놀라운 기술력입니다.</p>
<h3>온라인 강의 플랫폼도 만들 수 있을까요?</h3>
<figure data-ke-type="image" data-ke-mobilestyle="widthOrigin" data-ke-style="alignCenter"><figcaption>

</figcaption></figure>
<p>예를 들어, 교육 플랫폼 같은 구조를 구현하고 싶다면 &#8216;온라인 강의 수강 페이지가 포함된 플랫폼&#8217;이라는 식으로 요청하면 됩니다. 여기에 실제 참고 사이트의 화면 캡처를 함께 제공하면 더욱 정확한 결과물이 생성돼요. 원하는 사이트 분위기와 구조를 글과 이미지로 알려주는 것만으로도, AI는 그에 맞춘 페이지 구성을 자동으로 해줍니다. 텍스트 기반 설명과 시각적 자료가 결합되면 더욱 정교한 결과를 얻을 수 있죠.</p>
<h3 style="color: #000000; text-align: start;" data-ke-size="size23"><b>Lovable </b>코드 수정은 어떻게 하나요? 수정도 가능한가요?</h3>
<p>웹사이트를 자동으로 만들었더라도, 기능이나 디자인을 조금 바꾸고 싶을 수 있잖아요? 이럴 땐 GitHub 연동 기능이 유용합니다. 생성된 코드는 자동으로 GitHub에 저장할 수 있고, 개발자나 AI 도우미를 통해 쉽게 수정할 수 있어요. 만약 특정 기능을 추가하고 싶다면, 관련 라이브러리나 모듈을 붙여 넣는 것도 가능합니다. 예를 들어, 결제 시스템이나 영상 업로드 기능 같은 것도 연동해 넣을 수 있어요.</p>
<h3>오류가 나면 어떻게 하죠?</h3>
<p>AI도 완벽하진 않기에 가끔 오류가 발생할 수 있어요. 하지만 걱정 마세요. <b>lovable.dev</b>에는 ‘자동 수정’ 기능이 있어서 오류를 감지하고 AI가 스스로 수정하는 기능까지 포함돼 있습니다. 오류 메시지를 해석할 필요 없이 ‘Try to fix’ 버튼만 누르면 AI가 어떤 부분이 잘못되었는지 판단하고, 스스로 해결해줍니다. 초보자도 안심하고 작업할 수 있는 이유 중 하나죠.</p>
<h3>웹사이트 배포는 어떻게 하나요?</h3>

<p>모든 작업이 끝나면 &#8216;Preview&#8217; 기능을 이용해 사이트를 실제로 어떻게 보이는지 확인할 수 있습니다. 그리고 만족스러운 결과물이 나오면 ‘Publish’ 버튼을 클릭해 즉시 URL로 배포할 수 있어요. 별도의 서버나 복잡한 설정 없이 바로 온라인에 공개할 수 있는 점도 큰 장점입니다. 클라이언트 미팅 전 시제품을 만들거나, 자신만의 서비스 링크를 공유할 때도 유용하겠죠.</p>
<h3 style="color: #000000; text-align: start;" data-ke-size="size23"><b>Lovable </b>월 3억 수익을 내는 AI 개발자 사례도 있다?</h3>
<p>노트북 하나로 수십 억의 매출을 올리는 AI 개발자, <b>피터 레벨스</b>라는 이름 들어보셨나요? 그는 단 한 명의 직원 없이, 다양한 AI 툴을 활용해 서비스를 제작하고 엄청난 수익을 내고 있는 인물입니다. 이처럼 효율적인 툴과 창의적인 아이디어만 있으면, 누구나 수익화가 가능한 시대입니다. 피터의 사례는 많은 창작자와 1인 개발자에게 영감을 주고 있죠.</p>
<h3>더 정교한 작업이 필요하다면?</h3>
<p>AI가 만들어준 코드로 간단한 웹사이트를 완성했다면, 그다음 단계는 더 많은 기능을 추가하는 일이겠죠. GitHub에 저장된 소스를 가져와 <b>Cursor AI</b> 같은 코드 편집 도구를 활용하면, 보다 전문적인 개발 작업도 가능해집니다. 실제 프로젝트 폴더에는 구조화된 코드와 함께 사용 설명서도 포함돼 있어, 개발 경험이 부족한 사람도 따라 하기 쉬워요.</p>
<h3>AI 시대, 우리에게 필요한 준비는?</h3>
<p>AI가 모든 영역을 빠르게 변화시키고 있는 지금, 중요한 건 변화에 얼마나 잘 적응하느냐입니다. 단순히 AI 기술을 보는 데 그치지 않고, 이를 <b>직접 활용하는 능력</b>이 미래 경쟁력을 좌우합니다. 오늘 소개한 lovable.dev처럼 강력한 AI 도구를 배우고 활용한다면, 더 이상 전문가에게만 의존하지 않아도 되고, 기획자나 크리에이터도 직접 실현 가능한 웹 서비스를 만들 수 있어요. 지금부터 하나씩 시작해 보세요!</p>
<p><a style="background-color: #e6f5ff; color: #0070d1; text-align: start;" href="https://aboda.kr/entry/%EB%AC%B4%EB%A3%8C%EB%8F%84%EB%A9%94%EC%9D%B8-%EC%9B%B9%EC%82%AC%EC%9D%B4%ED%8A%B8-%EC%A3%BC%EC%86%8C-%EB%A7%8C%EB%93%A4%EA%B8%B0" target="_blank" rel="noopener">2025.05.30 &#8211; [제품추천/IT] &#8211; 무료도메인 웹사이트 주소 만들기</a></p>
<p><a href="https://2days.kr/29/06/13/37137/aboda/">직장인의 효율적인 업무 관리를 위한 Wrks.ai 웹사이트 소개</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://2days.kr/wp-content/uploads/2025/06/Image_fx-30.png" medium="image"></media:content>
            	</item>
		<item>
		<title>립싱크 AI 사진 속 인물 말하게 만들 수 있다!</title>
		<link>https://2days.kr/24/06/09/64179/it/program/</link>
		
		<dc:creator><![CDATA[urjent]]></dc:creator>
		<pubDate>Tue, 24 Jun 2025 00:46:57 +0000</pubDate>
				<category><![CDATA[program]]></category>
		<guid isPermaLink="false">https://2days.kr/?p=64179</guid>

					<description><![CDATA[립싱크 AI 사진 속 인물 말하게 만들 수 있다! 정지된 사진 속 얼굴이 생생하게 움직이며 말을 한다면 어떨까요? 마치 과거의 장면이 되살아나는 듯한 느낌을 줄 수 있는 이 기술은, 더 이상 영화 속 상상이 아닙니다. 인공지능 기술의 급속한 발전 덕분에, 이제는 누구나 손쉽게 이미지 한 장만으로도 생동감 있는 립싱크 영상을 만들 수 있게 되었죠. 이 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p data-ke-size="size16">립싱크 AI 사진 속 인물 말하게 만들 수 있다! 정지된 사진 속 얼굴이 생생하게 움직이며 말을 한다면 어떨까요? 마치 과거의 장면이 되살아나는 듯한 느낌을 줄 수 있는 이 기술은, 더 이상 영화 속 상상이 아닙니다. 인공지능 기술의 급속한 발전 덕분에, 이제는 누구나 손쉽게 이미지 한 장만으로도 생동감 있는 립싱크 영상을 만들 수 있게 되었죠. 이 글에서는 사진에 생명을 불어넣는 대표적인 AI 립싱크 도구 세 가지를 소개해 드릴게요.</p>
<h2>립싱크 AI 사진 속 인물 말하게 만들 수 있다!</h2>
<figure id="attachment_64180" aria-describedby="caption-attachment-64180" style="width: 696px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==" fifu-lazy="1" fifu-data-sizes="auto" fifu-data-srcset="https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=75&amp;resize=75&amp;ssl=1 75w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=100&amp;resize=100&amp;ssl=1 100w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=150&amp;resize=150&amp;ssl=1 150w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=240&amp;resize=240&amp;ssl=1 240w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=320&amp;resize=320&amp;ssl=1 320w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=500&amp;resize=500&amp;ssl=1 500w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=640&amp;resize=640&amp;ssl=1 640w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=800&amp;resize=800&amp;ssl=1 800w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=1024&amp;resize=1024&amp;ssl=1 1024w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=1280&amp;resize=1280&amp;ssl=1 1280w, https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1&amp;w=1600&amp;resize=1600&amp;ssl=1 1600w" class="wp-image-64180 size-large" fifu-data-src="https://i1.wp.com/2days.kr/wp-content/uploads/2025/06/Image_fx-28-1024x559.png?ssl=1" alt="립싱크 AI 사진 속 인물 말하게 만들 수 있다!" width="696" height="380" loading="lazy" title="립싱크 AI 사진 속 인물 말하게 만들 수 있다! 19"><figcaption id="caption-attachment-64180" class="wp-caption-text">립싱크 AI 사진 속 인물 말하게 만들 수 있다!</figcaption></figure>

<h3>1. 부드러운 영상 퀄리티가 강점인 ‘Hedra’</h3>

<p>첫 번째로 살펴볼 도구는 <b>Hedra</b>입니다. 원래는 이미지 생성 기반 플랫폼으로 알려졌지만, 최근에는 AI 기반 립싱크 영상 기능까지 제공하면서 활용도가 크게 높아졌습니다. 회원가입 후 정면 사진을 업로드하고, 대사를 입력하거나 직접 음성을 녹음해 적용할 수 있어요. 한국어도 지원하므로, 한글 텍스트를 입력해도 자연스럽게 작동합니다.</p>
<p><a href="https://aboda.kr/entry/AI-%EC%95%84%EB%B0%94%ED%83%80-Hedra-%EB%AC%B4%EB%A3%8C-%EA%B3%A0%ED%80%84%EB%A6%AC%ED%8B%B0%EB%A1%9C-%EB%A7%8C%EB%93%A4-%EC%88%98-%EC%9E%88%EC%96%B4" target="_blank" rel="noopener">2025.06.24 &#8211; [컴퓨터/AI] &#8211; AI 아바타 Hedra 무료 고퀄리티로 만들 수 있어!</a></p>
<p>또한 목소리 선택 옵션이 있어 다양한 톤의 음성을 미리 들어보고 설정할 수 있으며, 자신의 음성을 학습시켜 사용할 수도 있습니다. 영상 한 편을 만들 때 일정량의 크레딧이 소모되며, 생성된 영상은 다운로드도 가능합니다. 전체적으로 UI가 직관적이며, 영상의 품질이 높고 캐릭터의 입모양과 눈동자 움직임도 매우 자연스러워 다양한 콘텐츠 제작에 적합합니다.</p>
<h3>2. 직관적이고 빠른 ‘D-ID’의 사용자 친화형 기능</h3>
<p>두 번째는 <b>D-ID</b>입니다. 이 플랫폼은 정적 이미지를 활용해 빠르게 립싱크 영상을 만들 수 있는 간편한 도구로, 이메일 가입만으로 이용이 가능합니다. 처음 사용 시에는 ‘Create’ 버튼을 눌러 아바타를 직접 업로드하고 설정해야 합니다. 감정 표현과 움직임은 ‘자연스러움’을 선택하면 가장 안정적인 결과를 보여줍니다.</p>


<p><a href="https://www.d-id.com/" target="_blank" rel="noopener noreferrer noopener">https://www.d-id.com/</a></p>
<p>텍스트 입력창에 원하는 대사를 입력하면, AI가 그에 맞는 목소리와 표정을 적용하여 립싱크 영상을 생성해 줍니다. 한국어를 사용하려면 언어를 ‘Korean’으로 설정하고, 한국인 목소리를 선택해야 합니다. 기본 무료 플랜에서도 일정 수의 크레딧이 제공되며, 영상 제작 후 결과물을 저장할 수도 있어요. 간단한 설정만으로도 영상 제작이 가능하다는 점에서 초보자에게 추천할 만합니다.</p>
<h3>3. 진짜 연기처럼 자연스러운 ‘DubbDubb AI’</h3>
<p>세 번째로 소개할 도구는 <b>DubbDubb AI</b>입니다. 이 도구는 이름처럼 마치 배우처럼 대사를 말하고 감정을 전달하는 데 탁월한 퀄리티를 보여줍니다. 사용자는 ‘New Avatar’를 선택하고, 정면 얼굴이 잘 보이는 사진을 업로드하면 기본 설정이 완료됩니다. 이후 텍스트 스크립트를 입력하면, AI가 자동으로 음성을 생성하고 립싱크 애니메이션을 적용합니다.</p>

<p><a href="https://www.dupdub.com/" target="_blank" rel="noopener noreferrer noopener">https://www.dupdub.com/</a></p>
<figure id="og_1750725259443" contenteditable="false" data-ke-type="opengraph" data-ke-align="alignCenter" data-og-type="website" data-og-title="Try AI Tools For Voiceovers &amp; Content Creation | DupDub" data-og-description="Empower your creativity with DupDub's AI voiceover, writing, painting, and video editing tools. Start your transformation with a free trial." data-og-host="www.dupdub.com" data-og-source-url="https://www.dupdub.com/" data-og-url="https://www.dupdub.com/" data-og-image="https://scrap.kakaocdn.net/dn/AwxDV/hyZbpMHQ11/yEcfcw2ZkKkTu3Hcz1EN0k/img.png?width=400&amp;height=400&amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/bQkoxV/hyZch1Z0UI/3sR8OKUno3hqW9klhSRw10/img.png?width=400&amp;height=400&amp;face=0_0_400_400">
<div class="og-image"></div>
<div class="og-text">
<p class="og-title">Try AI Tools For Voiceovers &amp; Content Creation | DupDub</p>
<p class="og-desc">Empower your creativity with DupDub&#8217;s AI voiceover, writing, painting, and video editing tools. Start your transformation with a free trial.</p>
<p class="og-host">www.dupdub.com</p>
</div>
</figure>
<p>한국어는 물론, 다양한 언어를 지원하며, 성별과 말투, 분위기를 조절할 수 있어 활용 범위가 넓어요. 영상 제작 단계에서는 ‘Generate’ 버튼만 누르면 바로 렌더링이 시작되며, 출력된 결과물은 SNS 콘텐츠, 프레젠테이션, 마케팅 영상 등에 다양하게 활용할 수 있습니다. 감정 표현이 비교적 풍부하고 시선 처리도 자연스러워 실제 사람처럼 느껴지는 것이 강점입니다.</p>
<h3>어떤 립싱크 AI 툴이 나에게 적합할까?</h3>


<p>세 가지 도구 모두 사진에 생명력을 불어넣는 AI 기술이지만, 각각의 특징과 강점이 다릅니다. <b>Hedra</b>는 영상의 전체 퀄리티와 UI의 편리함이 뛰어나고, <b>D-ID</b>는 빠르게 립싱크 콘텐츠를 제작하고자 하는 사람에게 적합하며, <b>DubbDubb AI</b>는 감정 표현과 자연스러운 연기를 원한다면 최고의 선택이 될 수 있어요.</p>
<p>만약 콘텐츠 마케팅이나 브랜디드 콘텐츠를 제작하려는 분이라면, 이 AI 립싱크 도구들을 전략적으로 활용해 보세요. 이미지 한 장으로 전달력 높은 콘텐츠를 완성할 수 있는 이 기술은, 앞으로 영상 커뮤니케이션의 방식에 큰 변화를 줄 수 있습니다.</p>
<h3>립싱크 AI 마무리하며</h3>
<p>정적인 이미지를 활용해 실시간 립싱크 영상으로 바꿀 수 있는 이 놀라운 기술들 덕분에, 영상 제작의 진입 장벽이 크게 낮아졌습니다. 기획 아이디어만 있다면 누구나 AI 아바타, 립싱크 영상으로 표현력을 넓힐 수 있죠. 특히 유튜브 쇼츠, 광고, 교육 콘텐츠 등 다양한 용도에 맞춰 이 도구들을 자유롭게 활용해보세요.</p>
<p><b>관련 키워드:</b><br />
AI 립싱크, 사진 말하게 만들기, 헤드라 사용법, D-ID 튜토리얼, 덥덥AI 후기, AI 아바타 립싱크, 무료 AI 영상 생성기, 이미지 기반 영상 만들기, 한글 지원 AI 툴, AI 성우 영상 제작</p>
<p><a href="https://2days.kr/23/06/15/64144/industry/it/">Google Veo3 와 MusicGPT 콜라보로 만드는 AI 영상</a></p>
]]></content:encoded>
					
		
		
		<media:content url="https://2days.kr/wp-content/uploads/2025/06/Image_fx-28.png" medium="image"></media:content>
            	</item>
	</channel>
</rss>
