Skip to content

Latest commit

ย 

History

History
361 lines (295 loc) ยท 10.2 KB

File metadata and controls

361 lines (295 loc) ยท 10.2 KB

์™ธ๋ถ€ API ์—ฐ๋™ ๋ช…์„ธ์„œ

๊ฐœ์š”

์„ธ์…˜ ์ฒ˜๋ฆฌ ์ค‘ **๋ชจ๋“  ๋ฉ”์‹œ์ง€(user, interlocutor ํฌํ•จ)**์— ๋Œ€ํ•ด ์™ธ๋ถ€ AI ์„œ๋ฒ„์—์„œ ๊ทธ๋ฃน๋ณ„ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค.

relationship & relationship_info

relationship: ๋Œ€ํ™” ์ƒ๋Œ€์™€์˜ ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

  • ์˜ˆ์‹œ: "FRIEND", "SUPERIOR", "COWORKER", "LOVER" ๋“ฑ
  • ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž์œ ๋กญ๊ฒŒ ์ •์˜ ๊ฐ€๋Šฅ

relationship_info: ๊ด€๊ณ„์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ๋‹ด๋Š” ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

  • ์˜ˆ์‹œ: "2๋…„ ์ง€๊ธฐ", "์‹ ์ž…์‚ฌ์›", "๊ฐ™์€ ๋™์•„๋ฆฌ", "3๊ฐœ์›” ์‚ฌ๊ท" ๋“ฑ
  • AI ์„œ๋ฒ„๊ฐ€ ๋Œ€ํ™” ๋งฅ๋ฝ์„ ๋” ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

group_id๋ž€?

๊ฐ™์€ ๋ฐœํ™”์ž๊ฐ€ ์—ฐ์†์œผ๋กœ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€ ๊ทธ๋ฃน์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์˜ˆ์‹œ:

[๊ทธ๋ฃน 1] ์‚ฌ์šฉ์ž: "๋‚ด์ผ ํšŒ์˜ ์ „์— ๊ฒฐ๊ณผ ์ •๋ฆฌํ•ด์„œ ๊ณต์œ ํ•ด ์ฃผ์„ธ์š”"
[๊ทธ๋ฃน 1] ์‚ฌ์šฉ์ž: "ํšŒ์˜๊ฐ€ ์˜ค์ „ 9์‹œ๋‹ˆ๊นŒ 9์‹œ ์ „์— ์ฃผ์„ธ์š”"
[๊ทธ๋ฃน 2] ์ƒ๋Œ€๋ฐฉ: "๋„ค ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค"
[๊ทธ๋ฃน 3] ์‚ฌ์šฉ์ž: "๋‹ค์Œ๋ถ€ํ„ฐ๋Š” ๋ˆˆ์น˜์žˆ๊ฒŒ ์ผ์ฒ˜๋ฆฌ ํ•ด์ฃผ์„ธ์š”"
  • ๊ทธ๋ฃน 1: ์‚ฌ์šฉ์ž๊ฐ€ ์—ฐ์†์œผ๋กœ ๋ณด๋‚ธ 2๊ฐœ ๋ฉ”์‹œ์ง€
  • ๊ทธ๋ฃน 2: ์ƒ๋Œ€๋ฐฉ ๋ฉ”์‹œ์ง€ (interlocutor)
  • ๊ทธ๋ฃน 3: ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์‹œ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€ (์ƒˆ ๊ทธ๋ฃน)

AI ์„œ๋ฒ„๋Š” ๊ทธ๋ฃน ๋‹จ์œ„๋กœ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

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

POST AI_BASE_URL/api/analyze-messages

์š”์ฒญ ํ˜•์‹

Headers

Content-Type: application/json
Authorization: Bearer YOUR_API_KEY  (์„ ํƒ์‚ฌํ•ญ)

Request Body

{
  "relationship": "FRIEND",
  "relationship_info": "2๋…„ ์ง€๊ธฐ",
  "messages": [
    {
      "message_id": "uuid-string",
      "text": "์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€ ํ…์ŠคํŠธ",
      "speaker": "user",
      "confidence": 0.95,
      "group_id": 1
    },
    {
      "message_id": "another-uuid",
      "text": "๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€",
      "speaker": "user",
      "confidence": 0.87,
      "group_id": 1
    },
    {
      "message_id": "third-uuid",
      "text": "์ƒ๋Œ€๋ฐฉ์ด ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€",
      "speaker": "interlocutor",
      "confidence": 0.92,
      "group_id": 2
    },
    {
      "message_id": "fourth-uuid",
      "text": "๋‹ค์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€",
      "speaker": "user",
      "confidence": 0.89,
      "group_id": 3
    }
  ]
}

