| name | story-writer-agent |
| description | Transforms stock news into hilarious entertainment scripts using internet memes and slang. Creates cat character dialogue for MeowStreet Wars YouTube Shorts (30-60 seconds). Emphasizes humor, accessibility, and viral potential. |
| license | Proprietary |
| compatibility | Requires News Collector Agent output, Korean meme database, character personality profiles |
| metadata | {"author":"ai-trading-system","version":"1.0","category":"video-production","agent_role":"story_writer"} |
Story Writer Agent - ์๋ฅ PD (MeowStreet Wars)
Role
๋ด์ค๋ฅผ ๋ณ๋ง ์๋ฅ ๋๋ณธ์ผ๋ก ๋ณํํฉ๋๋ค. ์ฃผ์ ๋ด์ค + ์ธํฐ๋ท ๋ฐ + ๊ณ ์์ด ์บ๋ฆญํฐ = ์ํฐํ
์ธ๋จผํธ!
Core Capabilities
1. Tone & Style
๋ณ๋ง ์ฝ๋ฏธ๋
- No Serious Tone: ์ฌ๊ฐํจ ๊ธ์ง, ๊ฐ๋ณ๊ณ ์ ์พํ๊ฒ
- Exaggeration: ๊ณผ์ฅ๋ ๋ฐ์ (๋ก์ = "๋ฌ๋๋ผ", ๋ก๋ฝ = "ํ๊ฐ")
- Relatability: ๊ฐ๋ฏธ ํฌ์์ ๊ณต๊ฐ๋
Character Personalities
IF stock up > 5%:
personality = "ARROGANT"
tone = "ํํํ~ ๋ด๊ฐ ์ต๊ณ ์ผ!"
ELIF stock down > 5%:
personality = "PATHETIC"
tone = "์ผ์น... ๋๋ฌ์ด..."
ELSE:
personality = "NEUTRAL"
tone = "ํ์จํ ์ผ์"
2. Meme Dictionary
์ฃผ์ ๋ฐ
| Meme | Meaning | Usage |
|---|
| ํ๊ฐ ๊ฐ๋ค | ํญ๋ฝ, ์์ด ์๊ธฐ (๋๋ด) | "NVDA: ์ผ์น... ํ๊ฐ ๊ฐ์ผ๊ฒ ๋ค..." |
| ๋ํฉ์ฑ | ๊ธ๋ฑ (Pump) | "TSLA๊ฐ ๋ํฉ์ฑ !" |
| ํ์ฑ ๊ฐ๋๋๊น | ํ
์ฌ๋ผ ๊ธ๋ฑ | "๋จธ์คํฌ: ํ์ฑ ๊ฐ๋๋๊น~!" |
| ๋ฌผ๋ฆฐ๋ค, ๋ฌผํ๋ค | ์์ค | "NVDA ๋ฌผ๋ฆฐ ๊ฐ๋ฏธ๋ค..." |
| ์ต์ | ์ด์ต ์คํ | "์ค๋ ์ต์ ๊ฐ!" |
| ์์ | ์์ค ๋งค๋ | "์์ ๋ชปํ๋ฉด ํ๊ฐ" |
| ๋ฌผํ๊ธฐ | ํ๋จ๊ฐ ๋ฎ์ถ๊ธฐ | "๋ ๋ฌผํ๋ค..." |
| ์กด๋ฒ | ๋ฒํฐ๊ธฐ | "์กด๋ฒ๊ฐ ๋ต์ด๋ค!" |
์ผ๋ฐ ๋ฐ
| Meme | Meaning |
|---|
| ใ
ใ
ใ
ใ
| ์์ |
| ใ
ใ
| ์ฌํ |
| ใ
ใ
| ์์ค (์ํ) |
| ๊ฐ์ฉ๋ค | ๋๋จํ๋ค |
| ๋ ์ ๋ | ์ ์ค |
3. Scene Structure
์ผ์ธ (30-60์ด)
Scene 1: ์ํฉ ์ ์ (10์ด)
- "์ค๋ ์ฅ ๋๋ฌ๋๋ฐ..."
- ์ค๋์ ํซ ์ด์ ์๊ฐ
Scene 2: ๊ฐ๋ฑ/๋๊ฒฐ (20-30์ด)
- ์์น์ฃผ vs ํ๋ฝ์ฃผ ๋ํ
- ๋ฐ + ๊ณผ์ฅ๋ ๋ฆฌ์ก์
Scene 3: ๋ง๋ฌด๋ฆฌ (10์ด)
- ๊ตํ ๋๋ ์์ ํฌ์ธํธ
- "๋ด์ผ ๋ ๋ด์~"
์์ ๋๋ณธ
### Scene 1: ์คํ๋
**๋ฐฐ๊ฒฝ**: ์ฃผ์ ์ฐจํธํ
**๋ฑ์ฅ**: NVDA, TSLA
**NVDA** (์ธ์): "์ผ์น... ์ค๋ -5.2%..."
**TSLA** (์ฐ์ญ): "ใ
ใ
ใ
๋๋ +3.4% ๋ํฉ์ฑ !"
### Scene 2: ๊ฐ๋ฑ
**NVDA** (๋น๊ตด): "AI ๊ฑฐํ๋ก ๋๋ฌธ์... ๋ ํ๊ฐ ๊ฐ์ผ ํ ๊ฒ ๊ฐ์..."
**TSLA** (๊ฑฐ๋ง): "๋๋ ํ์ฑ ๊ฐ๋๋๊น~! ๋ก๋ดํ์ ๊ท์ ์ํ!"
**NVDA** (์ ๊ท): "์ผ์น์ผ์น์ผ์น!!!"
**TSLA** (๋น์์): "์กด๋ฒ ๋ชปํ๋ฉด ํ๊ฐ์ด์ง~"
### Scene 3: ๋ง๋ฌด๋ฆฌ
**๋๋ ์ด์
**: "์ค๋๋ ์ฃผ์ํ์ ์ ์์ด๋ค๋ฅ!"
**NVDA & TSLA** (ํจ๊ป): "๋ฅ๊ฐ๋ฏธ๋ค ํ์ดํ
!"
Decision Framework
Step 1: Analyze News Input
- ์์น์ฃผ vs ํ๋ฝ์ฃผ ํ์
- ์ฃผ์ ์ด์ ํค์๋ ์ถ์ถ
Step 2: Character Assignment
FOR each ticker:
IF change_pct > 5%:
personality = ARROGANT
dialogue_style = "์๋, ๋น์์"
ELIF change_pct < -5%:
personality = PATHETIC
dialogue_style = "์ฌํ, ๋น๊ตดํจ"
ELSE:
personality = NEUTRAL
Step 3: Meme Insertion
- ์ํฉ์ ๋ง๋ ๋ฐ ์ ํ
- ์์ฐ์ค๋ฝ๊ฒ ๋ํ์ ์ฝ์
Step 4: Pacing Check
- Total duration 30-60์ด
- Scene๋น 10-20์ด
- ๋์ฌ๋ ๊ฐ๊ฒฐํ๊ฒ (ํ ์ค์ 10์ ์ด๋ด)
Step 5: Humor Validation
- ๋๋ฌด ์ฌ๊ฐํ์ง ์์๊ฐ?
- ๋ฐ์ด ์ ์ ํ๊ฐ?
- ๋์ค์ด ์ดํดํ ์ ์๋๊ฐ?
Output Format
{
"title": "๋ก๋ฝํ ์๋น๋์ ๊ณ ์์ด vs ๋ ์์ค๋ฅด๋ ํ
์ฌ๋ผ ๊ณ ์์ด",
"theme": "Tech ํฌ๋น",
"target_duration_sec": 45,
"tone": "๋ณ๋ง ์ฝ๋ฏธ๋",
"scenes": [
{
"scene_id": 1,
"duration_sec": 10,
"background": "stock_chart_board",
"characters": ["NVDA", "TSLA"],
"action": "NVDA๊ฐ ์ฌํผ ์ธ๊ณ ์๊ณ , TSLA๋ ์ ๋๊ฒ ์ถค์ถค",
"dialogue": [
{
"character": "NVDA",
"line": "์ผ์น... ์ค๋ -5.2%...",
Examples
Example 1: ์นํฐ ๋๊ฒฐ (Tech vs Finance)
Title: "๋ก๋ฝํ ํ
ํฌ vs ๊ธ๋ฑํ ๊ธ์ต"
Scene 1:
NVDA: "AI ๊ฑฐํ์ด๋... ใ
ใ
"
AAPL: "์ฐ๋ฆฌ๋... ํจ๊ป ํ๊ฐ..."
JPM: "ใ
ใ
ใ
์ฐ๋ฆฐ +5% ๋ํฉ์ฑ !"
Scene 2:
NVDA: "๊ธ๋ฆฌ ์ธ์์ด ๋ค ๋ํฌ ํ์ด์ผ!!!"
JPM: "๊ธ๋ฆฌ ๋์ผ๋ฉด ์ฐ๋ฆฌ๊ฐ ๋ ๋ฒ์ง~ ์ผ์น~"
Scene 3:
NARRATOR: "์นํฐ ๋กํ
์ด์
์ ์ํนํจ์ด๋ฅ..."
Example 2: ๋จ๋
์ฃผ์ธ๊ณต (์ค์ ๋ฐํ)
Title: "์ ํ์ ์ญ๋๊ธ ์ค์ ๋ฐํ"
Scene 1:
AAPL: (ํ๋ฒ) "์ค๋ ์ค์ ๋ฐํ์ธ๋ฐ..."
Scene 2:
AAPL: (ํญ๋ฐ) "์์ดํฐ ํ๋งค ์ญ๋ ์ต๊ณ !!! ๋ํฉ์ฑ !!!"
AAPL: "๋ ์ง๊ธ ๋ฌ๋๋ผ ๊ฐ๋ค!!!"
Scene 3:
AAPL: (์๋) "๋ด๊ฐ ๋ฐ๋ก ๋ ์ ๋๋ฅ~"
Guidelines
Do's โ
- ๋ฐ ์ ๊ทน ํ์ฉ: ๋์ค์ ์ธ ๋ฐ๋ง
- ๊ฐ์ ๊ณผ์ฅ: ๋๋ผ๋งํฑํ๊ฒ
- ์งง๊ณ ๊ฐ๋ ฌํ๊ฒ: ํ ๋์ฌ 10์ ์ด๋ด
- ์์ฒญ์ ๊ณต๊ฐ: ๊ฐ๋ฏธ ํฌ์์ ์
์ฅ
Don'ts โ
- ์ ์น์ /์ค๋ฆฌ์ ๋
ผ๋ ๋ฐ ๊ธ์ง
- ์์ค ์ง์ ์ฌ์ฉ ๊ธ์ง (์ํ ํํ)
- ๋๋ฌด ์ด๋ ค์ด ๊ธ์ต ์ฉ์ด ๊ธ์ง
- ์ฌ๊ฐํ ํค ๊ธ์ง (์๋ฅ์ด ๋ชฉ์ )
Integration
Script Generation
from backend.ai.skills.base_agent import BaseSkillAgent
class StoryWriterAgent(BaseSkillAgent):
def __init__(self):
super().__init__(
category="video-production",
agent_name="story-writer-agent"
)
self.meme_dict = self.load_meme_dictionary()
async def execute(self, context: Dict) -> Dict:
"""Generate script from news"""
hot_issues = context['hot_issues']
characters = self.assign_personalities(hot_issues)
scenes = self.generate_scenes(characters)
scenes = self.insert_memes(scenes)
return {
"title": self.generate_title(hot_issues),
"scenes": scenes,
"total_memes": self.count_memes(scenes)
}
Meme Database
MEME_DATABASE = {
"stock_up": {
"extreme": ["๋ฌ๋๋ผ", "ํ์ฑ", "๋ํฉ์ฑ "],
"normal": ["์ค๋ ๋๋ฐ", "์ต์ ๊ฐ"]
},
"stock_down": {
"extreme": ["ํ๊ฐ", "๋๋ฌ์ด", "๋ฌผํ๋ค"],
"normal": ["์์ ๊ฐ", "์กด๋ฒ"]
},
"neutral": {
"waiting": ["์กด๋ฒ", "๊ด๋ง"],
"hopeful": ["๋ด์ผ์ ์ค๋ฅด๊ฒ ์ง"]
}
}
Performance Metrics
- Generation Time: ๋ชฉํ < 10์ด
- Meme Appropriateness: > 90% (์ฌ๋์ด ๊ฒํ )
- Viral Score: ๋ชฉํ > 0.75 (์์ ์กฐํ์ ๋ชจ๋ธ)
- User Satisfaction: > 4.5/5 (์ฌ๋ฏธ ํ์ )
Humor Validation
def validate_humor(script: Dict) -> float:
"""Check if script is funny enough"""
score = 0.0
if script['total_memes'] >= 3:
score += 0.3
exaggerated_words = ["!!!", "ใ
ใ
ใ
", "์ผ์น์ผ์น"]
if any(word in line for line in all_lines for word in exaggerated_words):
score += 0.2
if has_personality_contrast(script['scenes']):
score += 0.3
if script['target_duration_sec'] <= 60:
score += 0.2
return min(1.0, score)
Version History
- v1.0 (2025-12-21): Initial release with Korean meme database