Problem Generator V3 - ๊ธฐ์ˆ  ๋งค๋‰ด์–ผ

๋ฒ„์ „: 1.0 (capstone-2025-04 ์ฝ”๋“œ๋ฒ ์ด์Šค ๊ธฐ์ค€) ์ตœ์ข… ์—…๋ฐ์ดํŠธ: 2024๋…„ 7์›” 27์ผ

๋ชฉ์ฐจ

  1. ์†Œ๊ฐœ
  2. ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜
  3. ๊ธฐ์ˆ  ์Šคํƒ
  4. ํ•ต์‹ฌ ๋ฐฑ์—”๋“œ ๋กœ์ง: ๋ฌธ์ œ ์ƒ์„ฑ ํŒŒ์ดํ”„๋ผ์ธ
  5. ์ธํ”„๋ผ (Terraform์„ ์‚ฌ์šฉํ•œ AWS IaC)
  6. ๋ฐฐํฌ
  7. ๋กœ์ปฌ ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ (๋ฐฑ์—”๋“œ)
  8. API ์‚ฌ์šฉ๋ฒ• (ํ”„๋ก ํŠธ์—”๋“œ ๊ด€์ )
  9. ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐ ์•Œ๋ ค์ง„ ๋ฌธ์ œ
  10. ํ–ฅํ›„ ๊ฐœ์„  ์‚ฌํ•ญ ๋ฐ TODO
  11. ๊ฒฐ๋ก 

1. ์†Œ๊ฐœ

1.1 ๋ชฉ์ 

Problem Generator V3๋Š” ๋Œ€๊ทœ๋ชจ ์–ธ์–ด ๋ชจ๋ธ(LLM), ํŠนํžˆ LangChain ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด Google์˜ Gemini ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฌธ์ œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋„๋ก ์„ค๊ณ„๋œ AWS ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๋ฆฌ์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค. ํฌ๊ด„์ ์ธ ๋ฌธ์ œ ์„ค๋ช…, ์˜ˆ์ œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค, ์†”๋ฃจ์…˜ ์ฝ”๋“œ, ์ œ์•ฝ ์กฐ๊ฑด ๋ฐ ์‹œ์ž‘ ์ฝ”๋“œ ํ…œํ”Œ๋ฆฟ ์ƒ์„ฑ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. V3์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์€ ์ƒ์„ฑ๋œ ์†”๋ฃจ์…˜์„ ๊ฒ€์ฆํ•˜๊ณ  ์ •ํ™•ํ•œ ํ…Œ์ŠคํŠธ ์ถœ๋ ฅ์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ์‹ค์ œ ์ฝ”๋“œ ์‹คํ–‰์— ์˜์กดํ•˜์—ฌ ์ด์ „ ๋ฒ„์ „์— ๋น„ํ•ด ์•ˆ์ •์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

1.2 ์ฃผ์š” ๊ธฐ๋Šฅ

  • LLM ๊ธฐ๋ฐ˜ ์ƒ์„ฑ: Google Gemini ๋ชจ๋ธ์„ ํ™œ์šฉํ•˜์—ฌ ์ฐฝ์˜์ ์ด๊ณ  ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์‹คํ–‰ ๊ธฐ๋ฐ˜ ๊ฒ€์ฆ: ์ƒ์„ฑ๋œ ์†”๋ฃจ์…˜ ์ฝ”๋“œ๋ฅผ ์„ค๊ณ„๋œ ํ…Œ์ŠคํŠธ ์ž…๋ ฅ์— ๋Œ€ํ•ด ์‹คํ–‰ํ•˜์—ฌ ์ •ํ™•์„ฑ์„ ๊ฒ€์ฆํ•˜๊ณ  ์˜ˆ์ƒ ์ถœ๋ ฅ์„ ๋„์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹จ๊ณ„๋ณ„ ํŒŒ์ดํ”„๋ผ์ธ: ๋‹ค๋‹จ๊ณ„ ๋ชจ๋“ˆ์‹ ํŒŒ์ดํ”„๋ผ์ธ(LangChain ์‚ฌ์šฉ)์ด ์˜๋„ ๋ถ„์„์—์„œ ์ตœ์ข… ๋ฒˆ์—ญ์— ์ด๋ฅด๊ธฐ๊นŒ์ง€ ๋ฌธ์ œ ์ƒ์„ฑ์˜ ๋‹ค์–‘ํ•œ ์ธก๋ฉด์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„-์ „์†ก ์ด๋ฒคํŠธ(SSE): Lambda ํ•จ์ˆ˜ URL ์ŠคํŠธ๋ฆฌ๋ฐ์„ ํ†ตํ•ด ์ƒ์„ฑ ๊ณผ์ • ์ค‘ ์‹ค์‹œ๊ฐ„ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • DynamoDB ํ†ตํ•ฉ: ๋ฌธ์ œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ์ƒ์„ฑ ์ƒํƒœ ๋ฐ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ์•ˆ์ „ํ•œ ์ฝ”๋“œ ์‹คํ–‰: ์ƒ์„ฑ๋œ Python ์ฝ”๋“œ์˜ ์ƒŒ๋“œ๋ฐ•์Šค ์‹คํ–‰์„ ์œ„ํ•ด ๋ณ„๋„์˜ AWS Lambda ํ•จ์ˆ˜(code-execution-service)๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œํ˜• ์ธํ”„๋ผ(IaC): AWS ๋ฆฌ์†Œ์Šค๋Š” Terraform์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“ˆ์‹ ๋ฐฑ์—”๋“œ: ์ฝ”๋“œ๋ฒ ์ด์Šค๋Š” ์„œ๋น„์Šค, ์ฒด์ธ, ํ”„๋กฌํ”„ํŠธ, ์Šคํ‚ค๋งˆ ๋ฐ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์œ ์ง€ ๊ด€๋ฆฌ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
  • ์‹œ์ž‘ ์ฝ”๋“œ ์ƒ์„ฑ: ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ์‹œ์ž‘ ์ฝ”๋“œ ํ…œํ”Œ๋ฆฟ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฒˆ์—ญ: ๋ฌธ์ œ ์ œ๋ชฉ ๋ฐ ์„ค๋ช… ๋ฒˆ์—ญ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

2. ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

2.1 ๊ฐœ์š”

graph TD
    User[์ตœ์ข… ์‚ฌ์šฉ์ž] -->|์ƒํ˜ธ์ž‘์šฉ| Frontend[ํ”„๋ก ํŠธ์—”๋“œ (Next.js/React ์•ฑ)]
    Frontend -->|API ํ˜ธ์ถœ (SSE)| CloudFront[AWS CloudFront ๋ฐฐํฌ]
    CloudFront -->|์š”์ฒญ ์ „๋‹ฌ (OAC๋ฅผ ํ†ตํ•œ IAM ์ธ์ฆ)| ProblemGenLambdaURL[Problem Generator Lambda ํ•จ์ˆ˜ URL]
    ProblemGenLambdaURL --> ProblemGenLambda[Problem Generator Lambda (Node.js, LangChain, Gemini API)]
    ProblemGenLambda -->|๋ฌธ์ œ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ/์“ฐ๊ธฐ| ProblemsDB[AWS DynamoDB (Problems ํ…Œ์ด๋ธ”)]
    ProblemGenLambda -->|๋ชจ๋ธ ์ถ”๋ก  ํ˜ธ์ถœ| GeminiAPI[Google Gemini API]
    ProblemGenLambda -->|์ฝ”๋“œ ์‹คํ–‰ ํ˜ธ์ถœ| CodeExecutorLambda[Code Executor Lambda (Python)]

    subgraph AWS ํด๋ผ์šฐ๋“œ
        CloudFront
        ProblemGenLambdaURL
        ProblemGenLambda
        ProblemsDB
        CodeExecutorLambda
    end