ํ•„๋“œ ์„ค๋ช…

ํ•„๋“œ ํƒ€์ž… ์„ค๋ช…
relationship String [ํ•„์ˆ˜] ๋Œ€ํ™” ์ƒ๋Œ€์™€์˜ ๊ด€๊ณ„ (์˜ˆ: "FRIEND", "SUPERIOR", "COWORKER" ๋“ฑ)
relationship_info String [ํ•„์ˆ˜] ๊ด€๊ณ„์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด (์˜ˆ: "2๋…„ ์ง€๊ธฐ", "์‹ ์ž…์‚ฌ์›" ๋“ฑ)
messages Array [ํ•„์ˆ˜] ๋ชจ๋“  ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก (user, interlocutor ๋ชจ๋‘ ํฌํ•จ)
messages[].message_id String ๋ฉ”์‹œ์ง€ ๊ณ ์œ  ID (UUID)
messages[].text String ๋ฉ”์‹œ์ง€ ์›๋ฌธ
messages[].speaker String ๋ฐœํ™”์ž ("user" ๋˜๋Š” "interlocutor")
messages[].confidence Float OCR ์‹ ๋ขฐ๋„ (0.0 ~ 1.0)
messages[].group_id Integer ์—ฐ์† ๋ฉ”์‹œ์ง€ ๊ทธ๋ฃน ID (๊ฐ™์€ ๊ทธ๋ฃน = ์—ฐ์†์œผ๋กœ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€)

์‘๋‹ต ํ˜•์‹

Success Response (200 OK)

HTTP 200 ์‘๋‹ต์ด๋ฉด ์„ฑ๊ณต์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. status ํ•„๋“œ๋Š” ์„ ํƒ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

์ค‘์š”: ์‘๋‹ต์€ ๊ทธ๋ฃน ๋‹จ์œ„๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ๊ฐ ๊ทธ๋ฃน์˜ ๋ชจ๋“  ๋ฉ”์‹œ์ง€์— ๋™์ผํ•œ ๋ถ„์„ ๊ฒฐ๊ณผ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์˜ต์…˜ 1: ๋ฐฐ์—ด ์ง์ ‘ ๋ฐ˜ํ™˜ (๊ถŒ์žฅ)

[
  {
    "group_id": 1,
    "emotional_tone": "NEUTRAL",
    "score": 75,
    "impact_score": 2,
    "review_comment": "์ƒ๋Œ€๋ฐฉ์„ ๋ฐฐ๋ คํ•˜๋Š” ์ข‹์€ ํ‘œํ˜„์ž…๋‹ˆ๋‹ค.",
    "suggested_alternative": null
  },
  {
    "group_id": 2,
    "emotional_tone": "NEGATIVE",
    "score": 20,
    "impact_score": -2,
    "review_comment": "๋‹ค์†Œ ๊ณต๊ฒฉ์ ์œผ๋กœ ๋“ค๋ฆด ์ˆ˜ ์žˆ์–ด์š”.",
    "suggested_alternative": "'๊ทธ ๋ถ€๋ถ„์ด ์กฐ๊ธˆ ์˜์•„ํ–ˆ๋Š”๋ฐ, ๋„ค ์ƒ๊ฐ์„ ์ข€ ๋” ๋“ฃ๊ณ  ์‹ถ์–ด.'๋ผ๊ณ  ๋งํ•ด๋ณด์„ธ์š”."
  }
]

์˜ต์…˜ 2: ๊ฐ์ฒด๋กœ ๊ฐ์‹ธ์„œ ๋ฐ˜ํ™˜

{
  "status": "success",
  "response": [
    {
      "group_id": 1,
      "emotional_tone": "NEUTRAL",
      "score": 75,
      "impact_score": 2,
      "review_comment": "์ƒ๋Œ€๋ฐฉ์„ ๋ฐฐ๋ คํ•˜๋Š” ์ข‹์€ ํ‘œํ˜„์ž…๋‹ˆ๋‹ค.",
      "suggested_alternative": null
    }
  ]
}

ํ•„๋“œ ์„ค๋ช…

