Skip to content

Latest commit

ย 

History

History
539 lines (425 loc) ยท 18 KB

File metadata and controls

539 lines (425 loc) ยท 18 KB

AI ์œค๋ฆฌ ์ฑ—๋ด‡ API ๋ช…์„ธ์„œ (ํ”„๋ก ํŠธ์—”๋“œ์šฉ)

๐Ÿ“‹ ๋ชฉ์ฐจ

  1. ๊ฐœ์š”
  2. API ์—”๋“œํฌ์ธํŠธ
  3. ๋‹จ๊ณ„ ์ˆœ์„œ ๋ฐ ๋ฐ์ดํ„ฐ ํ๋ฆ„
  4. ๋‹จ๊ณ„๋ณ„ ์ƒ์„ธ ๋ช…์„ธ
  5. ์—๋Ÿฌ ์ฒ˜๋ฆฌ

๊ฐœ์š”

Base URL: https://dilemmai.org

์ฃผ์š” ์—”๋“œํฌ์ธํŠธ: POST /chat/multi-step

๋‹จ๊ณ„ ์ˆœ์„œ: opening โ†’ question โ†’ flip โ†’ roles โ†’ ending


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

POST /chat/multi-step

๋‹ค๋‹จ๊ณ„ ์ฑ—๋ด‡ ๋Œ€ํ™” ์ง„ํ–‰

Request Body

{
  "session_id": "unique-session-id",
  "user_input": "์‚ฌ์šฉ์ž ์ž…๋ ฅ ํ…์ŠคํŠธ",
  "step": "opening",  // ์„ ํƒ์‚ฌํ•ญ (์ฒซ ์š”์ฒญ์—๋งŒ ๋ช…์‹œ, ์ดํ›„๋Š” ์ž๋™ ์ง„ํ–‰)
  "variable": {       // ์„ ํƒ์‚ฌํ•ญ (ํ…Œ์ŠคํŠธ์šฉ ๋˜๋Š” ํŠน์ • ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ์ „๋‹ฌํ•  ๋•Œ)
    "topic": "AI ์œค๋ฆฌ",
    "question": "...",
    "choice1": "...",
    "choice2": "..."
  }
}

ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค๋ช…:

  • session_id (ํ•„์ˆ˜): ์„ธ์…˜ ๊ณ ์œ  ID
  • user_input (ํ•„์ˆ˜): ์‚ฌ์šฉ์ž ์ž…๋ ฅ ํ…์ŠคํŠธ
  • step (์„ ํƒ): ์‹คํ–‰ํ•  ๋‹จ๊ณ„ ์ง€์ • (์ฒซ ์š”์ฒญ์—๋งŒ ์‚ฌ์šฉ)
  • variable (์„ ํƒ): OpenAI ํ”„๋กฌํ”„ํŠธ์— ์ง์ ‘ ์ „๋‹ฌํ•  ๋ณ€์ˆ˜๋“ค (ํ…Œ์ŠคํŠธ ๋˜๋Š” ๋””๋ฒ„๊น…์šฉ)

Response

{
  "session_id": "unique-session-id",
  "current_step": "opening",
  "response_text": "์ฑ—๋ด‡ ์‘๋‹ต ํ…์ŠคํŠธ (์‚ฌ์šฉ์ž์—๊ฒŒ ํ‘œ์‹œ)",
  "parsed_variables": {
    // ๋‹จ๊ณ„๋ณ„๋กœ ์ถ”์ถœ๋œ ๊ตฌ์กฐํ™”๋œ ๋ณ€์ˆ˜๋“ค
  },
  "context": {
    // ์ „์ฒด ๋Œ€ํ™” ์ปจํ…์ŠคํŠธ (๋ชจ๋“  ์ด์ „ ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ)
  },
  "next_step": "question",  // ๋‹ค์Œ ๋‹จ๊ณ„ (๋งˆ์ง€๋ง‰์ด๋ฉด null)
  "is_complete": false      // ์™„๋ฃŒ ์—ฌ๋ถ€ (ending ๋‹จ๊ณ„์—์„œ true)
}

๋‹จ๊ณ„ ์ˆœ์„œ ๋ฐ ๋ฐ์ดํ„ฐ ํ๋ฆ„

opening โ†’ question โ†’ flip โ†’ roles โ†’ ending
๋‹จ๊ณ„ ์ž…๋ ฅ ๋ณ€์ˆ˜ ์ถœ๋ ฅ ๋ณ€์ˆ˜ (parsed_variables)
opening ์—†์Œ topic
question topic question, choice1, choice2
flip question, choice1, choice2 dilemma_situation, question, choice1, flips_agree_texts, choice2, flips_disagree_texts
roles flip์˜ 6๊ฐœ ๋ณ€์ˆ˜ char1, chardes1, char2, chardes2, char3, chardes3
ending flip์˜ 6๊ฐœ + roles์˜ 6๊ฐœ opening, char1~3, chardes1~3, dilemma_situation, question, agree_label, disagree_label, flips_agree_texts, flips_disagree_texts, agreeEnding, disagreeEnding

