| import os |
| import json |
|
|
|
|
| |
| |
| |
|
|
| |
| 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 |
|
|