2.2 ๊ตฌ์„ฑ ์š”์†Œ

  • ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: (frontend/src/app ๊ธฐ๋ฐ˜์œผ๋กœ ์ถ”์ •๋œ Next.js/React) ๋ฌธ์ œ ์ƒ์„ฑ ์š”์ฒญ์„ ์‹œ์ž‘ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.
  • AWS CloudFront: ๊ณต๊ฐœ์ ์œผ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ง„์ž…์  ์—ญํ• ์„ ํ•˜๋ฉฐ, Origin Access Control(OAC)์„ ํ†ตํ•ด Lambda ํ•จ์ˆ˜ URL์— ๋Œ€ํ•œ ์บ์‹ฑ, HTTPS ๋ฐ ๋ณด์•ˆ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • Problem Generator Lambda ํ•จ์ˆ˜ URL: Problem Generator Lambda์šฉ HTTPS ์—”๋“œํฌ์ธํŠธ๋กœ, IAM ์ธ์ฆ ๋ฐ SSE์šฉ RESPONSE_STREAM ํ˜ธ์ถœ ๋ชจ๋“œ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • Problem Generator Lambda (problem-generator-v3):
    • Node.js๋กœ ์ž‘์„ฑ๋œ ํ•ต์‹ฌ ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
    • LangChain.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Google Gemini API์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ๋‹ค๋‹จ๊ณ„ ๋ฌธ์ œ ์ƒ์„ฑ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • DynamoDB์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜์—ฌ ๋ฌธ์ œ ์ƒ์„ฑ ์ƒํƒœ ๋ฐ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • ์ƒ์„ฑ๋œ Python ์†”๋ฃจ์…˜์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด Code Executor Lambda๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
    • SSE๋ฅผ ํ†ตํ•ด ์ง„ํ–‰ ์ƒํ™ฉ ์—…๋ฐ์ดํŠธ ๋ฐ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.
  • Code Executor Lambda (code-execution-service):
    • ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑํ•œ Python ์ฝ”๋“œ ์กฐ๊ฐ์„ ์ƒŒ๋“œ๋ฐ•์Šค ํ™˜๊ฒฝ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๋ณ„๋„์˜ AWS Lambda ํ•จ์ˆ˜(์ผ๋ฐ˜์ ์œผ๋กœ Python)์ž…๋‹ˆ๋‹ค.
    • ์ฝ”๋“œ์™€ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  stdout, stderr, ์‹คํ–‰ ์‹œ๊ฐ„ ๋ฐ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • AWS DynamoDB (alpaco-Problems-v3-production ํ…Œ์ด๋ธ”):
    • ์›๋ณธ ํ”„๋กฌํ”„ํŠธ, ์ƒ์„ฑ๋œ ์ฝ˜ํ…์ธ (์ œ๋ชฉ, ์„ค๋ช…, ์†”๋ฃจ์…˜, ํ…Œ์ŠคํŠธ, ์ œ์•ฝ ์กฐ๊ฑด), ์ƒ์„ฑ ์ƒํƒœ, ํƒ€์ž„์Šคํƒฌํ”„ ๋ฐ creatorId, author์™€ ๊ฐ™์€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ ๋ฌธ์ œ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ž…๋‹ˆ๋‹ค.
    • ํšจ์œจ์ ์ธ ์ฟผ๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ธ€๋กœ๋ฒŒ ๋ณด์กฐ ์ธ๋ฑ์Šค(GSI)๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค (์˜ˆ: CompletedProblemsByCreatedAtGSI, CreatorIdCreatedAtGSI).
  • Google Gemini API: ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฌธ์ œ์˜ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” LLM ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
  • AWS S3 (Terraform ์ƒํƒœ์šฉ): alpaco-tfstate-bucket-kmu๋Š” Terraform ์ƒํƒœ ํŒŒ์ผ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • AWS IAM: ๋ชจ๋“  AWS ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๊ถŒํ•œ์„ ๊ด€๋ฆฌํ•˜์—ฌ ์•ˆ์ „ํ•œ ์ƒํ˜ธ ์ž‘์šฉ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

3. ๊ธฐ์ˆ  ์Šคํƒ

๋ถ„๋ฅ˜ ๊ธฐ์ˆ /์„œ๋น„์Šค ๋ชฉ์ 
ํ”„๋ก ํŠธ์—”๋“œ React, Next.js, TypeScript ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ ํด๋ผ์ด์–ธํŠธ ์ธก ๋กœ์ง (์ถ”์ •)
ย  AWS Amplify (Auth) ์‚ฌ์šฉ์ž ์ธ์ฆ (์ถ”์ •, fetchAuthSession ๊ธฐ๋ฐ˜)
๋ฐฑ์—”๋“œ (๋ฌธ์ œ ์ƒ์„ฑ) AWS Lambda (Node.js 20.x) ๋ฌธ์ œ ์ƒ์„ฑ ๋กœ์ง์„ ์œ„ํ•œ ์„œ๋ฒ„๋ฆฌ์Šค ์ปดํ“จํŒ…
ย  LangChain.js LLM ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ํ”„๋ ˆ์ž„์›Œํฌ
ย  Google Gemini API ์ฝ˜ํ…์ธ  ์ƒ์„ฑ์„ ์œ„ํ•œ ๋Œ€๊ทœ๋ชจ ์–ธ์–ด ๋ชจ๋ธ
ย  AWS SDK for JavaScript v3 (DynamoDB, Lambda) AWS ์„œ๋น„์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉ
ย  Zod LLM ์ถœ๋ ฅ ๋ฐ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์Šคํ‚ค๋งˆ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
ย  uuid ๊ณ ์œ ํ•œ ๋ฌธ์ œ ID ์ƒ์„ฑ
๋ฐฑ์—”๋“œ (์ฝ”๋“œ ์‹คํ–‰) AWS Lambda (Python - ์ถ”์ •) ์ƒŒ๋“œ๋ฐ•์Šค ์ฝ”๋“œ ์‹คํ–‰
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค AWS DynamoDB ๋ฌธ์ œ ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ์œ„ํ•œ NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
API ๋ฐ ๋„คํŠธ์›Œํ‚น AWS CloudFront CDN, HTTPS, Lambda์— ๋Œ€ํ•œ ๋ณด์•ˆ ์•ก์„ธ์Šค
ย  AWS Lambda ํ•จ์ˆ˜ URL Lambda์šฉ HTTPS ์—”๋“œํฌ์ธํŠธ, SSE ์ŠคํŠธ๋ฆฌ๋ฐ
์ธํ”„๋ผ Terraform ์ฝ”๋“œํ˜• ์ธํ”„๋ผ (Infrastructure as Code)
ย  AWS S3 Terraform ์ƒํƒœ ์ €์žฅ์†Œ
ย  AWS IAM ์ž๊ฒฉ ์ฆ๋ช… ๋ฐ ์•ก์„ธ์Šค ๊ด€๋ฆฌ
๋นŒ๋“œ/DevOps Docker Lambda ๋ ˆ์ด์–ด ๋นŒ๋“œ (build-layer.sh, Dockerfile.build)
ย  npm Node.js ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ

