Heewon Oh Claude Sonnet 4.5 commited on
Commit
862ca4c
ยท
1 Parent(s): cd3a181

feat: align synthesis output with STONKS EOD deep report format

Browse files

- RESEARCH_SYNTHESIS_PROMPT: 8-section structure matching STONKS
DEEP_REPORT_TEMPLATE (ํ•ต์‹ฌ์š”์•ฝ/์‹ค์ /์‚ฌ์—…์ „๋žต/์‹œ๋‚˜๋ฆฌ์˜ค/๋ฆฌ์Šคํฌ/ํˆฌ์ž์˜๊ฒฌ/
๋ชจ๋‹ˆํ„ฐ๋ง/์ฐธ๊ณ ์ž๋ฃŒ), emoji headers, checklist risk items
- to_markdown(): conclusion is now the full EOD report โ€” output directly,
move metadata (confidence/sources/elapsed) to a compact footer line
instead of prepending headers above the report body

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Files changed (2) hide show
  1. vela/prompts/research.py +117 -20
  2. vela/schemas.py +12 -37
vela/prompts/research.py CHANGED
@@ -36,35 +36,132 @@ RESEARCH_SYSTEM_PROMPT_TEMPLATE = """๋‹น์‹ ์€ ํ•œ๊ตญ ์ฃผ์‹ ๋ฆฌ์„œ์น˜ ์—์ด์ „
36
  # ํ•ฉ์„ฑ ํ”„๋กฌํ”„ํŠธ (์ตœ์ข… ๊ฒฐ๋ก  ์ƒ์„ฑ์šฉ) - v2 Enhanced Scaffolding
37
  # =============================================================================
38
 
39
- RESEARCH_SYNTHESIS_PROMPT = """[๋ถ„์„๋ชจ๋“œ: EOD_REPORT_WITH_REASONING]
40
  # VELA ํ•œ๊ตญ ์ฃผ์‹ ์• ๋„๋ฆฌ์ŠคํŠธ
41
 
42
  ## ์ ˆ๋Œ€ ๊ทœ์น™
43
  - ํ•œ๊ตญ์–ด๋งŒ ์‚ฌ์šฉ (์ค‘๊ตญ์–ด ์ ˆ๋Œ€ ๊ธˆ์ง€)
44
- - ์˜์–ด๋Š” ๊ณ ์œ ๋ช…์‚ฌ/์ „๋ฌธ์šฉ์–ด๋งŒ (HBM, PER, ROE ๋“ฑ)
45
- - ์ œ๊ณต๋œ ๋ฐ์ดํ„ฐ๋งŒ ์ธ์šฉ (๋‚ ์กฐ ๊ธˆ์ง€)
46
- - ๋‰ด์Šค ์ธ์šฉ ์‹œ ๋ฐ˜๋“œ์‹œ [์ถœ์ฒ˜](URL) ํ‘œ๊ธฐ
47
-
48
- ## ํ•„์ˆ˜ ์„น์…˜ (7๊ฐœ)
49
- 1. Executive Summary (2-3๋ฌธ์žฅ)
50
- 2. Key Metrics (ํ…Œ์ด๋ธ”)
51
- 3. ์‹œ์žฅ ๋™ํ–ฅ ๋ถ„์„
52
- 4. ์ˆ˜๊ธ‰ ๋ถ„์„
53
- 5. ๋‰ด์Šค ์˜ํ–ฅ ๋ถ„์„ (URL ์ธ์šฉ ํ•„์ˆ˜)
54
- 6. ๋ฆฌ์Šคํฌ ์š”์ธ
55
- 7. ํˆฌ์ž ์˜๊ฒฌ + References
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  ## ๋ถ„์„ ๊ธฐ์ค€
58
  - ๋“ฑ๋ฝ๋ฅ  ยฑ3%โ†‘: ๊ธ‰๋“ฑ/๊ธ‰๋ฝ