ํ•„๋“œ ํƒ€์ž… ์„ค๋ช…
status String (์„ ํƒ) ์‘๋‹ต ์ƒํƒœ ("success" ๋˜๋Š” "error")
response Array (์˜ต์…˜2 ์‚ฌ์šฉ ์‹œ) ๊ฐ ๊ทธ๋ฃน์— ๋Œ€ํ•œ ๋ถ„์„ ๊ฒฐ๊ณผ ๋ฐฐ์—ด
[].group_id Integer [ํ•„์ˆ˜] ๋ถ„์„ ๋Œ€์ƒ ๊ทธ๋ฃน ID (์š”์ฒญํ•œ messages์˜ group_id์™€ ๋งค์นญ)
[].emotional_tone String [ํ•„์ˆ˜] ๊ฐ์ • ํ†ค ("POSITIVE", "NEUTRAL", "NEGATIVE" ๋“ฑ)
[].score Integer [ํ•„์ˆ˜] AI๊ฐ€ ํ‰๊ฐ€ํ•œ ์ ์ˆ˜ (0 ~ 100)
[].impact_score Integer [ํ•„์ˆ˜] ์˜ํ–ฅ ์ ์ˆ˜ (-5 ~ +5)
[].review_comment String [ํ•„์ˆ˜] AI์˜ ํ”ผ๋“œ๋ฐฑ ๋ฉ”์‹œ์ง€
[].suggested_alternative String | null (์„ ํƒ) ๋Œ€์•ˆ ํ‘œํ˜„ ์ œ์‹œ (์—†์œผ๋ฉด null)

Error Response (4xx, 5xx)

{
  "status": "error",
  "error_code": "RATE_LIMIT_EXCEEDED",
  "message": "API rate limit exceeded. Please try again later."
}

์„ค์ • ๋ฐฉ๋ฒ•

์ฝ”๋“œ์—์„œ ์™ธ๋ถ€ API URL ์„ค์ •

external_service.py ํŒŒ์ผ์—์„œ ์„ค์ •:

from external_service import get_external_service

# ์™ธ๋ถ€ API ์‚ฌ์šฉ
service = get_external_service(
    api_url="https://your-ai-server.com/api/analyze-messages",
    api_key="your_api_key_here"
)

ํด๋ผ์ด์–ธํŠธ์—์„œ ์„ธ์…˜ ์ฒ˜๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์‹œ

์„ธ์…˜ ์ฒ˜๋ฆฌ ์‹œ relationship๊ณผ relationship_info ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค:

import requests

# ์„ธ์…˜ ์ฒ˜๋ฆฌ ํ˜ธ์ถœ
response = requests.post(
    "http://localhost:8000/sessions/{session_id}/process",
    params={
        "relationship": "FRIEND",  # ํ•„์ˆ˜: ๊ด€๊ณ„
        "relationship_info": "2๋…„ ์ง€๊ธฐ"  # ํ•„์ˆ˜: ์ถ”๊ฐ€ ์ •๋ณด
    }
)

main.py ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ ์˜ˆ์‹œ

# ์™ธ๋ถ€ ์„œ๋ฒ„ ์—ฐ๋™
external_service = get_external_service(
    api_url="https://your-ai-server.com/api/analyze-messages",
    api_key="your_api_key"
)
score_results = await external_service.get_scores_for_messages(
    merged_messages,
    relationship="FRIEND",
    relationship_info="2๋…„ ์ง€๊ธฐ"
)

๋”๋ฏธ ๋ชจ๋“œ (๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ์šฉ)

์™ธ๋ถ€ API URL์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ ๋”๋ฏธ ๋ชจ๋“œ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค:

# api_url=None์ด๋ฉด ๋”๋ฏธ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
service = get_external_service()  # ๋”๋ฏธ ๋ชจ๋“œ

๋”๋ฏธ ๋ชจ๋“œ์—์„œ๋Š”:

  • ๋žœ๋ค score (20 ~ 95)
  • ๋žœ๋ค emotional_tone (POSITIVE, NEUTRAL, NEGATIVE)
  • ๋žœ๋ค impact_score (-3 ~ 3)
  • ๋ฏธ๋ฆฌ ์ •์˜๋œ review_comment ์ค‘ ๋žœ๋ค ์„ ํƒ
  • ๋žœ๋ค suggested_alternative (์žˆ๊ฑฐ๋‚˜ null)
  • 0.5์ดˆ ์ง€์—ฐ ์‹œ๋ฎฌ๋ ˆ์ด์…˜

cURL ์˜ˆ์‹œ

curl -X POST https://your-ai-server.com/api/analyze-messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "relationship": "SUPERIOR",
    "relationship_info": "์‹ ์ž…์‚ฌ์›",
    "messages": [
      {
        "message_id": "123e4567-e89b-12d3-a456-426614174000",
        "text": "๋‚ด์ผ ํšŒ์˜ ์ „์— ๊ฒฐ๊ณผ ์ •๋ฆฌํ•ด์„œ ๊ณต์œ ํ•ด ์ฃผ์„ธ์š”",
        "speaker": "user",
        "confidence": 0.95,
        "group_id": 1
      },
      {
        "message_id": "223e4567-e89b-12d3-a456-426614174001",
        "text": "๋„ค ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค",
        "speaker": "interlocutor",
        "confidence": 0.92,
        "group_id": 2
      }
    ]
  }'