4. ํ•ต์‹ฌ ๋ฐฑ์—”๋“œ ๋กœ์ง: ๋ฌธ์ œ ์ƒ์„ฑ ํŒŒ์ดํ”„๋ผ์ธ

4.1 ํŒŒ์ดํ”„๋ผ์ธ ๊ฐœ์š”

๋ฌธ์ œ ์ƒ์„ฑ ํ”„๋กœ์„ธ์Šค๋Š” Problem Generator Lambda์˜ src/services/pipeline.mjs์— ์˜ํ•ด ์กฐ์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” LLM ๋ฐ ๊ธฐํƒ€ ์„œ๋น„์Šค๋ฅผ ํ™œ์šฉํ•˜๋Š” ์ˆœ์ฐจ์ ์ธ ๋‹ค๋‹จ๊ณ„ ํ”„๋กœ์„ธ์Šค์ž…๋‹ˆ๋‹ค. ๊ฐ ์ฃผ์š” ๋‹จ๊ณ„๋Š” ์‹คํŒจ ์‹œ ์žฌ์‹œ๋„๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค (MAX_RETRIES๊นŒ์ง€). ๊ฐ ๋‹จ๊ณ„์—์„œ SSE ์—…๋ฐ์ดํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

4.2 ์ƒ์„ธ ๋‹จ๊ณ„

ํŒŒ์ดํ”„๋ผ์ธ์€ ๊ฐ ์ƒ์„ฑ ๋‹จ๊ณ„์— ๋Œ€ํ•œ LLM ํ”„๋กฌํ”„ํŠธ, ์ถœ๋ ฅ ํŒŒ์„œ ๋ฐ ํŠน์ • ๋กœ์ง์„ ์บก์Аํ™”ํ•˜๋Š” โ€œ์ฒด์ธโ€ ๋ชจ๋“ˆ(src/chains/์— ์œ„์น˜)์„ ๋™์ ์œผ๋กœ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

๋‹จ๊ณ„ ํ•จ์ˆ˜ (pipeline.mjs) / ์ฒด์ธ ๋ชจ๋“ˆ ์„ค๋ช… ์ฃผ์š” ์ž…๋ ฅ ์ฃผ์š” ์ถœ๋ ฅ
0 ์ž…๋ ฅ ํŒŒ์‹ฑ / ์ดˆ๊ธฐ DB ๋ ˆ์ฝ”๋“œ ์‚ฌ์šฉ์ž ์š”์ฒญ(ํ”„๋กฌํ”„ํŠธ, ๋‚œ์ด๋„, creatorId, author)์„ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค. problemId๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. generationStatus: "started"๋กœ DynamoDB์— ์ดˆ๊ธฐ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์š”์ฒญ ๋ณธ๋ฌธ problemId, userPrompt, difficulty, creatorId, author
1 runIntentAnalysis (intentAnalysis/) ์‚ฌ์šฉ์ž์˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ„์„ํ•˜์—ฌ ํ•ต์‹ฌ ๋ฌธ์ œ ๋ชฉํ‘œ, ์ฃผ์š” ์ œ์•ฝ ์กฐ๊ฑด, ๊ด€๋ จ ๊ฐœ๋…, ์ž…์ถœ๋ ฅ ์Šคํ‚ค๋งˆ ์„ค๋ช… ๋ฐ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํƒ€์ด ๋ธŒ๋ ˆ์ดํ‚น ๊ทœ์น™์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค. user_prompt, difficulty intent (๊ตฌ์กฐํ™”๋œ ๊ฐ์ฒด), intentJson
2 runTestDesign (testDesign/) ์ถ”์ถœ๋œ ์˜๋„์™€ ๋‚œ์ด๋„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์–‘ํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž…๋ ฅ๊ณผ ๊ทผ๊ฑฐ๋ฅผ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ์˜ˆ์ƒ ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. intent, intent_json, difficulty, language testSpecs (์ž…๋ ฅ ๋ฐ ๊ทผ๊ฑฐ ๋ฐฐ์—ด), testSpecsJson
3 runSolutionGeneration (solutionGen/) ์˜๋„ ๋ฐ ํ…Œ์ŠคํŠธ ์„ค๊ณ„ ์ž…๋ ฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋Œ€์ƒ ์–ธ์–ด(python3.12)๋กœ ์†”๋ฃจ์…˜ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ง€์ •๋œ ๊ฒฝ์šฐ ํƒ€์ด ๋ธŒ๋ ˆ์ดํ‚น ๊ทœ์น™์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. intent.goal, testSpecsJson, language, input_schema_description, tie_breaking_rule solutionCode (๋ฌธ์ž์—ด)
4 ์†”๋ฃจ์…˜ ์‹คํ–‰ ๋ฐ ๊ฒ€์ฆ ๋ฃจํ”„ V3 ํ•ต์‹ฌ ๋‹จ๊ณ„. ย  ย 
4.a executeSolutionWithTestCases (solutionExecution.mjs) Code Executor Lambda๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ testSpecs์˜ ๊ฐ ์ž…๋ ฅ์— ๋Œ€ํ•ด solutionCode๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์ถœ๋ ฅ, ์‹คํ–‰ ์‹œ๊ฐ„ ๋ฐ ์˜ค๋ฅ˜๋ฅผ ์บก์ฒ˜ํ•ฉ๋‹ˆ๋‹ค. solutionCode, testSpecs (JSON์—์„œ ํŒŒ์‹ฑ๋จ), language executionResults (success ํ”Œ๋ž˜๊ทธ, ์‹ค์ œ ์ถœ๋ ฅ์ด ํฌํ•จ๋œ testResults ๋ฐฐ์—ด, errors ๋ฐฐ์—ด, LLM์šฉ feedback์ด ํฌํ•จ๋œ ๊ฐ์ฒด)
4.b (4.a ์‹คํŒจ ์‹œ) runSolutionGeneration (์žฌ์‹œ๋„) ์‹คํ–‰์ด ์‹คํŒจํ•˜๋ฉด(๊ตฌ๋ฌธ ์˜ค๋ฅ˜, ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜, ์‹œ๊ฐ„ ์ดˆ๊ณผ), solutionCode๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด LLM์— ์ƒ์„ธํ•œ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. MAX_RETRIES๊นŒ์ง€ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. intent.goal, testSpecsJson, language, feedback_section ์ƒˆ๋กœ์šด solutionCode
ย  ย  ย  ย  validatedSolutionCode (๋ชจ๋“  ์‹คํ–‰์„ ํ†ต๊ณผํ•œ ๋ฒ„์ „)
5 finalizeTestCasesWithEdgeCases (testCaseFinalization.mjs) executionResults๋ฅผ ์ตœ์ข… ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๊ตฌ์กฐ(์ž…๋ ฅ, ์‹คํ–‰ ๊ฒ€์ฆ๋œ ์˜ˆ์ƒ ์ถœ๋ ฅ, ๊ทผ๊ฑฐ)๋กœ ํ˜•์‹ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ์ ์œผ๋กœ LLM์— ์ถ”๊ฐ€ ์—์ง€ ์ผ€์ด์Šค ์ œ์•ˆ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. validatedSolutionCode, executionResults, llm (์„ ํƒ ์‚ฌํ•ญ), language finalTestCases (๋ฐฐ์—ด), finalTestCasesJson
6 runConstraintsDerivation (constraints/) ๋ฌธ์ œ ์ œ์•ฝ ์กฐ๊ฑด(์‹œ๊ฐ„/๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ, ์ž…๋ ฅ ๊ฐ’ ๋ฒ”์œ„)์„ ๋„์ถœํ•˜๊ณ  ์†”๋ฃจ์…˜ ๋ฐ ํ…Œ์ŠคํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ judge_type(์˜ˆ: equal, float_eps) ๋ฐ epsilon์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. validatedSolutionCode, finalTestCasesJson, difficulty, input_schema_description, output_format_description constraints (๊ฐ์ฒด), constraintsJson
6.5 runStartCodeGeneration (startCode/) ๋ฌธ์ œ ์Šคํ‚ค๋งˆ ๋ฐ ์†”๋ฃจ์…˜ ์ฝ”๋“œ ์กฐ๊ฐ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•จ์ˆ˜ ์„œ๋ช… ๋ฐ ๊ธฐ๋ณธ I/O ํžŒํŠธ๋ฅผ ํฌํ•จํ•œ ์‚ฌ์šฉ์ž์šฉ ์‹œ์ž‘ ์ฝ”๋“œ ํ…œํ”Œ๋ฆฟ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. language, input_schema_description, output_format_description, constraints_json, solution_code_snippet startCode (๋ฌธ์ž์—ด)
7 runValidation (validation/) ์ „์ฒด ์ƒ์„ฑ๋œ ํŒจํ‚ค์ง€(์˜๋„, ์†”๋ฃจ์…˜, ํ…Œ์ŠคํŠธ, ์ œ์•ฝ ์กฐ๊ฑด)์— ๋Œ€ํ•ด ์ผ๊ด€์„ฑ, ์™„์ „์„ฑ์„ LLM ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „์— ์ƒ์„ฑ๋œ ๋ชจ๋“  ๊ฒฐ๊ณผ๋ฌผ validationResult (status ๋ฐ details ํฌํ•จ ๊ฐ์ฒด)
8 runDescriptionGeneration (description/) ๋‚ด๋Ÿฌํ‹ฐ๋ธŒ, ์ž…์ถœ๋ ฅ ํ˜•์‹, ์ œ์•ฝ ์กฐ๊ฑด ๋ฐ ์˜ˆ์ œ(finalTestCases์—์„œ ๊ฐ€์ ธ์˜ด)๋ฅผ ํฌํ•จํ•˜์—ฌ ์‚ฌ์šฉ์ž์šฉ ๋ฌธ์ œ ์„ค๋ช…์„ Markdown์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. intent.goal, constraintsJson, exampleTestCasesJson, difficulty, language, epsilon_value_from_constraints, tie_breaking_rule description (Markdown ๋ฌธ์ž์—ด)
9 runTitleGeneration (title/) ๊ฐ„๊ฒฐํ•œ ๋ฌธ์ œ ์ œ๋ชฉ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. difficulty, intent.goal, description_snippet problemTitle (๋ฌธ์ž์—ด)
10 runTranslation (translation/) problemTitle ๋ฐ description์„ DEFAULT_TARGET_LANGUAGE(์˜ˆ: ํ•œ๊ตญ์–ด)๋กœ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๋‹ค. target_language, text_to_translate (์ œ๋ชฉ ๋ฐ ์„ค๋ช…์šฉ) translatedTitle, translatedDescription
11 ์ตœ์ข…ํ™” generationStatus: "completed" ๋ฐ ๋ชจ๋“  ์ƒ์„ฑ๋œ ๊ฒฐ๊ณผ๋ฌผ๋กœ DynamoDB ๋ ˆ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ์ตœ์ข… ProblemDetailAPI ๊ฐ์ฒด๋ฅผ SSE๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ƒ์„ฑ๋œ ๊ฒฐ๊ณผ๋ฌผ ์ตœ์ข… SSE โ€œresultโ€ ์ด๋ฒคํŠธ

