File size: 4,361 Bytes
83efdfc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4488b44
83efdfc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4488b44
83efdfc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import os
import json


# ─────────────────────────────────────────────
# β‘‘ Tool Router
# ─────────────────────────────────────────────

# 뢄석 μœ ν˜•λ³„ ν•„μš” 도ꡬ λ§€ν•‘
TOOLS_BY_ANALYSIS = {
    "swot":         ["fundamentals", "news", "price", "web_search"],
    "technical":    ["price", "technicals"],
    "fundamental":  ["fundamentals", "price"],
    "news_summary": ["news", "web_search"],
    "screener":     ["fundamentals"],
    "comparison":   ["fundamentals", "price"],
    "watchlist":    ["price", "technicals"],
    "earnings":     ["earnings", "fundamentals", "news", "web_search"],
    "general":      ["fundamentals", "price", "news", "web_search"],
}


def route_tools(intent):
    # 뢄석 μœ ν˜•μ— 따라 데이터 μˆ˜μ§‘ 도ꡬ λͺ©λ‘ κ²°μ •
    analysis_type = intent.get("analysis_type", "general")
    selected = TOOLS_BY_ANALYSIS.get(
        analysis_type,
        ["fundamentals", "price", "news", "web_search"]
    )
    print(f"[β‘‘] Tool Router β†’ μ„ νƒλœ 도ꡬ: {selected}")
    return selected


def parse_intent(client, user_query):
    LLM_MODEL_NAME = os.environ.get('LLM_MODEL_NAME')
    INTENT_TOOL = {
        "type": "function",
        "function": {
            "name": "parse_investment_intent",
            "description": "μ‚¬μš©μžμ˜ 투자 κ΄€λ ¨ μ§ˆμ˜μ—μ„œ μΈν…νŠΈμ™€ μ—”ν‹°ν‹°λ₯Ό μΆ”μΆœν•©λ‹ˆλ‹€.",
            "parameters": {
                "type": "object",
                "properties": {
                    "ticker": {"type": "string", "description": "주식 티컀 심볼 (예: AAPL, TSLA, 005930.KS). μ—†μœΌλ©΄ null."},
                    "analysis_type": {"type": "string", "enum": ["swot", "technical", "fundamental", "news_summary", "screener", "comparison", "watchlist", "earnings", "general"], "description": "μš”μ²­λœ 뢄석 μœ ν˜•. 싀적/μ–΄λ‹μŠ€/뢄기싀적/연간싀적/맀좜/μ˜μ—…μ΄μ΅ κ΄€λ ¨ μ§ˆμ˜λŠ” λ°˜λ“œμ‹œ 'earnings'둜 λΆ„λ₯˜."},
                    "time_range": {"type": "string", "enum": ["1d", "5d", "1mo", "3mo", "6mo", "1y", "2y", "5y"], "description": "뢄석 κΈ°κ°„. κΈ°λ³Έκ°’: 1y"},
                    "language": {"type": "string", "description": "응닡 μ–Έμ–΄ (ko, en, ja λ“±)"},
                    "extra_tickers": {"type": "array", "items": {"type": "string"}, "description": "비ꡐ 뢄석 μ‹œ μΆ”κ°€ 티컀 λͺ©λ‘"},
                    "target_year": {"type": "integer", "description": "싀적 쑰회 λŒ€μƒ 연도 (예: 2025). '25λ…„' β†’ 2025 λ³€ν™˜."},
                    "target_quarter": {"type": "integer", "enum": [1, 2, 3, 4], "description": "싀적 쑰회 λŒ€μƒ λΆ„κΈ° (1~4). μ—°κ°„ 싀적 μš”μ²­μ΄λ©΄ null."}
                },
                "required": ["analysis_type"]
            }
        }
    }
    response = client.chat.completions.create(
        model=LLM_MODEL_NAME,
        messages=[
            {
                "role": "system",
                "content": (
                    "당신은 투자 뢄석 μ‹œμŠ€ν…œμ˜ μΈν…νŠΈ νŒŒμ„œμž…λ‹ˆλ‹€. "
                    "μ‚¬μš©μžμ˜ μ§ˆμ˜μ—μ„œ 뢄석에 ν•„μš”ν•œ 정보λ₯Ό μ •ν™•νžˆ μΆ”μΆœν•˜μ„Έμš”. "
                    "ν•œκ΅­ 주식은 '.KS'(μ½”μŠ€ν”Ό) λ˜λŠ” '.KQ'(μ½”μŠ€λ‹₯) 접미사λ₯Ό λΆ™μ΄μ„Έμš”. "
                    "μ‚Όμ„±μ „μž β†’ 005930.KS, SKν•˜μ΄λ‹‰μŠ€ β†’ 000660.KS, LGμ—λ„ˆμ§€μ†”λ£¨μ…˜ β†’ 373220.KS, "
                    "ν˜„λŒ€μ°¨ β†’ 005380.KS, 카카였 β†’ 035720.KS, 넀이버 β†’ 035420.KS. "
                    "싀적/μ–΄λ‹μŠ€/뢄기싀적/연간싀적/맀좜/μ˜μ—…μ΄μ΅/EPS κ΄€λ ¨ μ§ˆμ˜λŠ” "
                    "'earnings'둜 λΆ„λ₯˜ν•˜κ³  μ–ΈκΈ‰λœ 연도·뢄기λ₯Ό μ±„μš°μ„Έμš”."
                )
            },
            {"role": "user", "content": user_query}
        ],
        tools=[INTENT_TOOL],
        tool_choice={"type": "function", "function": {"name": "parse_investment_intent"}}
    )
    args = json.loads(
        response.choices[0].message.tool_calls[0].function.arguments
    )
    args.setdefault("time_range",      "1y")
    args.setdefault("language",        "ko")
    args.setdefault("extra_tickers",   [])
    args.setdefault("target_year",     None)
    args.setdefault("target_quarter",  None)
    return args