59
  - ์™ธ๊ตญ์ธ 1000์–ตโ†‘: ๋Œ€๊ทœ๋ชจ ๋งค์ง‘
60
- - ๊ฐœ์ธ ์ฃผ๋„: ์ฃผ์˜ ํ•„์š”
61
-
62
- ## ๊ธˆ์ง€ ํ‘œํ˜„
63
- - ์ค‘๊ตญ์–ด (็ฎ€ไฝ“/็น้ซ”)
64
- - "~๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค" โ†’ "~๋กœ ๋ถ„์„๋ฉ๋‹ˆ๋‹ค"
65
- - ๊ฐ์ •์  ํ‘œํ˜„ โ†’ ๊ฐ๊ด€์  ์ˆ˜์น˜
66
 
67
- ์œ„ ๊ทœ์น™์„ ์—„๊ฒฉํžˆ ์ค€์ˆ˜ํ•˜์—ฌ ์ „๋ฌธ์ ์ธ ๋ฆฌํฌํŠธ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
68
  """
69
 
70
 
 
36
  # ํ•ฉ์„ฑ ํ”„๋กฌํ”„ํŠธ (์ตœ์ข… ๊ฒฐ๋ก  ์ƒ์„ฑ์šฉ) - v2 Enhanced Scaffolding
37
  # =============================================================================
38
 
39
+ RESEARCH_SYNTHESIS_PROMPT = """[๋ถ„์„๋ชจ๋“œ: EOD_DEEP_REPORT]
40
  # VELA ํ•œ๊ตญ ์ฃผ์‹ ์• ๋„๋ฆฌ์ŠคํŠธ
41
 
42
  ## ์ ˆ๋Œ€ ๊ทœ์น™
43
  - ํ•œ๊ตญ์–ด๋งŒ ์‚ฌ์šฉ (์ค‘๊ตญ์–ด ์ ˆ๋Œ€ ๊ธˆ์ง€)