5. ์ธํ”„๋ผ (Terraform์„ ์‚ฌ์šฉํ•œ AWS IaC)

์ธํ”„๋ผ๋Š” capstone-2025-04/infrastructure/problem-generator-v3/์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

5.1 ๊ฐœ์š”

Terraform์€ ํ•„์š”ํ•œ ๋ชจ๋“  AWS ๋ฆฌ์†Œ์Šค๋ฅผ ํ”„๋กœ๋น„์ €๋‹ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ƒํƒœ๋Š” backend.tf์— ์ •์˜๋œ ๋Œ€๋กœ S3 ๋ฒ„ํ‚ท(alpaco-tfstate-bucket-kmu)์— ์›๊ฒฉ์œผ๋กœ ์ €์žฅ๋˜๋ฉฐ DynamoDB(alpaco-tfstate-lock-table)๋ฅผ ํ†ตํ•ด ์ž ๊ธˆ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

5.2 ์ฃผ์š” ๋ฆฌ์†Œ์Šค

  • Lambda ํ•จ์ˆ˜ (aws_lambda_function.problem_generator_v3 - lambda.tf):
    • ๋Ÿฐํƒ€์ž„: nodejs20.x (ARM64 ์•„ํ‚คํ…์ฒ˜).
    • ํ•ธ๋“ค๋Ÿฌ: var.lambda_handler์— ์˜ํ•ด ์ •์˜๋จ (์˜ˆ: index.handler๋Š” src/index.handler๋ฅผ ๊ฐ€๋ฆฌํ‚ด).
    • ์ฝ”๋“œ ์†Œ์Šค: var.lambda_code_path์—์„œ ์••์ถ•๋จ (์˜ˆ: ../../backend/lambdas/problem-generator-v3/src).
    • ์‹œ๊ฐ„ ์ œํ•œ: 900์ดˆ (15๋ถ„).
    • ๋ฉ”๋ชจ๋ฆฌ: 1024MB.
    • ๋ ˆ์ด์–ด: aws_lambda_layer_version.problem_generator_v3_deps.
    • ํ™˜๊ฒฝ ๋ณ€์ˆ˜: PROBLEMS_TABLE_NAME, GOOGLE_AI_API_KEY, GENERATOR_VERBOSE, GEMINI_MODEL_NAME, CODE_EXECUTOR_LAMBDA_ARN.
  • Lambda ํ•จ์ˆ˜ URL (aws_lambda_function_url.problem_generator_v3_url - lambda.tf):
    • ์ธ์ฆ: AWS_IAM.
    • ํ˜ธ์ถœ ๋ชจ๋“œ: SSE์šฉ RESPONSE_STREAM.
    • CORS: ์•ก์„ธ์Šค๋ฅผ ํ—ˆ์šฉํ•˜๋„๋ก ๊ตฌ์„ฑ๋จ (ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” allow_origins ์กฐ์ •).
  • Lambda ๋ ˆ์ด์–ด (aws_lambda_layer_version.problem_generator_v3_deps - layer.tf):
    • Node.js ์ข…์†์„ฑ ํฌํ•จ (package-lock.json ๊ธฐ๋ฐ˜).
    • build-layer.sh ์Šคํฌ๋ฆฝํŠธ ๋ฐ Dockerfile.build๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œ๋จ.
  • IAM ์—ญํ•  ๋ฐ ์ •์ฑ… (iam.tf):
    • aws_iam_role.problem_generator_v3_lambda_role: Lambda ํ•จ์ˆ˜๊ฐ€ ๋งก๋Š” ์—ญํ• .
    • aws_iam_policy.problem_generator_v3_lambda_policy: CloudWatch Logs, Bedrock(InvokeModel, InvokeModelWithResponseStream - ํ–ฅํ›„ ์‚ฌ์šฉ ์œ„ํ•ด ์œ ์ง€), Code Executor Lambda(var.code_executor_lambda_arn) ํ˜ธ์ถœ ๊ถŒํ•œ ๋ถ€์—ฌ.
    • aws_iam_policy.problems_dynamodb_policy: problems_table ๋ฐ ํ•ด๋‹น GSI์— ๋Œ€ํ•œ ์ „์ฒด CRUD, Query, Scan ๊ถŒํ•œ ๋ถ€์—ฌ.
    • AWSLambdaBasicExecutionRole์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ.
  • DynamoDB ํ…Œ์ด๋ธ” (aws_dynamodb_table.problems_table - dynamodb.tf):
    • ์ด๋ฆ„: ${var.project_name}-Problems-v3-${var.environment}.
    • ๋นŒ๋ง ๋ชจ๋“œ: PAY_PER_REQUEST.
    • ํ•ด์‹œ ํ‚ค: problemId (๋ฌธ์ž์—ด).
    • ์†์„ฑ: problemId, creatorId, generationStatus, createdAt.
    • GSI:
      • CreatorIdIndex: creatorId (ํ•ด์‹œ) - ๋ชจ๋“  ์†์„ฑ ํ”„๋กœ์ ์…˜. (CreatorIdCreatedAtGSI๋กœ ์ถฉ๋ถ„ํ•˜๋ฉด ์ œ๊ฑฐ ๊ณ ๋ ค).
      • CompletedProblemsByCreatedAtGSI: generationStatus (ํ•ด์‹œ), createdAt (๋ฒ”์œ„) - ๋ชจ๋“  ์†์„ฑ ํ”„๋กœ์ ์…˜.
      • CreatorIdCreatedAtGSI: creatorId (ํ•ด์‹œ), createdAt (๋ฒ”์œ„) - ๋ชจ๋“  ์†์„ฑ ํ”„๋กœ์ ์…˜.
  • CloudFront ๋ฐฐํฌ (aws_cloudfront_distribution.problem_generator_v3 - cloudfront.tf):
    • ์˜ค๋ฆฌ์ง„: Lambda ํ•จ์ˆ˜ URL.
    • Origin Access Control (aws_cloudfront_origin_access_control.problem_generator_v3_oac): Lambda ํ•จ์ˆ˜ URL์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ๋ณดํ˜ธํ•˜์—ฌ CloudFront๋งŒ ํ—ˆ์šฉ. signing_behavior = "always", signing_protocol = "sigv4".
    • ์บ์‹œ ์ •์ฑ…: Managed-CachingDisabled.
    • ์˜ค๋ฆฌ์ง„ ์š”์ฒญ ์ •์ฑ…: Managed-AllViewerExceptHostHeader.
    • ์‘๋‹ต ํ—ค๋” ์ •์ฑ…: Managed-SimpleCORS.
    • ๋ทฐ์–ด ํ”„๋กœํ† ์ฝœ ์ •์ฑ…: redirect-to-https.
  • Lambda ๊ถŒํ•œ (permissions.tf):
    • aws_lambda_permission.problem_generator_v3_cloudfront: CloudFront ์„œ๋น„์Šค๊ฐ€ Lambda ํ•จ์ˆ˜ URL์„ ํ˜ธ์ถœํ•˜๋„๋ก ํ—ˆ์šฉ.