๋ณ€์ˆ˜ ์ „๋‹ฌ ๋ฐฉ์‹

  • ๋ฐฑ์—”๋“œ๋Š” context์— {step}_{variable} ํ˜•์‹์œผ๋กœ ์ €์žฅ (์˜ˆ: opening_topic)
  • ๋‹ค์Œ ๋‹จ๊ณ„ ํ˜ธ์ถœ ์‹œ ์ž๋™์œผ๋กœ ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ๋งคํ•‘ํ•˜์—ฌ OpenAI ํ”„๋กฌํ”„ํŠธ์— ์ „๋‹ฌ
  • ํ”„๋ก ํŠธ์—”๋“œ๋Š” ์‹ ๊ฒฝ ์“ธ ํ•„์š” ์—†์Œ (๋ฐฑ์—”๋“œ๊ฐ€ ์ž๋™ ์ฒ˜๋ฆฌ)

๋‹จ๊ณ„๋ณ„ ์ƒ์„ธ ๋ช…์„ธ

1๏ธโƒฃ Opening ๋‹จ๊ณ„

์œ ์ € ํ–‰๋™: ์ฃผ์ œ ํ™•์ •

์ฑ—๋ด‡ ํ–‰๋™: parsed_variables์— topic ๋ฐ˜ํ™˜

๋‹ค์Œ ๋‹จ๊ณ„: ์œ ์ €๊ฐ€ "๋‹ค์Œ ๋‹จ๊ณ„" ์ž…๋ ฅ โ†’ question ๋‹จ๊ณ„๋กœ ์ด๋™

parsed_variables ๊ตฌ์กฐ

{
  topic: string  // ํ™•์ •๋œ AI ์ฃผ์ œ
}

Response ์˜ˆ์‹œ

{
  "session_id": "session-123",
  "current_step": "opening",
  "response_text": "[์ฑ—๋ด‡์ด ์ƒ์„ฑํ•œ ์‘๋‹ต ํ…์ŠคํŠธ]",
  "parsed_variables": {
    "topic": "AI ์œค๋ฆฌ"
  },
  "next_step": "question",
  "is_complete": false
}

2๏ธโƒฃ Question ๋‹จ๊ณ„

์ž…๋ ฅ: opening ๋‹จ๊ณ„์—์„œ ๋ฐ›์€ topic

์œ ์ € ํ–‰๋™: ์งˆ๋ฌธ ํ™•์ •

์ฑ—๋ด‡ ํ–‰๋™: parsed_variables์— question, choice1, choice2 ๋ฐ˜ํ™˜

๋‹ค์Œ ๋‹จ๊ณ„: ์œ ์ €๊ฐ€ "๋‹ค์Œ ๋‹จ๊ณ„" ์ž…๋ ฅ โ†’ flip ๋‹จ๊ณ„๋กœ ์ด๋™ (question, choice1, choice2๋ฅผ variable๋กœ ์ „๋‹ฌ)

parsed_variables ๊ตฌ์กฐ

{
  question: string   // ๋”œ๋ ˆ๋งˆ ์งˆ๋ฌธ
  choice1: string    // ์„ ํƒ์ง€ 1
  choice2: string    // ์„ ํƒ์ง€ 2
}

Response ์˜ˆ์‹œ

{
  "session_id": "session-123",
  "current_step": "question",
  "response_text": "[์ฑ—๋ด‡์ด ์ƒ์„ฑํ•œ ์‘๋‹ต ํ…์ŠคํŠธ]",
  "parsed_variables": {
    "question": "AI ์‹œ์Šคํ…œ์ด ์ตœ๋Œ€ํ•œ ์ •ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์„ ํƒ์„ ํ•ด์•ผ ํ• ๊นŒ์š”?",
    "choice1": "์ •ํ™•์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํŠน์ • ์ง‘๋‹จ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ๊ฐ€?",
    "choice2": "๊ณต์ •์„ฑ์„ ์œ„ํ•ด ๋ชจ๋“  ์ง‘๋‹จ์— ๋Œ€ํ•ด ๊ท ํ˜• ์žกํžŒ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•  ๊ฒƒ์ธ๊ฐ€?"
  },
  "next_step": "flip",
  "is_complete": false
}

3๏ธโƒฃ Flip ๋‹จ๊ณ„

์ž…๋ ฅ: question ๋‹จ๊ณ„์—์„œ ๋ฐ›์€ question, choice1, choice2

์ฑ—๋ด‡ ํ–‰๋™: ์‹œ๋‚˜๋ฆฌ์˜ค์™€ ํ”Œ๋ฆฝ ์ƒํ™ฉ ๊ฒฐ์ •

