์์์ ๋ด ๋๋ผ ์๊ธฐ์์ต๋๋ค
๋ฏธ๊ตญ ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ์์ ์์ฆ "Roast My ~" ์๋ฆฌ์ฆ๊ฐ ํ์ฐฝ ํ์ ์ ๋๋ค. Roast My Strava, Roast My Code, Roast My Github... AIํํ ๋ด ๊ฒฐ๊ณผ๋ฌผ์ ๊ฐ์ ธ๋ค ์ฃผ๋ฉด ์ ๋ํ๊ฒ ๊น๋ฌ๋ผ๊ณ ํ๋ ์ฝ์ ํธ์ ๋๋ค.
๋ณด๋ฉด์ ๋ฑ ์๊ฐํ์ต๋๋ค. ์ด๊ฑฐ ์ฌ๋ฐ๊ฒ ๋ค!
๋ง์นจ ๊ทธ ๋ LinkedIn ํ๋กํ์ ์์ ํ์ด์์ธ์ง ๋ฐ๋ก ๋์ ๋ค์ด์์ต๋๋ค. LinkedIn ํ๋กํ ํฉํญ ์๋น์ค! ์ฐ๋ฆฌ๋๋ผ์๋ ์์๊น ์ถ์ด์ ์ฐพ์๋ดค๋๋ฐ ์์ง์ ์์๊ณ , ํด์ธ์ ์๋ ๋น์ทํ ์๋น์ค๋ค๋ ์ง์ ๋ค์ด๊ฐ๋ดค๋๋ ํ๋๊ฐ์ด ์๋์ ์ ํ์ต๋๋ค. ์คํฌ๋ํ API ํ ๋น๋์ด ๋ค ์ฐผ๊ฑฐ๋, LinkedIn์ด ๋ด ์ ๊ทผ์ ์์ ๋ง์๋ฒ๋ฆฐ ๊ฑฐ์์ต๋๋ค.
๊ทธ๋์ ๋ฐ~๋ก ๋ง๋ค๊ธฐ๋ก ๋ง๋จน์์ต๋๋ค! ์ด์์ด๋ฉด ํ๊ตญ์์ผ๋ก! ๐ฐ๐ท
๋ชฉ์ ๋ถํฐ ๋ถ๋ช ํ
์ด ํ๋ก์ ํธ๋ ์จ์ ํ ๋์ Claude ๋์ด์ ๋ง๋ ํ๋ก์ ํธ์ ๋๋ค. ๊ธฐํ ๋จ๊ณ์์๋ถํฐ Claude์ ํจ๊ป ๊ณ์ํด์ ๋ํ๋ฅผ ์ฃผ๊ณ ๋ฐ์ผ๋ฉฐ ๋ง๋ค์ด๋๊ฐ์ต๋๋ค. ์ฒ์์๋ ์ด๊ฒ์ ๊ฒ ๊ฑฐ์ฐฝํ๊ฒ ์๊ฐํ๋๋ฐ, ๋ํํ๋ค ๋ณด๋ ๊ฒฐ๊ตญ ํ๋๋ก ์ ๋ฆฌ๋์ต๋๋ค.
๋น ๋ฅด๊ณ ๊ฐ๋จํ๊ฒ, ์ฌ๋ฏธ์์ด ๋ณด์ด๋ ๊ฑธ ๋ง๋ค์.
์๋ฒฝ๋ณด๋ค๋ ์ผ๋จ ๋ง๋ค์ด์ ์ธ์์ ๋ด๋๊ณ ๋ฐ์๋ถํฐ ๋ณด๋ ๊ฑธ ๋ชฉํ๋ก ํ์ต๋๋ค. ๋จ์ํ๊ฒ ์ง์ง ์ฌ๋๋ค์ด ์ด๊ฑธ ์ธ๊น? ๊ถ๊ธํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฌด๋ฃ API ํ ๋น๋์ด ์ผ๋ง๋ ๋นจ๋ฆฌ ์์ง๋ ์ง ๊ธฐ๋๋์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๊ธฐ์ ๊ฒฐ์ โ ์คํฌ๋ํ์ ํฌ๊ธฐํ์ง ์๋๋ค
LinkedIn์ ์คํฌ๋ํ์ ์ฒ ์ ํ๊ฒ ๋ง์ต๋๋ค. ์ค์ ๋ก ์์ก๊น์ง ๊ฐ ์ผ์ด์ค๊ฐ ์์ ์ ๋์ ๋๋ค. ๊ทผ๋ฐ ์ฐพ์๋ณด๋ ์์ง ๊ฐ๋ฅํ API๋ค์ด ์์์ต๋๋ค.
๊ทธ๋์ Claude์ ๊ธฐ๋ณธ UI๋ถํฐ ๋น ๋ฅด๊ฒ ๋ง๋ค์ด์ ์คํฌ๋ํ์ด ์ด๋ป๊ฒ ์งํ๋๋์ง ์ด๋ค ์๋ฌ๊ฐ ๋๋์ง ํ ์คํธ๋ฅผ ํด๋ณด์๋๋ฐ, ํ๋ค๋ณด๋ ๊ณ ๋ฏผ์ด ์๊ฒผ์ต๋๋ค.
API๊ฐ ๋งํ๊ฑฐ๋ ํ ๋น๋์ด ๋ค ์ฐจ๋ฉด ์ด๋กํ์ง?
๊ทธ๋์ RapidAPI ๋ง์ผํ๋ ์ด์ค๋ฅผ ๋ค์ง๊ธฐ ์์ํ์ต๋๋ค. LinkedIn ์คํฌ๋ํ API๋ฅผ ํ๋ํ๋ ๋ค ์ฐพ์๋ดค์ต๋๋ค. ์ ๋ฃ๋ ์ฌ์ฉ์๊ฐ ๊ธ์๋๋ก ๋์ด๋ฌ์ ๋ ๊ณ ๋ คํ๊ธฐ๋ก ํ๊ณ , ์ฐ์ ๋ฌด๋ฃ๋ฅผ ์ด์ฌํ ์ฐพ์์ 8๊ฐ๋ฅผ ๋ชจ์์ต๋๋ค! ํ๋์ RapidAPI ํค๋ก ์ฌ๋ฌ API๋ฅผ ๋ฌด๋ฃ ๊ตฌ๋ ํ ์ ์๋ค๋ ๊ฑธ ์๊ฒ ๋๋ฉด์, ํ๋๊ฐ ํ๋์ ๊ฑธ๋ฆฌ๋ฉด ๋ค์ API๋ก ๋๊ธฐ๋ fallback chain ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์์ต๋๋ค. ์ด๋ ๊ฒ ํ ๋น๋ ๋ฌธ์ ๋ ํด๊ฒฐ!๐
๊ทธ๋ฆฌ๊ณ ์คํฌ๋ํ ์ฐจ๋จ ๋ฌธ์ ๋ ๋ ์ฌ๋ฐ๊ฒ ํ์ด๋ณด์์ต๋๋ค. ๋งํ๋ ๊ฒฝํ ์์ฒด๋ฅผ ์ฌ๋ฏธ์๋ UX๋ก ๋ง๋ค์ด๋ฒ๋ฆฌ์! ์๋ฌ ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋์ , ์ฐจ๋จ๋นํ๋ ์๊ฐ์ ํ ๋ฏธ ๋งํฌ๋ก ํ์ด๋ด๋ฉด ์คํ๋ ค ๋ ์๊ธฐ์ง ์์๊น?
โโ 8๊ฐ RapidAPI๋ฅผ ์์ฐจ์ ์ผ๋ก ์๋
โโ ์ฑ๊ณต โ AI ๋ถ์์ผ๋ก ์ด๋
โโ ์ ๋ถ ์คํจ
โโ 429 ํ ๋น๋ ์ด๊ณผ -> "ํ ๋ฏธ๋ผ๊ฐ ๋๋ฌด ์ธ๊ธฐ๊ฐ ๋ง์๋ถ๋ฌ์ ์์ฒญ ํ๋๋ฅผ ๋๊ฒจ๋ถ๋ ์ด์ ~"
โโ 403 ์คํฌ๋ํ ์ฐจ๋จ -> "LinkedIn์ด ํ ๋ฏธ ๋ชป ๋ค์ด์ค๊ฒ ๋ง์๋ถ๋ ์ด์ ~"
โโ PDF/์คํฌ๋ฆฐ์ท ์
๋ก๋๋ก ์๋ด
์ฌ์ฉ์ ์ ์ฅ์์๋ ์ด ๊ณผ์ ์ด ์ ํ ์ ๋ณด์ ๋๋ค. ๋ด๋ถ์์ ์กฐ์ฉํ ๋๋ค๊ฐ, ์ ๋ง ์ ๋ ๋๋ง ํ ๋ฏธ ๋งํฌ๋ก ์๋ดํ๊ณ , ๊ฑฐ๊ธฐ์ ํญ์ ๋ ๋ฒ์งธ ๋ฐฉ๋ฒ(์ง์ ์ ๋ก๋)์ด ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค. ์ฐจ๋จ๋นํ๋ ๊ฒ ์คํจ๊ฐ ์๋๋ผ ์คํ ๋ฆฌ๊ฐ ๋๋ ๊ตฌ์กฐ์ ๋๋ค. ์ด ์์ด๋์ด๊ฐ ๋ ์ฌ๋์ ๋ ์ผ๋ฅธ ์ฌ์ฉ์๋ค์๊ฒ ๋ณด์ฌ์ค ์๊ฐ์ ์ ๋์ ์์ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ ๋ฒ์งธ ๊ธฐ์ ๊ฒฐ์ โ PC์ ๋ชจ๋ฐ์ผ์ ๋ค๋ฅด๊ฒ
๊ฑฐ์ ๋ค ๋ง๋ค์ด๊ฐ๋์ฏค ํ ์คํธํ๋ค๋ณด๋ ํ๋๊ฐ ๊ฑธ๋ ธ์ต๋๋ค. LinkedIn ํ๋กํ์ PDF๋ก ์ ์ฅํ๋ ๊ธฐ๋ฅ์ด PC์์๋ง ๋ฉ๋๋ค. ๋ชจ๋ฐ์ผ ์ฑ์๋ ๊ทธ๋ฐ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
์ ๊น ๊ณ ๋ฏผํ์ง๋ง, ๊ทธ๋ฌ๋ฉด ๋ ๋ค ์ง์ํ๋ฉด ๋์ง! ํ๋ ๋ง์์ผ๋ก ๋ฐ๋ก ์์ ์ ๋ค์ด๊ฐ์ต๋๋ค.
- ๐ป PC: LinkedIn โ ๋๋ณด๊ธฐ โ PDF๋ก ์ ์ฅ โ ์ ๋ก๋
- ๐ฑ ๋ชจ๋ฐ์ผ: ํ๋กํ ์คํฌ๋ฆฐ์ท ์ดฌ์ โ ์ ๋ก๋ โ AI Vision์ผ๋ก ๋ถ์
PDF๋ ํ
์คํธ๊ฐ ๊ทธ๋๋ก ๋ฝํ๋๊น ๋ถ์ ์ ํ๋๊ฐ ๋๊ณ , ์คํฌ๋ฆฐ์ท์ AI์ ์ด๋ฏธ์ง ๋ถ์ ๋ฅ๋ ฅ์ ์ฐ๋ ๊ฒ๋๋ค. ์ด๋ค ๋ฐฉ๋ฒ์ด๋ ๊ฐ์ /api/roast ์๋ํฌ์ธํธ๋ก ๋ค์ด์ค๊ณ , ํ์ผ ํ์
์ ๋ฐ๋ผ ์ฒ๋ฆฌ๋ง ๋ฌ๋ผ์ง๊ฒ ๋ง๋ค์์ต๋๋ค.
์ํคํ ์ฒ ์ค๊ณ โ ํ ์ค Frontend Fundamentals ์ ์ฉ
ํด๋ ๊ตฌ์กฐ๋ฅผ ์ก์ ๋ ํ ์ค Frontend Fundamentals๋ฅผ ์ฐธ๊ณ ํ์ต๋๋ค. ํต์ฌ์ ๊ฐ๋จํฉ๋๋ค โ ํจ๊ป ์์ ๋๋ ์ฝ๋๋ ๊ฐ์ ๋๋ ํ ๋ฆฌ์. ์๋ฅผ ๋ค์ด ๊ฒฐ๊ณผ ํ๋ฉด์ ๊ณ ์น๋ฉด ResultScreen.tsx์ CringeGauge.tsx๋ ๊ฑฐ์ ํญ์ ๊ฐ์ด ์์ ๋๋๋ฐ, ์ด ๋์ด ๋ค๋ฅธ ํด๋์ ์์ผ๋ฉด ์๋ค๊ฐ๋ค ํ๋๋ผ ์ ์ ์์ต๋๋ค.
app/
โโโ components/ # ์ ์ญ ๊ณต์ UI (2๊ฐ ์ด์ ๋๋ฉ์ธ์์ ์ฌ์ฉ)
โ โโโ HalmiSpinner.tsx
โ
โโโ domains/ # ํ๋ฉด๋ณ ๋๋ฉ์ธ (ํจ๊ป ์์ ๋๋ ์ฝ๋ ์์ง)
โ โโโ result/
โ โ โโโ ResultScreen.tsx
โ โ โโโ CringeGauge.tsx # result ์ ์ฉ โ ๋ค๋ฅธ ๊ณณ์์ ์ ์
โ โโโ upload/
โ โโโ UploadScreen.tsx
โ โโโ UploadZone.tsx
โ
โโโ lib/ # ์ ์ญ ๊ณต์ ํ์
/์ ํธ
โโโ api/ # API ๋ผ์ฐํธ
ํ๋จ ๊ธฐ์ค์ ๋ฑ ํ๋์์ต๋๋ค. "์ด ์ปดํฌ๋ํธ ๋ค๋ฅธ ํ๋ฉด์์๋ ์ฐ๋?"
์ฐ๋ฉด components/ ์ ์ฐ๋ฉด ํด๋น ๋๋ฉ์ธ ํด๋ ์. ์ฌํํ๋๊น ์ข์ต๋๋ค.
์ํ ๊ด๋ฆฌ โ ์ํ ๋จธ์ ์ผ๋ก 7๊ฐ ํ๋ฉด ๊ด๋ฆฌ
page.tsx ํ๋์์ ์ํ ๋จธ์ ํจํด์ผ๋ก ํ๋ฉด์ ๊ด๋ฆฌํ์ต๋๋ค. Router ์์ด!
type Screen = 'landing' | 'scraping' | 'blocked' | 'upload' | 'loading' | 'result' | 'error'
// ํ๋ฆ
landing โ scraping โ (์ฑ๊ณต) โ loading โ result
โ (์คํจ) โ blocked โ upload โ loading โ result
AI ๋ชจ๋ธ ์ ํ โ Claude์์ Gemini๋ก ๊ฐ์ํ ์ด์
์ฒ์์ Claude Sonnet 4๋ฅผ ์ผ์ต๋๋ค. ๊ทผ๋ฐ ๋น์ฉ์ด ๊ฑธ๋ ธ์ต๋๋ค. ๋ฐ์ด๋ด ์๋น์ค๋ผ ํธ๋ํฝ์ ์์ธกํ ์๊ฐ ์๋๋ฐ, ๊ฑด๋น ๋น์ฉ์ด ๋๊ฐ๋ฉด ๋ถ๋ด์ด ํฝ๋๋ค.
| ์๊ตฌ์ฌํญ | Gemini 2.5 Flash |
|---|---|
| ๋ฌด๋ฃ ๋๋ ์ ๋ ด | โ |
| ์ด๋ฏธ์ง/PDF ๋ฉํฐ๋ชจ๋ฌ | โ |
| ํ๊ตญ์ด (์ถฉ์ฒญ๋ ์ฌํฌ๋ฆฌ) ์ฑ๋ฅ | โ |
| JSON ์ถ๋ ฅ ์์ ์ฑ | โ |
์๋ต์ ๊ตฌ์กฐํ๋ JSON์ผ๋ก ๋ฐ๊ฒ ํ์ต๋๋ค:
{
"cringeScore": 72,
"detectedWords": ["์ฑ์ฅํ๋", "์ํฉํธ", "์ปค๋ฎค๋์ผ์ด์
"],
"roastText": "์์ด๊ตฌ~ ์ด ํ๋กํ ์ธ ๋ ๋ถ๋๋ฝ์ง ์์์ด์ ?...",
"tips": ["...", "...", "..."]
}
detectedWords๋ฅผ ๋ฐฐ์ด๋ก ๋ฐ์ผ๋๊น ๊ฒฐ๊ณผ ํ๋ฉด์์ ๋ฑ์ง๋ก ์์๊ฒ ๋ณด์ฌ์ค ์ ์๊ณ , Slack ๋ก๊ทธ์๋ ๋ฐ๋ก ์ฐํ๋๋ค.
ํ๋กฌํํธ ์์ง๋์ด๋ง โ "๋ฐ์ ๋ฒํผ" ์์คํ
์ถฉ์ฒญ๋ ์ฌํฌ๋ฆฌ ํ ๋จธ๋๊ฐ ํฉํญํด์ฃผ๋ ์๋น์ค๋๊น ํ๋กฌํํธ๊ฐ ํต์ฌ์ ๋๋ค. ํ๊ตญ์ธ๋ค์ด LinkedIn์์ ์ ์ผ ๋ง์ด ์ฐ๋ ๋จ์ด๋ค์ ์กฐ์ฌํด์ ํ๋กฌํํธ์ ์ง์ ๋ฃ์์ต๋๋ค. ์ด๊ฑธ "๋ฐ์ ๋ฒํผ"์ด๋ผ๊ณ ์ด๋ฆ ๋ถ์๋๋ฐ AI๊ฐ ์ด ๋จ์ด๋ค์ ๋ณด๋ฉด ๋ฐ๋์ ๋ฐ์ํ๋๋ก ๋ง๋ ํด๋ฆฌ์ ฐ ํจํด์ ๋๋ค.
| ์ ํ | ์์ |
|---|---|
| ์ฑ์ฅ ์ง์ฐฉํ | "๋งค์ผ ์ฑ์ฅํ๋", "๋ฌ๋ ์ปค๋ธ", "์๊ธฐ์ฃผ๋์ " |
| ํ์ /๋ฌธ์ ํด๊ฒฐ ํ์ธํ | "์ํฉํธ", "๊ฐ์น ์ฐฝ์ถ", "์ธ์ฌ์ดํธ" |
| ์ํต/ํ์ ๊ต๊ณผ์ํ | "์ํํ ์ปค๋ฎค๋์ผ์ด์ ", "์ค๋์ญ", "๋๋ฆฌ๋ธ" |
| ๊ฒธ์ํ ์ฒ ์๋ํ | "๊ฐ์ฌํ๊ฒ๋", "์ด ์ข๊ฒ๋", "humbled to" |
| ์คํํธ์ ์ฉ์ด ๋จ๋ฐํ | "์ ์์ผ", "๊ทธ๋ก์ค", "MVP", "ํผ๋ด" |
| ์ซ์ ์๋ ์ฑ๊ณผํ | "๋งค์ถ์ ์ฑ์ฅ์์ผฐ์ต๋๋ค" (์ผ๋ง๋?) |
| ๋ปํ ์๊ธฐ์๊ฐํ | "๋ ๋์ ์ธ์์ ๋ง๋ค๊ณ ์ถ์", "๋ค์ํ ๊ฒฝํ" |
| ๋น์ฐํ ์คํฌ ๋์ดํ | ์ปค๋ฎค๋์ผ์ด์ , ํ์ํฌ, ๋ฆฌ๋์ญ, ์ฑ์คํจ |
๊ฐ์ฑ ์ค๊ณ โ ํฉํญ๊ณผ ์์์ ๋ฐ๋ก
์ฒ์์ AIํํ "๋ง์ง๋ง์ ๋ฐ๋ปํ๊ฒ ๋ง๋ฌด๋ฆฌํด์ค"๋ผ๊ณ ์์ผฐ๋๋ฐ, ํค์ด ๋งค๋ฒ ๋ฌ๋ผ์ ธ์ ์ด์ํ์ต๋๋ค. ๊ทธ๋์ ์ญํ ์ ๋๋ ๋ฒ๋ ธ์ต๋๋ค.
- AI โ ๋๊น์ง ํฉํญ๋ง. ์๊ธฐ๊ฐ ์ํ๋ ๊ฒ์ ์ง์ค
- HalmiCheer ์ปดํฌ๋ํธ โ ๊ณ ์ ์์ ๋ฌธ๊ตฌ๋ก ๋ง๋ฌด๋ฆฌ
๋ธ๋๋ฉ โ ํ ๋ฏธ๋ผ์ ํ์
๋ฏธ๊ตญ์ "Roast My"๊ฐ ์๋ค๋ฉด, ํ๊ตญ์๋ ๋ญ๊ฐ ์ด์ธ๋ฆด๊น?
"๋ผ๋ผ๋~" ๋๋ฆฝ์ด ๋ ์ฌ๋์ต๋๋ค. ๊ผฐ๋ ์ด๋ฅธ์ด ์ ์ ์ฌ๋ ํ์ ๋๋ ๊ทธ ๋๋. ๊ฑฐ๊ธฐ์ ๋์์ด๋๋ก ์ผํ๋ ์นํ ์น๊ตฌ๊ฐ ์์ ์ ๋ง๋ค์ด์คฌ๋ ํ๋จธ๋ ์ฌ์ง์ด ๋ ์ค๋ฅด๋ฉด์ ๋ฑ ๋ง์๋จ์ด์ก์ต๋๋ค.
ํ ๋ฏธ๋ผ ์ด๋ฆ ์ง์ ์๊ฐ ์ด๋ฏธ ๋ฐ์ ๋ ๋๋์ด์์ต๋๋ค.
๋ฐ ์๋น์ค ๋ง๋๋ ๊น์ ์๊ฐ๋ ๊ฑด๋ฐ, ์ด์คํฐ์๊ทธ๋ ํ๋ ๋ฃ์์ต๋๋ค. ์ฌ๋ฐ์ ๊ฒ ๊ฐ์์.
๐ซ ๋์์ํ ๋ด๋น์๋ ๋ณด๊ณ ๊ณ์์ ? ํ ๋ฏธ๋ผ ร ๋ฏธ๋ผ ์ฝ๋ผ๋ณด ์ด๋ป๊ฒ ์ด์ ~ ๐
์ด๋ฐ ์ธ๋ฐ์๋ ๋ํ ์ผ ๋ฃ์ ๋๊ฐ ์ ์ผ ์ฌ๋ฐ์ต๋๋ค.๐
๋ชจ๋ํฐ๋ง โ Sentry + Slack์ผ๋ก ๋
์๋ฌ๋ Sentry, ์ ์ ์ฌ์ฉ ๋ก๊ทธ๋ Slack Webhook. ์ฌํํ๊ฒ ๊ฐ์ต๋๋ค.
๐ต ํฉํญ ์๋ฃ!
โข ์ค๊ธ ์ ์: 72/100 (๋ถ๋๋ฝ์ง ์์์ด์ ? ๐)
โข ํ์ธ ๋จ์ด: ์ฑ์ฅํ๋, ์ํฉํธ, ์ปค๋ฎค๋์ผ์ด์
โข ๋ถ์ ๋ฐฉ์: URL ์คํฌ๋ํ
์ฌ์ฉ์๊ฐ ์ค์ ๋ก ์ฐ๋ค๊ฐ ์๋ฌ๊ฐ ํฐ์ง๋ฉด ๋ฐ๋ก๋ฐ๋ก ๋์ํ๊ณ ์ถ์๊ณ , API ํ ๋น๋์ด ์ผ๋ง๋ ์์ง๋๊ณ ์๋์ง, ์ ๋ก๋ ๋ฐฉ์์ผ๋ก ๋์ด๊ฐ๋ ๋น์จ์ ์ด๋ค์ง๋ ํ์ธํ๊ณ ์ถ์์ต๋๋ค. DB๋ ์ด๋๋ฏผ ํจ๋๊น์ง ๋ง๋ค ํ์๋ ์์ด์, Slack์ผ๋ก ๊ฐ๋จํ ์ ๋ณด๋ง ์ค๋๋ก ํ์ต๋๋ค. ์ฌ์ด๋ ํ๋ก์ ํธ์๋ ์ด๊ฒ ๋ฑ์ ๋๋ค.
๋ฐ์นญ ํ โ ์ค์๋น์ค์์ ํฐ์ง ๊ฒ๋ค
๋ฐฐํฌํ๊ณ ํ๋ฃจ ๋ง์ ์ฝ๋๋ก๋ ์ ๋ ์ก์ ์ ์์๋ ๋ฌธ์ ๋ค์ด ๋ฐ์ํ์ต๋๋ค. ๋ถ๋ช ์ด์์์๋๋ฐ...
1. ํ๊ธ LinkedIn URL ์คํฌ๋ํ ์คํจ
์์-์ด-1234567 ๊ฐ์ด ํ๊ธ์ด ์์ธ username์ ๋ฃ์ผ๋ฉด 8๊ฐ API๊ฐ ์ ๋ถ ์คํจํฉ๋๋ค. RapidAPI ์คํฌ๋ํผ๋ค์ด ๋น์๋ฌธ username์ ์์ ๋ชป ์ฒ๋ฆฌํ๋ ๊ฑฐ์์ต๋๋ค.
์๋ฌ ํ๋ฉด๋ณด๋ค ์ฌ์ ์๋ด๊ฐ ๋ซ๋ค๊ณ ๋ดค์ต๋๋ค. ํ๊ธ์ด ๊ฐ์ง๋๋ฉด "์คํฌ๋ํ์ด ์ ๋ ์ ์์ด์ " ๋ฌธ๊ตฌ๋ฅผ ๋ฏธ๋ฆฌ ๋์์, ์ ๋ก๋๋ก ์์ฐ์ค๋ฝ๊ฒ ์ ๋ํ๋๋ก ๋ฐ๊ฟจ์ต๋๋ค.
2. Gemini JSON ํ์ฑ ์คํจ
๊ฐํ์ ์ผ๋ก 500์ด ํฐ์ก์ต๋๋ค. Gemini๊ฐ JSON์ ๋ฐํํ ๋ ๊ฐ๋ json ... ๋งํฌ๋ค์ด ์ฝ๋๋ธ๋ก์ผ๋ก ๊ฐ์ธ๊ฑฐ๋, ์๋ค์ ์ค๋ช
ํ
์คํธ๋ฅผ ๋ถ์ด๋ ๊ฒฝ์ฐ๊ฐ ์์์ต๋๋ค. ๋จ์ JSON.parse()๋ก๋ ๋น์ฐํ ํฐ์ง๋๋ค.
2๋จ๊ณ ํ์ฑ์ผ๋ก ํด๊ฒฐํ์ต๋๋ค:
try {
// 1์ฐจ: ์ฝ๋๋ธ๋ก ์ ๊ฑฐ ํ ํ์ฑ
const cleaned = text.replace(/```[\s\S]*?\n([\s\S]*?)```/g, "$1").trim();
result = JSON.parse(cleaned);
} catch {
// 2์ฐจ: ์๋ต์์ ์ฒซ ๋ฒ์งธ { ~ ๋ง์ง๋ง } ๋ฅผ ์ง์ ์ถ์ถ
const firstBrace = text.indexOf("{");
const lastBrace = text.lastIndexOf("}");
if (firstBrace !== -1 && lastBrace > firstBrace) {
result = JSON.parse(text.slice(firstBrace, lastBrace + 1));
}
}
1์ฐจ์์ ์ ๊ท์์ผ๋ก ์ฝ๋๋ธ๋ก์ ์ ๊ฑฐํ๊ณ , ์คํจํ๋ฉด 2์ฐจ์์ JSON ๊ฐ์ฒด์ ์์({)๊ณผ ๋(})์ ์ง์ ์ฐพ์ ์ถ์ถํฉ๋๋ค. Gemini๊ฐ ์ฝ๋๋ธ๋ก ์๋ค์ ์ด๋ค ํ
์คํธ๋ฅผ ๋ถ์ด๋ JSON๋ง ์ ํํ ๊บผ๋ผ ์ ์์ต๋๋ค. ํ์ฑ ์คํจ ์์๋ raw text๋ฅผ Sentry์ ์ฐ์ด์ ๋์ค์ ๋ญ๊ฐ ๊นจ๋จ๋ ธ๋์ง ์ถ์ ํ ์ ์๊ฒ ํ์ต๋๋ค.
3. Gemini๊ฐ ๋ ์ง๋ฅผ ๋ชจ๋ฆ ๋๋ค!
์ฌ์ฉ์ ํผ๋๋ฐฑ์ผ๋ก ์๊ฒ ๋ ๋ฌธ์ ์ ๋๋ค. ํ๋กํ์ "์ผ์ฑ ์ฒญ๋ SW ์์นด๋ฐ๋ฏธ 2025๋ 1์"์ด๋ผ๊ณ ์ ํ ์์ผ๋ฉด, Gemini๊ฐ ์ด๊ฑธ ๋ฏธ๋ ์ผ์ ์ผ๋ก ์ค์ธํด์ "์์๋ ์ ํ ๊ฑธ ๊ฒฝ๋ ฅ์ด๋ผ๊ณ ์ฌ๋ ค ๋์ผ๋ฉด ์ฌ๋๋ค์ด ์์์ฃผ๋ ์ค ์๋๊ฒจ?"๋ผ๊ณ ํฉํญํ๋ ์ํฉ์ด ๋ฐ์ํ์ต๋๋ค. 2025๋ 1์์ ์ด๋ฏธ ์ง๋ ๊ณผ๊ฑฐ์ธ๋ฐ๋.
LLM์ ํ์ต ์์ ์ ์ง์๋ง ๊ฐ์ง๊ณ ์์ด์, ํ๋กฌํํธ์ ํ์ฌ ๋ ์ง๋ฅผ ๋ช ์์ ์ผ๋ก ์๋ ค์ฃผ์ง ์์ผ๋ฉด ์๊ฐ ๊ธฐ์ค์ ์ก์ง ๋ชปํฉ๋๋ค. ํด๊ฒฐ์ ๊ฐ๋จํฉ๋๋ค.
function buildSystemPrompt() {
const today = new Date().toISOString().split("T")[0];
return `...
์ค๋ ๋ ์ง: ${today}
ํ๋กํ์ ์ ํ ๋ ์ง/๊ธฐ๊ฐ์ ํ๋จํ ๋ ๋ฐ๋์ ์ค๋ ๋ ์ง ๊ธฐ์ค์ผ๋ก ๊ณผ๊ฑฐ/ํ์ฌ/๋ฏธ๋๋ฅผ ํ๋จํ์ธ์.
...`;
}
ํ ์ค ์ถ๊ฐ๋ก ํด๊ฒฐ๋์ง๋ง, ์ง์ ํผ๋๋ฐฑ์ ๋ฐ๊ธฐ ์ ๊น์ง๋ ์ ํ ๋ ์ฌ๋ฆฌ์ง ๋ชปํ ๋ฌธ์ ์์ต๋๋ค. ์ค์ ๋ก ์ฌ์ฉ์์ ํผ๋๋ฐฑ์ ํตํด ๋ฌธ์ ์ ๋ค์ ํ์ ํ ์ ์์ด์ ํผ๋๋ฐฑ ์์ญ์ ์ถ๊ฐํ๊ธธ ์ ๋ง ์ํ๋จ ์๊ฐ์ด ๋ค์์ต๋๋ค.
4. ํด๋ฆฝ๋ณด๋ ๊ถํ ๊ฑฐ๋ถ
๊ฒฐ๊ณผ ํ๋ฉด ๊ณต์ ๋ฒํผ์์ NotAllowedError๊ฐ ํฐ์ก์ต๋๋ค. navigator.share() โ ์คํจ โ clipboard.writeText()๋ฅผ ์์๋๋ก ํธ์ถํ๋ ๊ตฌ์กฐ์๋๋ฐ, ๋ฒํผ ํด๋ฆญ ํ ๋ฒ์ผ๋ก ๋ณด์ API๋ฅผ ๋ ๊ฐ ์ฐ๋ฌ์ ๋ถ๋ฅด๋ฉด ๋ ๋ฒ์งธ์์ ์ ์ค์ฒ๊ฐ ์๋น๋ ๊ฑธ๋ก ๊ฐ์ฃผ๋ผ์ ๊ฑฐ๋ถ๋นํฉ๋๋ค.
navigator.share ์ง์ ํ๊ฒฝ์ด๋ฉด ๊ทธ๊ฒ๋ง ์ฐ๊ณ ๋ฐ๋ก return, ๋ฏธ์ง์์ด๋ฉด ํด๋ฆฝ๋ณด๋๋ก ๋ถ๊ธฐํ๊ฒ ๊ณ ์ณค์ต๋๋ค. ๋ API๊ฐ ๊ฒฝ์ํ๋ ๊ตฌ์กฐ๋ฅผ ์์ค ๊ฒ๋๋ค.
๋ง์น๋ฉฐ
ํ ๋ฏธ๋ผ๋ฅผ ๋ง๋๋ ๋ด๋ด ์ฌ๋ฐ์์ต๋๋ค. 8๊ฐ API fallback chain์ ์ฎ์ ๋, ์ฐจ๋จ ํ๋ฉด์ ์คํ ๋ฆฌ๋ก ๋ฐ๊ฟ ๋, ์ด์คํฐ์๊ทธ๋ฅผ ์ฌ์ ๋...๋ฑ๋ฑ ์ด๋ฐ ๋ํ ์ผ ํ๋ํ๋๋ฅผ ๋ง๋ค ๋ ์ฌ๋ฏธ์์ด ํ ์ ์ ๋ค์ ์๊ฐํ๋ ๋ ์ ๋๊ฒ ๋ง๋ค ์ ์์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ทธ๋ฅ AI ์ฑ๋ด๊ณผ ์ฌ๋ฐ๋ ์๋น์ค์ ์ฐจ์ด๋ ๊ฒฐ๊ตญ ๋ํ ์ผ์์ ๋์จ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฌด์๋ณด๋ค ๋ง๋๋ ์ฌ๋์ด ์ฌ๋ฐ์ด์ผ ์ฐ๋ ์ฌ๋๋ ์ฌ๋ฐ์ต๋๋ค!
์ฃผ๋ณ์ ๋ง์ด๋ค ๊ณต์ ํด์ฃผ์ธ์~~๐