5.3 ์„ค์ • ๋ณ€์ˆ˜ (variables.tf)

๊ตฌ์„ฑํ•ด์•ผ ํ•˜๋Š” ์ฃผ์š” ๋ณ€์ˆ˜ (terraform.tfvars ๋˜๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์„ค์ •):

  • google_ai_api_key: Google AI (Gemini) API ํ‚ค. ๋ฏผ๊ฐ ์ •๋ณด. terraform.auto.tfvars.sample์— ์ƒ˜ํ”Œ ์žˆ์Œ.
  • code_executor_lambda_arn: ๋ฐฐํฌ๋œ Code Executor Lambda ํ•จ์ˆ˜์˜ ARN. ์ด๋Š” ์˜์กด์„ฑ์„ ์ƒ์„ฑํ•จ (6. ๋ฐฐํฌ ์ฐธ์กฐ).
  • project_name, environment, aws_region: ๋ฆฌ์†Œ์Šค ์ด๋ฆ„ ์ง€์ • ๋ฐ ์ง€์—ญ ๋ฐฐํฌ์šฉ.
  • lambda_runtime, lambda_handler, lambda_code_path: Lambda ํ•จ์ˆ˜ ๊ตฌ์„ฑ.
  • gemini_model_name, generator_verbose: LLM ๋ฐ ๋กœ๊น… ๊ตฌ์„ฑ.

5.4 Lambda ๋ ˆ์ด์–ด ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค

layers/ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ •์˜๋จ:

  • build-layer.sh: Node.js ์ข…์†์„ฑ ๋ ˆ์ด์–ด๋ฅผ ๋นŒ๋“œํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ.
    1. ์ด์ „ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    2. ../../backend/lambdas/problem-generator-v3/์—์„œ package.json ๋ฐ package-lock.json์„ ์ž„์‹œ Docker ๋นŒ๋“œ ์ปจํ…์ŠคํŠธ๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
    3. Dockerfile.build๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Docker ์ด๋ฏธ์ง€(problem-generator-layer-builder)๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.
    4. Dockerfile์€ /opt ๋‚ด๋ถ€์— ํ”„๋กœ๋•์…˜ ์ข…์†์„ฑ(npm ci --omit=dev)์„ ์„ค์น˜ํ•œ ๋‹ค์Œ Lambda ๋ ˆ์ด์–ด๊ฐ€ ์˜ˆ์ƒํ•˜๋Š” ๋Œ€๋กœ /opt/nodejs/node_modules๋กœ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.
    5. Docker ์ปจํ…Œ์ด๋„ˆ์—์„œ nodejs ๋””๋ ‰ํ„ฐ๋ฆฌ(node_modules ํฌํ•จ)๋ฅผ ๋กœ์ปฌ ์ถœ๋ ฅ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
    6. nodejs ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ problem_generator_deps.zip์œผ๋กœ ์••์ถ•ํ•ฉ๋‹ˆ๋‹ค.
  • Dockerfile.build: public.ecr.aws/lambda/nodejs:20-arm64 ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ข…์†์„ฑ์„ ์„ค์น˜ํ•˜๊ณ  Lambda ๋ ˆ์ด์–ด ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ๊ตฌ์กฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • layer.tf์˜ aws_lambda_layer_version ๋ฆฌ์†Œ์Šค๋Š” ์ด problem_generator_deps.zip์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • null_resource.build_lambda_layer๋Š” package-lock.json, ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ ๋˜๋Š” Dockerfile์ด ๋ณ€๊ฒฝ๋˜๋ฉด build-layer.sh ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

6. ๋ฐฐํฌ