์ถœ๋ ฅ: parsed_variables์— 6๊ฐœ ๋ณ€์ˆ˜ ๋ฐ˜ํ™˜

  • dilemma_situation: ์ƒํ™ฉ ์‹œ๋‚˜๋ฆฌ์˜ค
  • question: ์งˆ๋ฌธ
  • choice1: ์„ ํƒ์ง€ 1 (agree_label)
  • flips_agree_texts: ์„ ํƒ์ง€ 1์— ๋Œ€ํ•œ ํ”Œ๋ฆฝ ์ž๋ฃŒ
  • choice2: ์„ ํƒ์ง€ 2 (disagree_label)
  • flips_disagree_texts: ์„ ํƒ์ง€ 2์— ๋Œ€ํ•œ ํ”Œ๋ฆฝ ์ž๋ฃŒ

๋‹ค์Œ ๋‹จ๊ณ„: ์œ ์ €๊ฐ€ "๋‹ค์Œ ๋‹จ๊ณ„" ์ž…๋ ฅ โ†’ roles ๋‹จ๊ณ„๋กœ ์ด๋™ (์œ„ 6๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌ)

parsed_variables ๊ตฌ์กฐ

{
  dilemma_situation: string   // ์ƒํ™ฉ ์‹œ๋‚˜๋ฆฌ์˜ค
  question: string            // ๋”œ๋ ˆ๋งˆ ์งˆ๋ฌธ
  choice1: string             // ์„ ํƒ์ง€ 1
  flips_agree_texts: string   // ์„ ํƒ์ง€ 1 ํ”Œ๋ฆฝ ์ž๋ฃŒ
  choice2: string             // ์„ ํƒ์ง€ 2
  flips_disagree_texts: string // ์„ ํƒ์ง€ 2 ํ”Œ๋ฆฝ ์ž๋ฃŒ
}

Response ์˜ˆ์‹œ

{
  "session_id": "session-123",
  "current_step": "flip",
  "response_text": "[์ฑ—๋ด‡์ด ์ƒ์„ฑํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์™€ ํ”Œ๋ฆฝ ์ƒํ™ฉ ํ…์ŠคํŠธ]",
  "parsed_variables": {
    "dilemma_situation": "AI ์‹œ์Šคํ…œ์ด ํ•™๊ต์—์„œ ํ•™์ƒ๋“ค์˜ ์„ฑ์ ์„ ์˜ˆ์ธกํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค...",
    "question": "AI ์‹œ์Šคํ…œ์ด ์ตœ๋Œ€ํ•œ ์ •ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด...",
    "choice1": "์ •ํ™•์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํŠน์ • ์ง‘๋‹จ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ๊ฐ€?",
    "flips_agree_texts": "์ •ํ™•์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ๋‹ค์ˆ˜ ์ง‘๋‹จ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•œ ๊ฒฐ๊ณผ...",
    "choice2": "๊ณต์ •์„ฑ์„ ์œ„ํ•ด ๋ชจ๋“  ์ง‘๋‹จ์— ๋Œ€ํ•ด ๊ท ํ˜• ์žกํžŒ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•  ๊ฒƒ์ธ๊ฐ€?",
    "flips_disagree_texts": "๋ชจ๋“  ์ง‘๋‹จ์— ๋Œ€ํ•ด ๊ท ํ˜• ์žกํžŒ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ์˜ ๊ท ํ˜•์„ ๋งž์ถ˜ ๊ฒฐ๊ณผ..."
  },
  "next_step": "roles",
  "is_complete": false
}

4๏ธโƒฃ Roles ๋‹จ๊ณ„

์ž…๋ ฅ: flip ๋‹จ๊ณ„์—์„œ ๋ฐ›์€ 6๊ฐœ ๋ณ€์ˆ˜

  • dilemma_situation, question, choice1, flips_agree_texts, choice2, flips_disagree_texts

์ฑ—๋ด‡ ํ–‰๋™: ์—ญํ• ๊ทน ์ธ๋ฌผ 3๋ช… ์„ค๊ณ„

์ถœ๋ ฅ: parsed_variables์— 6๊ฐœ ๋ณ€์ˆ˜ ๋ฐ˜ํ™˜

  • char1, charDes1: ์—ญํ•  1 ์ด๋ฆ„ ๋ฐ ๋ฐฐ๊ฒฝ ์„ค๋ช…
  • char2, charDes2: ์—ญํ•  2 ์ด๋ฆ„ ๋ฐ ๋ฐฐ๊ฒฝ ์„ค๋ช…
  • char3, charDes3: ์—ญํ•  3 ์ด๋ฆ„ ๋ฐ ๋ฐฐ๊ฒฝ ์„ค๋ช…

๋‹ค์Œ ๋‹จ๊ณ„: ์œ ์ €๊ฐ€ "๋‹ค์Œ ๋‹จ๊ณ„" ์ž…๋ ฅ โ†’ ending ๋‹จ๊ณ„๋กœ ์ด๋™ (flip 6๊ฐœ + roles 6๊ฐœ ๋ณ€์ˆ˜ ์ „๋‹ฌ)