Python ์š”์ฒญ ์˜ˆ์‹œ

import requests

response = requests.post(
    "https://your-ai-server.com/api/analyze-messages",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_API_KEY"
    },
    json={
        "relationship": "FRIEND",  # ํ•„์ˆ˜
        "relationship_info": "2๋…„ ์ง€๊ธฐ",  # ํ•„์ˆ˜
        "messages": [
            {
                "message_id": "123e4567-e89b-12d3-a456-426614174000",
                "text": "๋‚ด์ผ ํšŒ์˜ ์ „์— ๊ฒฐ๊ณผ ์ •๋ฆฌํ•ด์„œ ๊ณต์œ ํ•ด ์ฃผ์„ธ์š”",
                "speaker": "user",
                "confidence": 0.95,
                "group_id": 1
            },
            {
                "message_id": "223e4567-e89b-12d3-a456-426614174001",
                "text": "ํšŒ์˜๊ฐ€ ์˜ค์ „ 9์‹œ๋‹ˆ๊นŒ 9์‹œ ์ „์— ์ฃผ์„ธ์š”",
                "speaker": "user",
                "confidence": 0.92,
                "group_id": 1  # ๊ฐ™์€ ๊ทธ๋ฃน (์—ฐ์† ๋ฉ”์‹œ์ง€)
            },
            {
                "message_id": "323e4567-e89b-12d3-a456-426614174002",
                "text": "๋„ค ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค",
                "speaker": "interlocutor",
                "confidence": 0.89,
                "group_id": 2  # ์ƒ๋Œ€๋ฐฉ ๋ฉ”์‹œ์ง€
            }
        ]
    },
    timeout=30
)

if response.status_code == 200:
    data = response.json()
    # ๋ฐฐ์—ด์ด๋ฉด ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ, ๊ฐ์ฒด๋ฉด 'response' ํ‚ค์—์„œ ์ถ”์ถœ
    results = data if isinstance(data, list) else data.get('response', [])
    for result in results:
        print(f"Group {result['group_id']}: Score={result['score']}, Comment={result['review_comment']}")

ํƒ€์ž„์•„์›ƒ ๋ฐ ์—๋Ÿฌ ์ฒ˜๋ฆฌ

  • ํƒ€์ž„์•„์›ƒ: 30์ดˆ
  • ์‹คํŒจ ์‹œ: ์ž๋™์œผ๋กœ ๋”๋ฏธ ๋ฐ์ดํ„ฐ๋กœ fallback
  • ์žฌ์‹œ๋„: ์—†์Œ (1ํšŒ๋งŒ ์‹œ๋„)

๋ณด์•ˆ ๊ณ ๋ ค์‚ฌํ•ญ

  1. HTTPS ์‚ฌ์šฉ ํ•„์ˆ˜
  2. API ํ‚ค๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌ (.env ํŒŒ์ผ ์‚ฌ์šฉ ๊ถŒ์žฅ)
  3. Rate Limiting ๊ณ ๋ ค (๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”์‹œ์ง€ ํ•œ ๋ฒˆ์— ์ „์†ก ๋ฐฉ์ง€)

ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ • ์˜ˆ์‹œ

.env ํŒŒ์ผ ์ƒ์„ฑ:

EXTERNAL_API_URL=https://your-ai-server.com/api/analyze-messages
EXTERNAL_API_KEY=your_secret_api_key_here

์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ:

import os
from dotenv import load_dotenv

load_dotenv()

service = get_external_service(
    api_url=os.getenv("EXTERNAL_API_URL"),
    api_key=os.getenv("EXTERNAL_API_KEY")
)

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ €์žฅ

์‘๋‹ต๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค:

  • group_id: ํ•ด๋‹น ๊ทธ๋ฃน์˜ ๋ชจ๋“  ๋ฉ”์‹œ์ง€์— ๋™์ผํ•œ ๋ถ„์„ ๊ฒฐ๊ณผ๊ฐ€ ์ ์šฉ๋จ
  • score: ์ ์ˆ˜ (0 ~ 100)
  • emotional_tone: ๊ฐ์ • ํ†ค
  • impact_score: ์˜ํ–ฅ ์ ์ˆ˜
  • review_comment: ํ”ผ๋“œ๋ฐฑ ๋ฉ”์‹œ์ง€
  • suggested_alternative: ๋Œ€์•ˆ ํ‘œํ˜„ (์žˆ๋Š” ๊ฒฝ์šฐ)

๊ฐ™์€ group_id๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ๋ฉ”์‹œ์ง€๋Š” ๋™์ผํ•œ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.