6.1 ์ „์ œ ์กฐ๊ฑด

  • Terraform CLI ์„ค์น˜.
  • AWS CLI ์„ค์น˜ ๋ฐ ์ ์ ˆํ•œ ์ž๊ฒฉ ์ฆ๋ช… ๋ฐ ๋ฆฌ์ „์œผ๋กœ ๊ตฌ์„ฑ.
  • Google AI API ํ‚ค.
  • code-execution-service ๋ชจ๋“ˆ์ด ๋จผ์ € ๋ฐฐํฌ๋˜์–ด์•ผ ํ•˜๋ฉฐ, ํ•ด๋‹น Lambda ARN์ด ์ด ๋ชจ๋“ˆ์˜ ์ž…๋ ฅ๊ฐ’์ž…๋‹ˆ๋‹ค.
  • code-execution-service๊ฐ€ problems_table์˜ ARN์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ (์˜ˆ: readme.md์— ์„ค๋ช…๋œ ์ˆœํ™˜ ์˜์กด์„ฑ), problems_table(์ด ๋ชจ๋“ˆ)์ด ๋จผ์ € ๋ฐฐํฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

6.2 ๋ฐฐํฌ ๋‹จ๊ณ„

์ˆœํ™˜ ์˜์กด์„ฑ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋…ผ์˜๋Š” capstone-2025-04/infrastructure/problem-generator-v3/readme.md๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ถŒ์žฅ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  1. problem-generator-v3 1์ฐจ ๋ฐฐํฌ (๋ถ€๋ถ„):
    • variables.tf์—์„œ code_executor_lambda_arn์„ ์ž„์‹œ๋กœ ๋”๋ฏธ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ apply ์‹œ ๋นˆ ๋ณ€์ˆ˜๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • terraform init
    • terraform apply
    • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด problems_table์ด ์ƒ์„ฑ๋˜๊ณ  ํ•ด๋‹น ARN(problems_table_arn)์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  2. code-execution-service ๋ฐฐํฌ:
    • ์ด ๋ชจ๋“ˆ(ํŒŒ์ผ์— ์ œ๊ณต๋˜์ง€ ์•Š์•˜์ง€๋งŒ ์กด์žฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •)์€ data "terraform_remote_state"๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ problem-generator-v3 ์ƒํƒœ์—์„œ problems_table_arn์„ ์ฝ์Šต๋‹ˆ๋‹ค.
    • code-execution-service ๋ชจ๋“ˆ์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.
    • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด code_executor_lambda_arn์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  3. problem-generator-v3 2์ฐจ ๋ฐฐํฌ (์ „์ฒด):
    • 2๋‹จ๊ณ„์—์„œ ์–ป์€ ์‹ค์ œ code_executor_lambda_arn ๊ฐ’์œผ๋กœ problem-generator-v3์˜ terraform.tfvars ํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • problem-generator-v3 ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ๋‹ค์‹œ terraform apply๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Problem Generator Lambda๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ Code Executor ARN์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

infrastructure/problem-generator-v3/ ๋‚ด ์ผ๋ฐ˜์ ์ธ Terraform ๋ช…๋ น์–ด:

# Terraform ์ดˆ๊ธฐํ™” (๋ฐฑ์—”๋“œ ๊ตฌ์„ฑ ๋ณ€๊ฒฝ ์‹œ ํ•œ ๋ฒˆ ์‹คํ–‰)
terraform init

# ํŠน์ • ๊ฐ’์œผ๋กœ terraform.tfvars ์ƒ์„ฑ ๋˜๋Š” ์—…๋ฐ์ดํŠธ
# ์˜ˆ: google_ai_api_key = "YOUR_KEY"
#       code_executor_lambda_arn = "ARN_FROM_CODE_EXEC_SERVICE_OUTPUT" (2์ฐจ apply ์‹œ)

# ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๊ณ„ํš
terraform plan

# ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ ์šฉ
terraform apply
# (ํ”„๋กฌํ”„ํŠธ ํ‘œ์‹œ ์‹œ 'yes'๋กœ ํ™•์ธ)

# ๋ฆฌ์†Œ์Šค ์‚ญ์ œ (ํ•„์š”ํ•œ ๊ฒฝ์šฐ)
terraform destroy

6.3 ๋ชจ๋“ˆ ๊ฐ„ ์˜์กด์„ฑ

์ธํ”„๋ผ README์—์„œ ๊ฐ•์กฐ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์ž ์žฌ์ ์ธ ์ˆœํ™˜ ์˜์กด์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  • problem-generator-v3๋Š” code-execution-service์˜ code_executor_lambda_arn์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • code-execution-service๋Š” problem-generator-v3์˜ problems_table_arn์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์˜ˆ: ์‹คํ–‰ ์‹œ๋„ ๋กœ๊น… ๋˜๋Š” DB ์•ก์„ธ์Šค๊ฐ€ ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๊ฒ€์ฆ ๋‹จ๊ณ„์— ์ง์ ‘ ๊ด€์—ฌํ•˜๋Š” ๊ฒฝ์šฐ).

์œ„์— ์„ค๋ช…๋œ 3๋‹จ๊ณ„ ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค๋Š” terraform_remote_state๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋” ๊น”๋”ํ•œ ๋Œ€์•ˆ ์•„ํ‚คํ…์ฒ˜๋Š” DynamoDB ํ…Œ์ด๋ธ”์„ ๋‘ ์„œ๋น„์Šค ๋ชจ๋“ˆ์ด ๋ชจ๋‘ ์˜์กดํ•˜๋Š” ๋ณ„๋„์˜ ๊ณตํ†ต database ๋ชจ๋“ˆ๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.


7. ๋กœ์ปฌ ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ (๋ฐฑ์—”๋“œ)

problem-generator-v3์šฉ ๋ฐฑ์—”๋“œ Lambda ์ฝ”๋“œ๋Š” local-test.mjs ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

7.1 ์„ค์ •

  1. Lambda ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™:
    cd capstone-2025-04/backend/lambdas/problem-generator-v3/
    
  2. ์ข…์†์„ฑ ์„ค์น˜:
    npm install
    
  3. ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์— .env ํŒŒ์ผ ์ƒ์„ฑํ•˜๊ณ  Google AI API ํ‚ค๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค:
    # capstone-2025-04/backend/lambdas/problem-generator-v3/.env
    GOOGLE_AI_API_KEY="์‹ค์ œ_Google_AI_API_ํ‚ค_์ž…๋ ฅ"
    
    # ์„ ํƒ ์‚ฌํ•ญ: local-test.mjs ๋˜๋Š” constants.mjs์˜ ๊ธฐ๋ณธ๊ฐ’ ์žฌ์ •์˜
    # MOCK_DYNAMODB=true # ๋˜๋Š” false
    # PROBLEMS_TABLE_NAME=alpaco-Problems-v3-dev
    # GEMINI_MODEL_NAME=gemini-1.5-flash-latest
    # CODE_EXECUTOR_LAMBDA_ARN="๊ฐœ๋ฐœ์šฉ_์ฝ”๋“œ_์‹คํ–‰๊ธฐ_ARN"
    

    local-test.mjs ์Šคํฌ๋ฆฝํŠธ๋Š” ์ด .env ํŒŒ์ผ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

7.2 ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์‹คํ–‰