parsed_variables ๊ตฌ์กฐ

{
  char1: string      // ์—ญํ•  1 ์ด๋ฆ„
  chardes1: string   // ์—ญํ•  1 ๋ฐฐ๊ฒฝ ์„ค๋ช…
  char2: string      // ์—ญํ•  2 ์ด๋ฆ„
  chardes2: string   // ์—ญํ•  2 ๋ฐฐ๊ฒฝ ์„ค๋ช…
  char3: string      // ์—ญํ•  3 ์ด๋ฆ„
  chardes3: string   // ์—ญํ•  3 ๋ฐฐ๊ฒฝ ์„ค๋ช…
}

Response ์˜ˆ์‹œ

{
  "session_id": "session-123",
  "current_step": "roles",
  "response_text": "[์ฑ—๋ด‡์ด ์ƒ์„ฑํ•œ ์—ญํ•  ์ œ์•ˆ ํ…์ŠคํŠธ]",
  "parsed_variables": {
    "char1": "ํ•™์ƒ",
    "chardes1": "๋‹น์‹ ์€ ์ค‘ํ•™๊ต 3ํ•™๋…„ ํ•™์ƒ์ด๋ฉฐ, AI ์‹œ์Šคํ…œ์˜ ์„ฑ์  ์˜ˆ์ธก ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ž˜ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค...",
    "char2": "๊ต์‚ฌ",
    "chardes2": "๋‹น์‹ ์€ 10๋…„ ๊ฒฝ๋ ฅ์˜ ๊ณ ๋“ฑํ•™๊ต ๊ต์‚ฌ์ž…๋‹ˆ๋‹ค...",
    "char3": "ํ•™๋ถ€๋ชจ",
    "chardes3": "๋‹น์‹ ์€ ์ค‘ํ•™๊ต 1ํ•™๋…„ ์ž๋…€๋ฅผ ๋‘” ํ•™๋ถ€๋ชจ๋กœ..."
  },
  "next_step": "ending",
  "is_complete": false
}

5๏ธโƒฃ Ending ๋‹จ๊ณ„

์ž…๋ ฅ: flip ๋‹จ๊ณ„์˜ 6๊ฐœ ๋ณ€์ˆ˜ + roles ๋‹จ๊ณ„์˜ 6๊ฐœ ๋ณ€์ˆ˜ (์ด 12๊ฐœ)

์ฑ—๋ด‡ ํ–‰๋™: ์ตœ์ข… ํ…œํ”Œ๋ฆฟ ์™„์„ฑ (์˜คํ”„๋‹, ์—ญํ• , ์‹œ๋‚˜๋ฆฌ์˜ค, ์งˆ๋ฌธ, ์„ ํƒ์ง€, ํ”Œ๋ฆฝ ์ž๋ฃŒ, ์ตœ์ข… ๋ฉ˜ํŠธ ํฌํ•จ)

์ถœ๋ ฅ: parsed_variables์— 15๊ฐœ ๋ณ€์ˆ˜ ๋ฐ˜ํ™˜

์™„๋ฃŒ: is_complete: true, next_step: null

parsed_variables ๊ตฌ์กฐ

{
  opening: string[]            // ์˜คํ”„๋‹ ๋ฉ˜ํŠธ (๋ฌธ์žฅ ๋ฐฐ์—ด)
  char1: string                // ์—ญํ•  1 ์ด๋ฆ„
  chardes1: string             // ์—ญํ•  1 ๋ฐฐ๊ฒฝ ์„ค๋ช…
  char2: string                // ์—ญํ•  2 ์ด๋ฆ„
  chardes2: string             // ์—ญํ•  2 ๋ฐฐ๊ฒฝ ์„ค๋ช…
  char3: string                // ์—ญํ•  3 ์ด๋ฆ„
  chardes3: string             // ์—ญํ•  3 ๋ฐฐ๊ฒฝ ์„ค๋ช…
  dilemma_situation: string[]  // ์ƒํ™ฉ ์‹œ๋‚˜๋ฆฌ์˜ค (๋ฌธ์žฅ ๋ฐฐ์—ด)
  question: string             // ๋”œ๋ ˆ๋งˆ ์งˆ๋ฌธ
  agree_label: string          // ์„ ํƒ์ง€ 1 ๋ผ๋ฒจ
  disagree_label: string       // ์„ ํƒ์ง€ 2 ๋ผ๋ฒจ
  flips_agree_texts: string[]  // ์„ ํƒ์ง€ 1 ํ”Œ๋ฆฝ ์ž๋ฃŒ (๋ฌธ์žฅ ๋ฐฐ์—ด)
  flips_disagree_texts: string[] // ์„ ํƒ์ง€ 2 ํ”Œ๋ฆฝ ์ž๋ฃŒ (๋ฌธ์žฅ ๋ฐฐ์—ด)
  agreeEnding: string          // ์„ ํƒ์ง€ 1 ์ตœ์ข… ๋ฉ˜ํŠธ
  disagreeEnding: string       // ์„ ํƒ์ง€ 2 ์ตœ์ข… ๋ฉ˜ํŠธ
}