44
+ - ์˜์–ด๋Š” ๊ณ ์œ ๋ช…์‚ฌ/์ „๋ฌธ์šฉ์–ด๋งŒ (HBM, PER, ROE, CAPEX ๋“ฑ)
45
+ - ์ œ๊ณต๋œ ๋ฐ์ดํ„ฐ๋งŒ ์ธ์šฉ (๋‚ ์กฐ ๊ธˆ์ง€) โ€” ์ˆ˜์น˜ ๋ถˆํ™•์‹ค ์‹œ "N/A" ํ‘œ๊ธฐ
46
+ - ๋‰ด์Šค/์†Œ์Šค ์ธ์šฉ ์‹œ ๋ฐ˜๋“œ์‹œ [์ œ๋ชฉ](URL) ํ˜•์‹
47
+
48
+ ## ์ถœ๋ ฅ ํ˜•์‹ (์•„๋ž˜ ๋งˆํฌ๋‹ค์šด ๊ตฌ์กฐ๋ฅผ ๋ฐ˜๋“œ์‹œ ์ค€์ˆ˜)
49
+
50
+ ## ๐Ÿ“Œ ํ•ต์‹ฌ ์š”์•ฝ (TL;DR)
51
+
52
+ ### ์ฃผ์š” ์‚ฌํ•ญ
53
+ - **์ฃผ์š” ์ด์Šˆ**: 2~3๋ฌธ์žฅ์œผ๋กœ ์ตœ๊ทผ ํ•ต์‹ฌ ์ด์Šˆ ์š”์•ฝ
54
+
55
+ ### ํˆฌ์ž ํฌ์ธํŠธ
56
+ - โœ… ๊ฐ•์  1: ๊ตฌ์ฒด์  ๊ทผ๊ฑฐ
57
+ - โœ… ๊ฐ•์  2: ๊ตฌ์ฒด์  ๊ทผ๊ฑฐ
58
+ - โš ๏ธ ๋ฆฌ์Šคํฌ 1: ๊ตฌ์ฒด์  ๊ทผ๊ฑฐ
59
+ - โš ๏ธ ๋ฆฌ์Šคํฌ 2: ๊ตฌ์ฒด์  ๊ทผ๊ฑฐ
60
+
61
+ ---
62
+
63
+ ## ๐Ÿ“Š ์‹ค์  ๋ฐ ๋ฐธ๋ฅ˜์—์ด์…˜
64
+
65
+ ### ์ฃผ์š” ์žฌ๋ฌด ์ง€ํ‘œ
66
+
67
+ | ํ•ญ๋ชฉ | ์ตœ๊ทผ ์‹ค์  | ์ „๋…„ ๋Œ€๋น„ | ๋น„๊ณ  |
68
+ |:-----|:---------|:---------|:-----|
69
+ | **๋งค์ถœ** | | | |
70
+ | **์˜์—…์ด์ต** | | | |
71
+ | **์˜์—…์ด์ต๋ฅ ** | | | |
72
+ | **PER** | | | |
73
+ | **PBR** | | | |
74
+
75
+ ### ์ฆ๊ถŒ์‚ฌ ๋ชฉํ‘œ๊ฐ€
76
+
77
+ | ์ฆ๊ถŒ์‚ฌ | ๋ชฉํ‘œ๊ฐ€ | ์˜๊ฒฌ | ๊ทผ๊ฑฐ |
78
+ |:-------|:-------|:-----|:-----|
79
+ | | | | |
80
+
81
+ ---
82
+
83
+ ## ๐Ÿ” ์‹ค์  ๋ถ„์„
84
+
85
+ ### ์ตœ๊ทผ ์‹ค์  ๋™ํ–ฅ
86
+ - ๋งค์ถœ/์ด์ต ์ฆ๊ฐ ์›์ธ ๋ถ„์„
87
+
88
+ ### ํ•ต์‹ฌ ์„ฑ์žฅ ๋™์ธ
89
+ - ์‹ ๊ทœ ์‚ฌ์—…/์ œํ’ˆ ๋ชจ๋ฉ˜ํ…€
90
+ - ์‹œ์žฅ ์ ์œ ์œจ ๋ณ€ํ™”
91
+
92
+ ---
93
+
94
+ ## โš™๏ธ ์‚ฌ์—… ์ „๋žต ๋ฐ ๊ฒฝ์Ÿ๋ ฅ
95
+
96
+ ### ์ „๋žต์  ์ด๋‹ˆ์…”ํ‹ฐ๋ธŒ
97
+ - CAPEX / ์ฆ์„ค ๊ณ„ํš, ํŒŒํŠธ๋„ˆ์‹ญ, ๊ธ€๋กœ๋ฒŒ ํ™•์žฅ
98
+
99
+ ### ๊ฒฝ์Ÿ ์šฐ์œ„
100
+ - ๊ธฐ์ˆ ๋ ฅ, ๋น„์šฉ ๊ฒฝ์Ÿ๋ ฅ, ๊ณ ๊ฐ ๊ด€๊ณ„
101
+
102
+ ---
103
+
104
+ ## ๐ŸŽฏ ํˆฌ์ž ์‹œ๋‚˜๋ฆฌ์˜ค
105
+
106
+ ### ๐Ÿ“ˆ ๋‚™๊ด€ ์‹œ๋‚˜๋ฆฌ์˜ค
107
+ - ์ „์ œ: ํ•ต์‹ฌ ์กฐ๊ฑด
108
+ - ์ „๋ง: ๋งค์ถœยท์ด์ต๋ฅ  ๋ฐฉํ–ฅ์„ฑ
109
+
110
+ ### ๐Ÿ“Š ์ค‘๋ฆฝ ์‹œ๋‚˜๋ฆฌ์˜ค
111
+ - ์ „์ œ: ํ•ต์‹ฌ ์กฐ๊ฑด
112
+ - ์ „๋ง: ๋งค์ถœยท์ด์ต๋ฅ  ๋ฐฉํ–ฅ์„ฑ
113
+
114
+ ### ๐Ÿ“‰ ๋น„๊ด€ ์‹œ๋‚˜๋ฆฌ์˜ค
115
+ - ์ „์ œ: ํ•ต์‹ฌ ์กฐ๊ฑด
116
+ - ์ „๋ง: ๋งค์ถœยท์ด์ต๋ฅ  ๋ฐฉํ–ฅ์„ฑ
117
+
118
+ ---
119
+
120
+ ## โš ๏ธ ๋ฆฌ์Šคํฌ ์š”์ธ
121
+
122
+ ### ์‚ฌ์—… ๋ฆฌ์Šคํฌ
123
+ - [ ] ๋ฆฌ์Šคํฌ 1
124
+ - [ ] ๋ฆฌ์Šคํฌ 2
125
+
126
+ ### ์‹œ์žฅ ๋ฆฌ์Šคํฌ
127
+ - [ ] ๋ฆฌ์Šคํฌ 1
128
+ - [ ] ๋ฆฌ์Šคํฌ 2
129
+
130
+ ---
131
+
132
+ ## ๐Ÿ’ก ํˆฌ์ž ์˜๊ฒฌ
133
+
134
+ ### ์ข…ํ•ฉ ํŒ๋‹จ
135
+ - **๋‹จ๊ธฐ ๋ฐฉํ–ฅ์„ฑ**: Bullish / Neutral / Bearish
136
+ - **์ค‘์žฅ๊ธฐ ์ „๋ง**: 1~2๋ฌธ์žฅ
137
+
138
+ ### ๋งค์ˆ˜/๋ณด๋ฅ˜ ๊ทผ๊ฑฐ
139
+ - **๊ทผ๊ฑฐ**: ํ•ต์‹ฌ 1๋ฌธ์žฅ
140
+
141
+ ---
142
+
143
+ ## ๐Ÿ” ๋ชจ๋‹ˆํ„ฐ๋ง ํฌ์ธํŠธ
144
+
145
+ ### ๋‹จ๊ธฐ
146
+ - [ ] ์ฒดํฌํฌ์ธํŠธ 1
147
+ - [ ] ์ฒดํฌํฌ์ธํŠธ 2
148
+
149
+ ### ์ค‘๊ธฐ
150
+ - [ ] ์ฒดํฌํฌ์ธํŠธ 1
151
+
152
+ ---
153
+
154
+ ## ๐Ÿ“š ์ฐธ๊ณ  ์ž๋ฃŒ
155
+ ์†Œ์Šค ๋ฒˆํ˜ธ์™€ URL์„ [์ œ๋ชฉ](URL) ํ˜•์‹์œผ๋กœ ๋‚˜์—ด
156
+
157
+ ---
158
 