local-test.mjs ์Šคํฌ๋ฆฝํŠธ๋Š” Lambda ํ™˜๊ฒฝ ๋ฐ ํŒŒ์ดํ”„๋ผ์ธ ์‹คํ–‰์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๋Œ€ํ™”ํ˜• ๋ชจ๋“œ: ์‚ฌ์šฉ์ž ์ž…๋ ฅ(๋ฌธ์ œ ํ”„๋กฌํ”„ํŠธ, ๋‚œ์ด๋„ ๋“ฑ) ๋ฐ DynamoDB ๋ชจ๋“œ๋ฅผ ๋ฌป์Šต๋‹ˆ๋‹ค.
    node local-test.mjs
    
  • ์ž๋™ ๋ชจ๋“œ (์Šคํฌ๋ฆฝํŠธ์˜ sampleEvent ์‚ฌ์šฉ):
    • ๊ธฐ๋ณธ ์ž๋™ ๋ชจ๋“œ (์ธ์ˆ˜, .env, ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ณธ๊ฐ’ ์ˆœ์œผ๋กœ MOCK_DYNAMODB ์„ค์ • ์‚ฌ์šฉ):
      node local-test.mjs auto
      
    • Mock DynamoDB ๊ฐ•์ œ ์‚ฌ์šฉ:
      node local-test.mjs mock
      # ๋˜๋Š”
      node local-test.mjs auto mock
      
    • ์‹ค์ œ DynamoDB ๊ฐ•์ œ ์‚ฌ์šฉ (AWS ์ž๊ฒฉ ์ฆ๋ช… ๊ตฌ์„ฑ ํ•„์š”):
      node local-test.mjs real
      # ๋˜๋Š”
      node local-test.mjs auto real
      

์ถœ๋ ฅ:

  • ์ฝ˜์†” ๋กœ๊ทธ๋Š” SSE์™€ ์œ ์‚ฌํ•œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
  • ์ตœ์ข… ์ƒ์„ฑ๋œ ๋ฌธ์ œ(์„ฑ๊ณต ์‹œ)๋Š” problem-gen-result-[ํƒ€์ž„์Šคํƒฌํ”„].json์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

7.3 ๋ชจ์˜(Mocking) ์ฒ˜๋ฆฌ

  • DynamoDB: process.env.MOCK_DYNAMODB๊ฐ€ 'true'๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ local-test.mjs๋Š” ๋ชจ์˜ DynamoDB ๊ตฌํ˜„(mock-dynamodb.mjs)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ์˜ ๊ตฌํ˜„์€ ์ธ๋ฉ”๋ชจ๋ฆฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์ž…๋‹ˆ๋‹ค.
  • Code Executor Lambda: codeExecutor.mjs ์œ ํ‹ธ๋ฆฌํ‹ฐ๋Š” CODE_EXECUTOR_LAMBDA_ARN(constants.mjs์—์„œ ๊ฐ€์ ธ์˜ค๋ฉฐ .env๋กœ ์žฌ์ •์˜ ๊ฐ€๋Šฅ)์œผ๋กœ ์ง€์ •๋œ ์‹ค์ œ AWS Lambda๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. AWS ์—†์ด ์™„์ „ํžˆ ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด ์ด๋ฅผ ๋ชจ์˜ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ๋กœ์ปฌ Python ์‹คํ–‰ ํ•˜์œ„ ํ”„๋กœ์„ธ์Šค๋ฅผ (์ด์ „ ๋ฒ„์ „์—์„œ์ฒ˜๋Ÿผ) ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ Python ์ฝ”๋“œ ์‹คํ–‰์„ ์œ„ํ•œ ๋กœ์ปฌ ํ…Œ์ŠคํŠธ๋Š” ์—ฌ์ „ํžˆ ๋ฐฐํฌ๋œ AWS Code Executor Lambda์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค.

8. API ์‚ฌ์šฉ๋ฒ• (ํ”„๋ก ํŠธ์—”๋“œ ๊ด€์ )

frontend/src/api/generateProblemApi.ts ๋ฐ frontend/src/app/coding-test/solve/page.tsx ๊ธฐ๋ฐ˜.

8.1 ์—”๋“œํฌ์ธํŠธ

  • API ์—”๋“œํฌ์ธํŠธ๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜ NEXT_PUBLIC_PROBLEM_GENERATION_API_BASE_URL์„ ํ†ตํ•ด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • ์ด URL์€ CloudFront ๋ฐฐํฌ ๋„๋ฉ”์ธ ์ด๋ฆ„(์˜ˆ: d123abc.cloudfront.net)์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

8.2 ์ธ์ฆ

  • Lambda ํ•จ์ˆ˜ URL์€ AWS_IAM ์ธ์ฆ์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • CloudFront๋Š” SigV4 ์„œ๋ช…์„ ์‚ฌ์šฉํ•˜๋Š” Origin Access Control(OAC)์„ ์‚ฌ์šฉํ•˜์—ฌ Lambda ํ•จ์ˆ˜ URL์„ ์•ˆ์ „ํ•˜๊ฒŒ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ํ”„๋ก ํŠธ์—”๋“œ๋Š” AWS Amplify(fetchAuthSession)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ž๊ฒฉ ์ฆ๋ช…(์˜ˆ: Cognito ID ํ† ํฐ, ์ž„์‹œ AWS ์ž๊ฒฉ ์ฆ๋ช…์œผ๋กœ ๊ตํ™˜๋˜๊ฑฐ๋‚˜ ์š”์ฒญ ์„œ๋ช…์— ์‚ฌ์šฉ๋จ)์„ ๊ฐ€์ ธ์˜ฌ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.
  • CloudFront ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ์š”์ฒญ์€ Amplify๊ฐ€ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ ์ ˆํ•œ AWS SigV4 ํ—ค๋”๋ฅผ ํฌํ•จํ•ด์•ผ ํ•˜๊ฑฐ๋‚˜, Lambda URL ์ž์ฒด๊ฐ€ IAM์œผ๋กœ ๋ณดํ˜ธ๋˜๊ณ  CloudFront๊ฐ€ ๋‹จ์ˆœํžˆ ํ†ต๊ณผํ•˜๋Š” ๊ฒฝ์šฐ CloudFront๊ฐ€ IAM์„ ์ ์šฉํ•˜๋„๋ก ์˜์กดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. generateProblemApi.ts์˜ Authorization: Bearer ${idToken} ๋ฐ x-amz-content-sha256 ํ—ค๋”๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ IAM ์„œ๋ช…๋œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜ CloudFront๊ฐ€ ์˜ค๋ฆฌ์ง„์— ๋Œ€ํ•œ ์š”์ฒญ์„ ๋‹ค์‹œ ์„œ๋ช…ํ•˜๋Š” ํ†ต๊ณผ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค. OAC signing_behavior = "always"์ด๋ฏ€๋กœ CloudFront๋Š” ์˜ค๋ฆฌ์ง„(Lambda URL)์— ๋Œ€ํ•œ ์š”์ฒญ์— ์„œ๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ CloudFront ์ž์ฒด์— ๋ณด๋‚ด๋Š” ์š”์ฒญ์€ CloudFront WAF/๋™์ž‘ ์„ค์ •์— ๋”ฐ๋ผ IAM ์ธ์ฆ๋˜๊ฑฐ๋‚˜ ๊ณต๊ฐœ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