Response ์˜ˆ์‹œ

{
  "session_id": "session-123",
  "current_step": "ending",
  "response_text": "[์ฑ—๋ด‡์ด ์ƒ์„ฑํ•œ ์ตœ์ข… ์ดˆ์•ˆ ํ…์ŠคํŠธ]",
  "parsed_variables": {
    "opening": [
      "ํ•™๊ต์˜ AI ์‹œ์Šคํ…œ์ด ๋„์ž…๋œ ์ง€ ํ•œ ๋‹ฌ์ด ์ง€๋‚ฌ์Šต๋‹ˆ๋‹ค.",
      "ํ•™์ƒ๋“ค์˜ ์„ฑ์ ์„ ์˜ˆ์ธกํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋œ ์ด ์‹œ์Šคํ…œ์€ ํ•™๋ถ€๋ชจ์™€ ๊ต์‚ฌ๋“ค ์‚ฌ์ด์—์„œ ๊ธฐ๋Œ€์™€ ์šฐ๋ ค๋ฅผ ๋™์‹œ์— ๋ถˆ๋Ÿฌ์ผ์œผํ‚ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.",
      "์˜ค๋Š˜, ํ•™๊ต๋Š” ๋ฐ˜๋Œ€์™€ ์ฐฌ์„ฑ์„ ๋‚˜๋ˆ„๋Š” ๊ณต์ฒญํšŒ๋ฅผ ๊ฐœ์ตœํ•˜๊ธฐ๋กœ ํ•˜์˜€๊ณ , ์ด ์ž๋ฆฌ์—๋Š” AI ์‹œ์Šคํ…œ ๊ฐœ๋ฐœ์ž, ํ•™์ƒ ๋Œ€ํ‘œ, ๊ทธ๋ฆฌ๊ณ  ํ•™๋ถ€๋ชจ๊ฐ€ ๋ชจ์˜€์Šต๋‹ˆ๋‹ค.",
      "์—ฌ๋Ÿฌ๋ถ„์€ ๊ฐ์ž์˜ ์ž…์žฅ์—์„œ ์ด ์‹ ๊ธฐ์ˆ ์˜ ์œค๋ฆฌ์  ๋ฌธ์ œ๋ฅผ ํ† ๋ก ํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค."
    ],
    "char1": "AI ์‹œ์Šคํ…œ ๊ฐœ๋ฐœ์ž",
    "chardes1": "๋‹น์‹ ์€ ํ•œ ๋Œ€ํ•™๊ต์˜ ์ปดํ“จํ„ฐ ๊ณตํ•™๊ณผ์—์„œ AI ์‹œ์Šคํ…œ์„ ์—ฐ๊ตฌํ•˜๋Š” ๊ต์ˆ˜์ž…๋‹ˆ๋‹ค...",
    "char2": "ํ•™์ƒ ๋Œ€ํ‘œ",
    "chardes2": "๋‹น์‹ ์€ ๊ณ ๋“ฑํ•™๊ต 3ํ•™๋…„ ํ•™์ƒ์œผ๋กœ, ํ•™๊ต์˜ ํ•™์ƒํšŒ์—์„œ ํ™œ๋™ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค...",
    "char3": "ํ•™๋ถ€๋ชจ",
    "chardes3": "๋‹น์‹ ์€ ์ค‘ํ•™์ƒ์„ ๋‘” ๋ถ€๋ชจ๋กœ, ์ž๋…€์˜ ๊ต์œก๊ณผ ์•ˆ์ „์— ๊ด€์‹ฌ์ด ๋งŽ์Šต๋‹ˆ๋‹ค...",
    "dilemma_situation": [
      "AI ์‹œ์Šคํ…œ์ด ํ•™๊ต์—์„œ ํ•™์ƒ๋“ค์˜ ์„ฑ์ ์„ ์˜ˆ์ธกํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.",
      "์ด ์‹œ์Šคํ…œ์€ ์ฒ˜์Œ ๋„์ž…๋  ๋•Œ ํ•™์ƒ๋“ค์˜ ๊ฐœ์ธ์ ์ธ ์„ฑํ–ฅ๊ณผ ๋ฐ˜์‘์„ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ , ๊ฐ๊ด€์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.",
      "์ตœ๊ทผ ์ด ์‹œ์Šคํ…œ์˜ ์ •ํ™•์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด ๋ฐฉ์•ˆ์ด ์ œ์‹œ๋˜์—ˆ๊ณ , ๊ทธ ๊ณผ์ •์—์„œ ํŠน์ • ์ง‘๋‹จ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋…ผ์˜๊ฐ€ ์ผ๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.",
      "๊ทธ๋Ÿฌ๋‚˜ ์ด๋กœ ์ธํ•ด ๊ณต์ •์„ฑ๊ณผ ์ฐจ๋ณ„์ ์ธ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์šฐ๋ ค๊ฐ€ ์ปค์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค."
    ],
    "question": "AI ์‹œ์Šคํ…œ์ด ์ตœ๋Œ€ํ•œ ์ •ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์„ ํƒ์„ ํ•ด์•ผ ํ• ๊นŒ์š”?",
    "agree_label": "์ •ํ™•์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํŠน์ • ์ง‘๋‹จ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ๊ฐ€?",
    "disagree_label": "๊ณต์ •์„ฑ์„ ์œ„ํ•ด ๋ชจ๋“  ์ง‘๋‹จ์— ๋Œ€ํ•ด ๊ท ํ˜• ์žกํžŒ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•  ๊ฒƒ์ธ๊ฐ€?",
    "flips_agree_texts": [
      "์ •ํ™•์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ๋‹ค์ˆ˜ ์ง‘๋‹จ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•œ ๊ฒฐ๊ณผ, ํŠน์ • ์ง‘๋‹จ์ด ๊ณผ์†Œํ‰๊ฐ€๋˜๊ณ  ์ฐจ๋ณ„๋ฐ›๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.",
      "์ด๋Š” ํ•™๋ถ€๋ชจ์™€ ํ•™์ƒ๋“ค ์‚ฌ์ด์—์„œ ํฐ ๋…ผ๋ž€์ด ์ผ์–ด๋‚˜๊ฒŒ ํ–ˆ์œผ๋ฉฐ, ๊ฒฐ๊ตญ ํ•™๊ต๋Š” ์‹ ๋ขฐ๋ฅผ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค."
    ],
    "flips_disagree_texts": [
      "๋ชจ๋“  ์ง‘๋‹จ์— ๋Œ€ํ•ด ๊ท ํ˜• ์žกํžŒ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ์˜ ๊ท ํ˜•์„ ๋งž์ถ˜ ๊ฒฐ๊ณผ, ์‹œ์Šคํ…œ์ด ์ผ๋ถ€ ํ•™์ƒ๋“ค์—๊ฒŒ ์—ฐ๊ฒฐ๋˜๋Š” ์ง€ํ‘œ๊ฐ€ ์™œ๊ณก๋˜์–ด ๊ทธ๋“ค์˜ ์„ฑ์  ์˜ˆ์ธก์— ๋ถ€์ •์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์ณค์Šต๋‹ˆ๋‹ค.",
      "์ด๋กœ ์ธํ•ด ํ•™์ƒ๋“ค์˜ ๋ถˆ๋งŒ์ด ์ปค์ง€๊ณ , ๊ต์‚ฌ๋“ค๋„ ์˜ˆ์ธก์— ํ˜ผ๋ž€์„ ๊ฒช๊ฒŒ ๋ฉ๋‹ˆ๋‹ค."
    ],
    "agreeEnding": "์šฐ๋ฆฌ๋Š” ์ •ํ™•์„ฑ์„ ์šฐ์„ ์‹œํ•œ๋‹ค๊ณ  ๊ฒฐ์ •ํ•˜์˜€๊ณ , ๊ทธ ๊ฒฐ๊ณผ ์–ป์€ ์ •๋ณด๋Š” ์žˆ์—ˆ์ง€๋งŒ, ๊ณต์ •์„ฑ์„ ์žƒ์–ด ํ•™์ƒ๋“ค๊ณผ ํ•™๋ถ€๋ชจ์˜ ์‹ ๋ขฐ๋ฅผ ๋ฌด๋„ˆ๋œจ๋ฆฌ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์€ ๊ธฐ์ˆ ์  ์„ฑ๊ณผ์™€ ์œค๋ฆฌ์  ๋ฌธ์ œ ๊ฐ€์šด๋ฐ ์–ด๋–ค ์ชฝ์„ ๋” ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜์‹œ๋‚˜์š”?",
    "disagreeEnding": "์šฐ๋ฆฌ๋Š” ๊ณต์ •์„ฑ์„ ์šฐ์„ ์‹œํ•œ๋‹ค๊ณ  ๊ฒฐ์ •ํ•˜์˜€๊ณ , ๊ทธ๊ฒƒ์ด ํ•™์ƒ๋“ค์˜ ๊ธฐ๋Œ€๋ฅผ ๋งŒ์กฑ์‹œ์ผฐ์ง€๋งŒ, ์˜ˆ์ธก ์‹œ์Šคํ…œ์˜ ์‹ ๋ขฐ์„ฑ์€ ๋‚ฎ์•„์ง€๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์€ ์‹ ๋ขฐ์™€ ์ •ํ™•์„ฑ ์ค‘ ์–ด๋–ค ๊ฐ€์น˜๋ฅผ ๋” ์ค‘์‹œํ•˜๋‚˜์š”?"
  },
  "next_step": null,
  "is_complete": true
}