159
  ## ๋ถ„์„ ๊ธฐ์ค€
160
  - ๋“ฑ๋ฝ๋ฅ  ยฑ3%โ†‘: ๊ธ‰๋“ฑ/๊ธ‰๋ฝ
161
  - ์™ธ๊ตญ์ธ 1000์–ตโ†‘: ๋Œ€๊ทœ๋ชจ ๋งค์ง‘
162
+ - ์ˆ˜์น˜ ๋ฏธํ™•์ธ ์‹œ: "N/A" ํ‘œ๊ธฐ (๋‚ ์กฐ ๊ธˆ์ง€)
 
 
 
 
 
163
 
164
+ ์œ„ ๊ตฌ์กฐ๋ฅผ ๋ฐ˜๋“œ์‹œ ์ค€์ˆ˜ํ•˜์—ฌ ์ „๋ฌธ์ ์ธ EOD ๋ถ„์„ ๋ฆฌํฌํŠธ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
165
  """
166
 
167
 
vela/schemas.py CHANGED
@@ -558,43 +558,18 @@ class ResearchResult(BaseModel):
558
  return self.model_dump_json(indent=indent)
559
 
560
  def to_markdown(self) -> str:
561
- """๋งˆํฌ๋‹ค์šด ๋ฆฌํฌํŠธ๋กœ ๋ณ€ํ™˜"""
562
- md = f"# ๋ฆฌ์„œ์น˜ ๊ฒฐ๊ณผ: {self.query}\n\n"
563
- md += f"**์‹ ๋ขฐ๋„**: {self.confidence:.0%}\n"
564
- md += f"**์†Œ์Šค ์ˆ˜**: {len(self.sources)}๊ฐœ\n"
565
- md += f"**์†Œ์š” ์‹œ๊ฐ„**: {self.metadata.elapsed_seconds:.1f}์ดˆ\n\n"
566
-
567
- # ํ•ต์‹ฌ ๋ฐœ๊ฒฌ์‚ฌํ•ญ
568
- if self.key_findings:
569
- md += "## ํ•ต์‹ฌ ๋ฐœ๊ฒฌ์‚ฌํ•ญ\n\n"
570
- for finding in self.key_findings:
571
- md += f"- {finding}\n"
572
- md += "\n"
573
-
574
- # ๊ฒฐ๋ก 
575
- md += "## ๊ฒฐ๋ก \n\n"
576
- md += self.conclusion + "\n\n"
577
-
578
- # ์ถ”๋ก  ๊ณผ์ •
579
- md += "## ์ถ”๋ก  ๊ณผ์ •\n\n"
580
- for step in self.reasoning_trace:
581
- md += f"### Step {step.step_number}\n"
582
- md += f"**์‚ฌ๊ณ **: {step.thought}\n"
583
- md += f"**์•ก์…˜**: {step.action}"
584
- if step.query:
585
- md += f" - `{step.query}`"
586
- md += f"\n**๊ด€์ฐฐ**: {step.observation}\n"
587
- md += f"**์‹ ๋ขฐ๋„**: {step.confidence:.0%}\n\n"
588
-
589
- # ์†Œ์Šค
590
- md += "## ์ฐธ๊ณ  ์ž๋ฃŒ\n\n"
591
- for i, src in enumerate(self.sources, 1):
592
- md += f"{i}. [{src.title}]({src.url})"
593
- if src.securities_firm:
594
- md += f" ({src.securities_firm})"
595
- if src.date:
596
- md += f" - {src.date}"
597
- md += "\n"
598
 
599
  return md
600
 
 
558
  return self.model_dump_json(indent=indent)
559
 
560
  def to_markdown(self) -> str:
561
+ """๋งˆํฌ๋‹ค์šด ๋ฆฌํฌํŠธ๋กœ ๋ณ€ํ™˜ (STONKS EOD ํ˜•์‹)
562
+
563
+ synthesis ๋‹จ๊ณ„์—์„œ ์ด๋ฏธ EOD ๋ฆฌํฌํŠธ ๊ตฌ์กฐ๋กœ ์ƒ์„ฑ๋˜๋ฏ€๋กœ
564
+ conclusion์„ ์ง์ ‘ ์ถœ๋ ฅํ•˜๊ณ , ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ํ•˜๋‹จ์— ์ ‘ํžŒ ํ˜•์‹์œผ๋กœ ํ‘œ์‹œ.
565
+ """
566
+ # ๊ฒฐ๋ก ์ด ์ด๋ฏธ EOD ๋ฆฌํฌํŠธ ํ˜•์‹ โ€” ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅ
567
+ md = self.conclusion.strip() + "\n"
568
+
569
+ # ํ•˜๋‹จ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ (Gradio accordion์šฉ)
570
+ md += "\n---\n"
571
+ md += f"*์‹ ๋ขฐ๋„: {self.confidence:.0%} ยท ์†Œ์Šค: {len(self.sources)}๊ฐœ ยท "
572
+ md += f"์†Œ์š”: {self.metadata.elapsed_seconds:.0f}์ดˆ*\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
573
 
574
  return md
575