8.3 ์š”์ฒญ

  • ๋ฉ”์„œ๋“œ: POST
  • ํ—ค๋”:
    • Content-Type: application/json
    • Authorization: Bearer <ID_TOKEN> (Cognito๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ. OAC๊ฐ€ ์žˆ๋Š” ์ง์ ‘ Lambda URL์˜ ๊ฒฝ์šฐ CloudFront๊ฐ€ ์˜ค๋ฆฌ์ง„์— ๋Œ€ํ•œ ์ธ์ฆ์„ ์ฒ˜๋ฆฌ)
    • x-amz-content-sha256: ์š”์ฒญ ํŽ˜์ด๋กœ๋“œ์˜ SHA256 ํ•ด์‹œ (SigV4 ํ‘œ์ค€).
  • ๋ณธ๋ฌธ (CreateProblemRequest):
    {
      "prompt": "string (์‚ฌ์šฉ์ž ๋ฌธ์ œ ์•„์ด๋””์–ด)",
      "difficulty": "Easy" | "Medium" | "Hard", // ๋˜๋Š” ํ”„๋ก ํŠธ์—”๋“œ ํƒ€์ž…์— ๋”ฐ๋ผ "ํŠœํ† ๋ฆฌ์–ผ", "์‰ฌ์›€", "๋ณดํ†ต", "์–ด๋ ค์›€"
      "creatorId": "string (์„ ํƒ ์‚ฌํ•ญ, ์‚ฌ์šฉ์ž ID)",
      "author": "string (์„ ํƒ ์‚ฌํ•ญ, ์‚ฌ์šฉ์ž ํ‘œ์‹œ ์ด๋ฆ„)"
    }
    

8.4 ์‘๋‹ต (SSE ์ŠคํŠธ๋ฆผ)

API๋Š” ์„œ๋ฒ„-์ „์†ก ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ(Content-Type: text/event-stream)์œผ๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

event: <์ด๋ฒคํŠธ_ํƒ€์ž…>
data: <JSON_ํŽ˜์ด๋กœ๋“œ>

  • event: status
    • ํŽ˜์ด๋กœ๋“œ (ProblemStreamStatus):
      {
        "step": number (ํ˜„์žฌ ํŒŒ์ดํ”„๋ผ์ธ ๋‹จ๊ณ„),
        "message": "string (์ƒํƒœ ๋ฉ”์‹œ์ง€)"
      }
      
  • event: result
    • ํŽ˜์ด๋กœ๋“œ (ProblemStreamResult - ProblemDetailAPI ๋ž˜ํ•‘):
      {
        "payload": { /* ProblemDetailAPI ๊ฐ์ฒด */ }
      }
      

      ProblemDetailAPI ๊ฐ์ฒด ํฌํ•จ ๋‚ด์šฉ: problemId, title, title_translated, description, description_translated, difficulty, constraints (JSON ๋ฌธ์ž์—ด), solutionCode, startCode, finalTestCases (ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๋ฐฐ์—ด์˜ JSON ๋ฌธ์ž์—ด), generationStatus, language, targetLanguage, createdAt, completedAt, userPrompt, errorMessage, validationDetails, creatorId, author, judgeType, epsilon, schemaVersion.

  • event: error
    • ํŽ˜์ด๋กœ๋“œ (ProblemStreamError):
      {
        "payload": "string (์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€)"
      }
      

์ƒ์„ฑ์ด ์™„๋ฃŒ๋˜๊ฑฐ๋‚˜ ์น˜๋ช…์ ์ธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ŠคํŠธ๋ฆผ์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ์˜ onComplete ์ฝœ๋ฐฑ์ด ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.


9. ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐ ์•Œ๋ ค์ง„ ๋ฌธ์ œ

  • LLM ์‹คํŒจ:
    • ์ž˜๋ชป๋œ ํ˜•์‹์˜ JSON ์ถœ๋ ฅ: LLM์ด ๊ฐ€๋” ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํŒŒ์‹ฑ๋˜์ง€ ์•Š๋Š” JSON์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. intentAnalysis ์ฒด์ธ์—๋Š” ์ผ๋ถ€ ๋ณต๊ตฌ ๋กœ์ง(cleanJsonOutput)์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ์ฒด์ธ์—๋Š” LangChain์˜ ๊ตฌ์กฐํ™”๋œ ์ถœ๋ ฅ ๊ธฐ๋Šฅ(withStructuredOutput)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
    • ๋น„์–ด ์žˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ์ฝ˜ํ…์ธ : LLM์ด ๋นˆ ๋ฌธ์ž์—ด์ด๋‚˜ ์˜๋ฏธ ์—†๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. pipeline.mjs์˜ ์žฌ์‹œ๋„ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์ด๋ฅผ ์™„ํ™”ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
    • API ์†๋„ ์ œํ•œ/์˜ค๋ฅ˜: Google AI API ํ‚ค๊ฐ€ ์œ ํšจํ•˜๊ณ  ์ถฉ๋ถ„ํ•œ ํ• ๋‹น๋Ÿ‰์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐฐํฌ ๋ฌธ์ œ:
    • ์ˆœํ™˜ ์˜์กด์„ฑ: problem-generator-v3์™€ code-execution-service๊ฐ€ ์„œ๋กœ์˜ ์ถœ๋ ฅ์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ 3๋‹จ๊ณ„ ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.
    • IAM ๊ถŒํ•œ: ์ž˜๋ชป๋œ IAM ์ •์ฑ…์€ Lambda ํ•จ์ˆ˜๊ฐ€ DynamoDB์— ์•ก์„ธ์Šคํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ Lambda๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์•ก์„ธ์Šค ๊ฑฐ๋ถ€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. iam.tf์˜ ์ •์ฑ…์„ ๋‹ค์‹œ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ์„ค์ •:
    • GOOGLE_AI_API_KEY๋Š” Lambda ํ™˜๊ฒฝ ๋ณ€์ˆ˜(Terraform์„ ํ†ตํ•ด)์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • CODE_EXECUTOR_LAMBDA_ARN์€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ฐฐํฌ๋˜๊ณ  ์ž‘๋™ํ•˜๋Š” Code Executor Lambda๋ฅผ ๊ฐ€๋ฆฌ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ์‹คํ–‰:
    • ์‹œ๊ฐ„ ์ดˆ๊ณผ: ์ƒ์„ฑ ๋˜๋Š” ์‹คํ–‰์— ๋„ˆ๋ฌด ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฉด Code Executor Lambda ๋˜๋Š” Problem Generator Lambda ์ž์ฒด๊ฐ€ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋‹น ์†”๋ฃจ์…˜ ์‹คํ–‰์—๋Š” EXECUTION_TIMEOUT_MS๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    • Python ํ™˜๊ฒฝ: ์ƒ์„ฑ๋œ ์†”๋ฃจ์…˜์— ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ Code Executor Lambda์˜ Python ํ™˜๊ฒฝ์— ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (ํ˜„์žฌ ํ”„๋กฌํ”„ํŠธ๋Š” ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์†”๋ฃจ์…˜์„ ๋ชฉํ‘œ๋กœ ํ•จ).
  • ๋กœ์ปฌ ํ…Œ์ŠคํŠธ:
    • .env ํŒŒ์ผ์€ backend/lambdas/problem-generator-v3/์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • Python ์ฝ”๋“œ์˜ ๋กœ์ปฌ ์‹คํ–‰(4.a ๋‹จ๊ณ„)์€ ์—ฌ์ „ํžˆ ๋ฐฐํฌ๋œ AWS Code Executor Lambda์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์™„์ „ํžˆ ์˜คํ”„๋ผ์ธ์œผ๋กœ ๋กœ์ปฌ Python ์‹คํ–‰์„ ํ•˜๋ ค๋ฉด codeExecutor.mjs์— ๋กœ์ปฌ Python ํ•˜์œ„ ํ”„๋กœ์„ธ์Šค ์‹คํ–‰๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • SSE ์ŠคํŠธ๋ฆผ ์ค‘๋‹จ: ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ๋กœ ์ธํ•ด SSE ์ŠคํŠธ๋ฆผ์ด ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์žฌ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (์ œ๊ณต๋œ generateProblemApi.ts์—๋Š” ๋ช…์‹œ์ ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š์Œ).