ํ”„๋ก ํŠธ์—”๋“œ ์ฒ˜๋ฆฌ ๊ฐ€์ด๋“œ

๊ธฐ๋ณธ ํ๋ฆ„

// 1. ์„ธ์…˜ ์‹œ์ž‘ (opening ๋‹จ๊ณ„)
const sessionId = generateUniqueId();
const response1 = await fetch('/chat/multi-step', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    session_id: sessionId,
    user_input: "AI ์œค๋ฆฌ์— ๋Œ€ํ•ด ํ† ๋ก ํ•˜๊ณ  ์‹ถ์–ด์š”",
    step: 'opening'
  })
});
const data1 = await response1.json();
// data1.parsed_variables.topic ์‚ฌ์šฉ

// 2. ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰ (step ์ƒ๋žต ์‹œ ์ž๋™ ์ง„ํ–‰)
const response2 = await fetch('/chat/multi-step', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    session_id: sessionId,
    user_input: "๋‹ค์Œ ๋‹จ๊ณ„"
  })
});
const data2 = await response2.json();
// data2.current_step === 'question'
// data2.parsed_variables.question, choice1, choice2 ์‚ฌ์šฉ

parsed_variables ์ฒ˜๋ฆฌ

// parsed_variables๊ฐ€ ๋น„์–ด์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•ญ์ƒ ์ฒดํฌ
if (data.parsed_variables && Object.keys(data.parsed_variables).length > 0) {
  // ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ
  processStructuredData(data.parsed_variables);
} else {
  // ํŒŒ์‹ฑ ์‹คํŒจ ์‹œ ์›๋ณธ ํ…์ŠคํŠธ ์‚ฌ์šฉ
  displayRawText(data.response_text);
}

variable ํ•„๋“œ ์‚ฌ์šฉ (ํ…Œ์ŠคํŠธ/๋””๋ฒ„๊น…)

// ํŠน์ • ๋‹จ๊ณ„๋ฅผ ๋ฐ”๋กœ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์‹ถ์„ ๋•Œ (์ด์ „ ๋‹จ๊ณ„ ์—†์ด)
const response = await fetch('/chat/multi-step', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    session_id: sessionId,
    user_input: "์‹œ์ž‘",
    step: "flip",
    variable: {
      question: "AI๊ฐ€ ํ•™์ƒ ์„ฑ์ ์„ ์˜ˆ์ธกํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์–ด๋–ค ์„ ํƒ์„ ํ•ด์•ผ ํ• ๊นŒ์š”?",
      choice1: "์ •ํ™•์„ฑ์„ ์œ„ํ•ด ํŠน์ • ์ง‘๋‹จ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„  ์‚ฌ์šฉํ•œ๋‹ค",
      choice2: "๊ณต์ •์„ฑ์„ ์œ„ํ•ด ๋ชจ๋“  ์ง‘๋‹จ์— ๊ท ํ˜• ์žกํžŒ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•œ๋‹ค"
    }
  })
});
// variable๋กœ ์ „๋‹ฌํ•œ ๊ฐ’์ด ํ”„๋กฌํ”„ํŠธ์— ์ง์ ‘ ์ „๋‹ฌ๋จ

์ฃผ์˜: variable ํ•„๋“œ๋Š” ์ฃผ๋กœ ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ ์šฉ๋„์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๋•์…˜์—์„œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฑ์—”๋“œ๊ฐ€ ์ž๋™์œผ๋กœ context์—์„œ ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

ending ๋‹จ๊ณ„ ์ฒ˜๋ฆฌ ์˜ˆ์‹œ

if (data.is_complete && data.parsed_variables) {
  const template = {
    opening: data.parsed_variables.opening,
    roles: [
      { name: data.parsed_variables.char1, description: data.parsed_variables.chardes1 },
      { name: data.parsed_variables.char2, description: data.parsed_variables.chardes2 },
      { name: data.parsed_variables.char3, description: data.parsed_variables.chardes3 }
    ],
    scenario: data.parsed_variables.dilemma_situation,
    question: data.parsed_variables.question,
    choices: [
      {
        label: data.parsed_variables.agree_label,
        flipTexts: data.parsed_variables.flips_agree_texts,
        ending: data.parsed_variables.agreeEnding
      },
      {
        label: data.parsed_variables.disagree_label,
        flipTexts: data.parsed_variables.flips_disagree_texts,
        ending: data.parsed_variables.disagreeEnding
      }
    ]
  };
  
  // ํ…œํ”Œ๋ฆฟ ์‚ฌ์šฉ
  createGameTemplate(template);
}

์—๋Ÿฌ ์ฒ˜๋ฆฌ

์—๋Ÿฌ ์‘๋‹ต ํ˜•์‹

{
  "detail": "์—๋Ÿฌ ๋ฉ”์‹œ์ง€"
}

HTTP ์ƒํƒœ ์ฝ”๋“œ

์ฝ”๋“œ ์˜๋ฏธ ๋Œ€์‘ ๋ฐฉ๋ฒ•
200 ์„ฑ๊ณต ์ •์ƒ ์ฒ˜๋ฆฌ
400 Bad Request ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ํ™•์ธ
500 Internal Server Error ์žฌ์‹œ๋„ ๋˜๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆผ
502 Bad Gateway OpenAI API ์˜ค๋ฅ˜, ์žฌ์‹œ๋„

parsed_variables๊ฐ€ ๋นˆ ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ

LangChain ํŒŒ์‹ฑ์ด ์‹คํŒจํ•ด๋„ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๊ณ  ๋นˆ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
  "parsed_variables": {},
  "response_text": "์›๋ณธ ์‘๋‹ต ํ…์ŠคํŠธ"
}

์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•: response_text๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ‘œ์‹œ


์„ธ์…˜ ๊ด€๋ฆฌ API

์„ธ์…˜ ์ •๋ณด ์กฐํšŒ

GET /chat/session/{session_id}

์„ธ์…˜ ์‚ญ์ œ

DELETE /chat/session/{session_id}

๊ธฐํƒ€ API

์ด๋ฏธ์ง€ ์ƒ์„ฑ

POST /chat/image

์ƒ์„ธํ•œ ๋‚ด์šฉ์€ ๋ณ„๋„ ๋ฌธ์„œ ์ฐธ์กฐ


์š”์•ฝ

๊ฐ ๋‹จ๊ณ„๋ณ„ ํ•ต์‹ฌ

๋‹จ๊ณ„ ์œ ์ € ํ–‰๋™ ๋ฐฑ์—”๋“œ ์ถœ๋ ฅ (parsed_variables) ๋น„๊ณ 
opening ์ฃผ์ œ ํ™•์ • topic ์ฒซ ๋‹จ๊ณ„
question ์งˆ๋ฌธ ํ™•์ • question, choice1, choice2 topic ์‚ฌ์šฉ
flip "๋‹ค์Œ ๋‹จ๊ณ„" 6๊ฐœ ๋ณ€์ˆ˜ (์‹œ๋‚˜๋ฆฌ์˜ค+ํ”Œ๋ฆฝ) question, choice1, choice2 ์‚ฌ์šฉ
roles "๋‹ค์Œ ๋‹จ๊ณ„" 6๊ฐœ ๋ณ€์ˆ˜ (์—ญํ•  ์ •๋ณด) flip์˜ 6๊ฐœ ๋ณ€์ˆ˜ ์‚ฌ์šฉ
ending "๋‹ค์Œ ๋‹จ๊ณ„" 15๊ฐœ ๋ณ€์ˆ˜ (์ตœ์ข… ํ…œํ”Œ๋ฆฟ) flip 6๊ฐœ + roles 6๊ฐœ ์‚ฌ์šฉ, is_complete=true

ํ•ต์‹ฌ ํฌ์ธํŠธ

  1. session_id: ๋ชจ๋“  ์š”์ฒญ์— ๋™์ผํ•œ session_id ์‚ฌ์šฉ
  2. step ์ƒ๋žต: ์ฒซ ์š”์ฒญ๋งŒ step: "opening" ๋ช…์‹œ, ์ดํ›„๋Š” ์ƒ๋žตํ•˜๋ฉด ์ž๋™ ์ง„ํ–‰
  3. parsed_variables: ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ, ๋น„์–ด์žˆ์„ ์ˆ˜ ์žˆ์Œ
  4. response_text: ํ•ญ์ƒ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ‘œ์‹œํ•  ํ…์ŠคํŠธ ํฌํ•จ
  5. is_complete: ending ๋‹จ๊ณ„์—์„œ true, ํ…œํ”Œ๋ฆฟ ์™„์„ฑ ์‹œ๊ทธ๋„

๋ณ€๊ฒฝ ์ด๋ ฅ

v3.0.0 (2025-01-XX)

  • ๐Ÿ”„ ๋‹จ๊ณ„ ์ˆœ์„œ ๋ณ€๊ฒฝ: opening โ†’ question โ†’ flip โ†’ roles โ†’ ending
  • โœจ flip ๋‹จ๊ณ„ ํ™•์žฅ: 6๊ฐœ ๋ณ€์ˆ˜ ์ถ”์ถœ (์‹œ๋‚˜๋ฆฌ์˜ค+ํ”Œ๋ฆฝ)
  • โœจ roles ๋‹จ๊ณ„ ํ™•์žฅ: 6๊ฐœ ๋ณ€์ˆ˜ ์ถ”์ถœ (์—ญํ•  ์ •๋ณด)
  • โœจ ending ๋‹จ๊ณ„ ํ™•์žฅ: 15๊ฐœ ๋ณ€์ˆ˜ ์ถ”์ถœ (์ตœ์ข… ํ…œํ”Œ๋ฆฟ)
  • ๐Ÿ“ API ๋ช…์„ธ์„œ ๊ฐ„์†Œํ™” ๋ฐ ์žฌ์ž‘์„ฑ