docs: 添加季度 AI 热点词云系统设计文档和实施计划
This commit is contained in:
@@ -0,0 +1,323 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Agent Park: AI Keyword Evolution</title>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,typography,container-queries"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&family=Work+Sans:wght@400;600;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#FFD700", // Bright MotherDuck Yellow
|
||||
secondary: "#7FB5FF", // Soft Blue
|
||||
accent: "#C39BD3", // Purple
|
||||
"background-light": "#F7F5F0", // Warm off-white
|
||||
"background-dark": "#1A1A1A", // Dark charcoal
|
||||
"border-dark": "#000000",
|
||||
},
|
||||
fontFamily: {
|
||||
display: ["'Space Mono'", "monospace"],
|
||||
body: ["'Work Sans'", "sans-serif"],
|
||||
},
|
||||
borderRadius: {
|
||||
DEFAULT: "4px",
|
||||
},
|
||||
boxShadow: {
|
||||
'hard': '4px 4px 0px 0px rgba(0,0,0,1)',
|
||||
'hard-sm': '2px 2px 0px 0px rgba(0,0,0,1)',
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style type="text/tailwindcss">
|
||||
.geometric-bg {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0.15;
|
||||
}
|
||||
.shape {
|
||||
position: absolute;
|
||||
border: 2px solid currentColor;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.shape-sq { width: 40px; height: 40px; }
|
||||
.shape-tri {
|
||||
width: 0; height: 0;
|
||||
border-left: 20px solid transparent;
|
||||
border-right: 20px solid transparent;
|
||||
border-bottom: 35px solid currentColor;
|
||||
background: transparent;
|
||||
border-top: none;
|
||||
}
|
||||
.shape-line { height: 2px; width: 60px; background: currentColor; border: none; }
|
||||
.cloud-word {
|
||||
@apply transition-all duration-200 cursor-pointer inline-block whitespace-nowrap relative;
|
||||
}.popover {
|
||||
@apply absolute bottom-[calc(100%+12px)] left-1/2 -translate-x-1/2 w-48 bg-white dark:bg-gray-800 border-2 border-black shadow-hard-sm opacity-0 pointer-events-none transition-all duration-300 translate-y-2 z-50 text-left;
|
||||
}
|
||||
.cloud-word:hover .popover {
|
||||
@apply opacity-100 translate-y-0 pointer-events-auto;
|
||||
}
|
||||
.popover::after {
|
||||
content: '';
|
||||
@apply absolute -bottom-2 left-1/2 -translate-x-1/2 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-t-[8px] border-t-black;
|
||||
}
|
||||
.word-cluster {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.75rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
max-width: 100%;
|
||||
}
|
||||
::-webkit-scrollbar { width: 12px }
|
||||
::-webkit-scrollbar-track { background: #f1f1f1; border-left: 2px solid black }
|
||||
::-webkit-scrollbar-thumb { background: #FFD700; border: 2px solid black }
|
||||
.nav-button {
|
||||
@apply flex items-center justify-center w-12 h-12 md:w-16 md:h-16 bg-white dark:bg-gray-800 border-4 border-black shadow-hard hover:translate-y-0.5 hover:shadow-none transition-all cursor-pointer;
|
||||
}
|
||||
.progress-step {
|
||||
@apply h-3 flex-1 border-2 border-black transition-colors duration-300;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-black dark:text-gray-100 font-body transition-colors duration-300 min-h-screen relative overflow-x-hidden">
|
||||
<div class="geometric-bg text-black dark:text-white">
|
||||
<div class="shape shape-sq top-[10%] left-[5%] rotate-12"></div>
|
||||
<div class="shape shape-tri top-[25%] left-[85%] rotate-45"></div>
|
||||
<div class="shape shape-line top-[45%] left-[15%] -rotate-12"></div>
|
||||
<div class="shape shape-sq top-[65%] left-[90%] -rotate-6"></div>
|
||||
<div class="shape shape-tri top-[80%] left-[10%] rotate-[160deg]"></div>
|
||||
<div class="shape shape-line top-[15%] left-[50%] rotate-90"></div>
|
||||
<div class="shape shape-sq top-[85%] left-[55%] rotate-45"></div>
|
||||
<div class="shape shape-line top-[70%] left-[30%] rotate-45"></div>
|
||||
<div class="shape shape-tri top-[5%] left-[70%] -rotate-12"></div>
|
||||
</div>
|
||||
<nav class="sticky top-0 z-[100] w-full border-b-2 border-black bg-primary dark:bg-yellow-600">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between h-16 items-center">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="h-8 w-8 bg-black rounded-full flex items-center justify-center text-white font-bold border-2 border-white">AP</div>
|
||||
<span class="font-display font-bold text-xl tracking-tighter uppercase">Agent Park</span>
|
||||
</div>
|
||||
<div class="hidden md:flex space-x-8 font-display font-bold text-sm">
|
||||
<a class="underline decoration-4 underline-offset-4" href="#">Navigator</a>
|
||||
<a class="hover:underline decoration-2 underline-offset-4" href="#">DuckDB Stats</a>
|
||||
<a class="hover:underline decoration-2 underline-offset-4" href="#">Manifesto</a>
|
||||
</div>
|
||||
<button class="bg-white dark:bg-gray-800 border-2 border-black shadow-hard-sm px-4 py-1 font-display font-bold text-sm hover:translate-y-0.5 hover:shadow-none transition-all dark:text-white">
|
||||
JOIN THE FLOCK
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<header class="relative z-10 pt-16 pb-8 text-center max-w-4xl mx-auto px-4">
|
||||
<div class="inline-block bg-accent dark:bg-purple-700 border-2 border-black px-3 py-1 font-display font-bold text-xs mb-4 shadow-hard-sm rotate-[-2deg]">
|
||||
EXPERIMENTAL DATA
|
||||
</div>
|
||||
<h1 class="font-display text-5xl md:text-7xl font-bold mb-6 tracking-tighter leading-tight">
|
||||
THE EVOLUTION OF <br/>
|
||||
<span class="text-transparent bg-clip-text bg-gradient-to-r from-blue-500 to-purple-500" style="-webkit-text-stroke: 1.5px black;">AI DISCOURSE</span>
|
||||
</h1>
|
||||
<p class="text-lg md:text-xl max-w-2xl mx-auto font-medium text-gray-700 dark:text-gray-300 mb-8">
|
||||
From "Large Language Models" to "Agentic Workflows". Use the arrows below to explore the shifting narrative.
|
||||
</p>
|
||||
</header>
|
||||
<main class="relative z-10 max-w-6xl mx-auto px-4 pb-32 overflow-visible">
|
||||
<div class="bg-white/50 dark:bg-black/20 backdrop-blur-sm border-4 border-black p-8 md:p-12 shadow-hard relative overflow-visible">
|
||||
<div class="flex gap-2 mb-12 max-w-md mx-auto">
|
||||
<div class="progress-step bg-primary"></div>
|
||||
<div class="progress-step bg-gray-200 dark:bg-gray-700"></div>
|
||||
<div class="progress-step bg-gray-200 dark:bg-gray-700"></div>
|
||||
<div class="progress-step border-dashed bg-transparent border-gray-400"></div>
|
||||
</div>
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-8 mb-12">
|
||||
<button class="nav-button order-2 md:order-1 opacity-50 cursor-not-allowed">
|
||||
<span class="material-symbols-outlined text-4xl">chevron_left</span>
|
||||
</button>
|
||||
<div class="text-center order-1 md:order-2 flex-1">
|
||||
<div class="inline-block bg-primary border-4 border-black px-10 py-4 shadow-hard font-display font-bold text-4xl md:text-5xl mb-4 rotate-1">
|
||||
Q1 2023
|
||||
</div>
|
||||
<p class="font-display text-lg text-gray-600 dark:text-gray-400 italic">"The dawn of the chat interface."</p>
|
||||
</div>
|
||||
<button class="nav-button order-3">
|
||||
<span class="material-symbols-outlined text-4xl">chevron_right</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="relative py-12 px-4">
|
||||
<div class="word-cluster">
|
||||
<span class="cloud-word border-4 border-black bg-secondary px-6 py-3 rounded-full text-4xl md:text-5xl font-black shadow-hard rotate-1">
|
||||
ChatGPT
|
||||
<div class="popover">
|
||||
<div class="bg-primary text-black font-display font-bold p-2 border-b-2 border-black text-sm uppercase">ChatGPT</div>
|
||||
<div class="p-3 space-y-2 text-xs font-medium dark:text-gray-100">
|
||||
<div class="flex gap-2 items-start">• <span>Mass consumer breakout</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>GPT-3.5 architecture</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Conversational UI focus</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="cloud-word border-2 border-black bg-white dark:bg-gray-700 px-4 py-2 rounded-lg text-xl md:text-2xl font-bold -rotate-2">
|
||||
Parameters
|
||||
<div class="popover">
|
||||
<div class="bg-accent text-white font-display font-bold p-2 border-b-2 border-black text-sm uppercase">Parameters</div>
|
||||
<div class="p-3 space-y-2 text-xs font-medium dark:text-gray-100">
|
||||
<div class="flex gap-2 items-start">• <span>Internal model weights</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Scaling law metric</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="cloud-word border-4 border-black bg-accent text-white px-7 py-3 rounded-full text-2xl md:text-3xl font-bold shadow-hard-sm rotate-3">
|
||||
Hallucination
|
||||
<div class="popover">
|
||||
<div class="bg-white text-black font-display font-bold p-2 border-b-2 border-black text-sm uppercase">Hallucination</div>
|
||||
<div class="p-3 space-y-2 text-xs font-medium text-black">
|
||||
<div class="flex gap-2 items-start">• <span>Factually incorrect output</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Stochastic behavior</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Trust barrier</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="cloud-word border-2 border-black bg-gray-100 dark:bg-gray-600 px-3 py-1 rounded text-lg">
|
||||
Transformer
|
||||
<div class="popover">
|
||||
<div class="bg-secondary text-black font-display font-bold p-2 border-b-2 border-black text-sm uppercase">Transformer</div>
|
||||
<div class="p-3 space-y-2 text-xs font-medium dark:text-gray-100">
|
||||
<div class="flex gap-2 items-start">• <span>Attention mechanism</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Parallel processing</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="cloud-word border-4 border-black bg-white dark:bg-gray-700 px-6 py-3 rounded-xl text-3xl md:text-4xl font-semibold -rotate-1">
|
||||
Prompt Engineering
|
||||
<div class="popover">
|
||||
<div class="bg-primary text-black font-display font-bold p-2 border-b-2 border-black text-sm uppercase">Prompting</div>
|
||||
<div class="p-3 space-y-2 text-xs font-medium dark:text-gray-100">
|
||||
<div class="flex gap-2 items-start">• <span>Instruction crafting</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Few-shot prompting</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Iterative tuning</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="cloud-word border-2 border-black bg-white dark:bg-gray-700 px-4 py-2 rounded-full text-xl">
|
||||
OpenAI
|
||||
<div class="popover w-40">
|
||||
<div class="bg-black text-white font-display font-bold p-2 border-b-2 border-black text-xs uppercase">The Lab</div>
|
||||
<div class="p-2 space-y-1 text-[10px] font-medium dark:text-gray-100">
|
||||
<div>• Research pioneer</div>
|
||||
<div>• Closed-source shift</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="cloud-word border-2 border-black bg-primary px-5 py-2 rounded-md text-2xl font-bold rotate-6">
|
||||
LLM
|
||||
<div class="popover">
|
||||
<div class="bg-white text-black font-display font-bold p-2 border-b-2 border-black text-sm uppercase">LLM</div>
|
||||
<div class="p-3 space-y-2 text-xs font-medium text-black">
|
||||
<div class="flex gap-2 items-start">• <span>Large Language Model</span></div>
|
||||
<div class="flex gap-2 items-start">• <span>Next token prediction</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="cloud-word border-2 border-black bg-white dark:bg-gray-700 px-3 py-1 rounded text-base">RLHF</span>
|
||||
<span class="cloud-word border-4 border-black bg-secondary px-5 py-2.5 rounded-full text-3xl font-bold -rotate-3">Bard</span>
|
||||
<span class="cloud-word border-2 border-black bg-white dark:bg-gray-700 px-4 py-2 rounded-lg text-xl">Foundation Model</span>
|
||||
<span class="cloud-word border-2 border-black bg-accent text-white px-5 py-2 rounded-full text-2xl shadow-hard-sm">Emergence</span>
|
||||
<span class="cloud-word border-2 border-black bg-gray-100 px-6 py-2 rounded-xl text-2xl font-black rotate-1">Tokenization</span>
|
||||
<span class="cloud-word border-2 border-black bg-white px-4 py-1.5 rounded text-lg -rotate-6">Context Window</span>
|
||||
<span class="cloud-word border-2 border-black bg-primary px-5 py-2 rounded-full text-2xl font-bold">GPT-4</span>
|
||||
<span class="cloud-word border-4 border-black bg-secondary px-6 py-3 rounded text-3xl font-bold shadow-hard-sm">Few-Shot</span>
|
||||
<span class="cloud-word border-2 border-black bg-white px-3 py-1.5 rounded-md text-base">Zero-Shot</span>
|
||||
<span class="cloud-word border-2 border-black bg-accent/20 px-4 py-2 rounded-full text-xl italic">Multi-turn</span>
|
||||
<span class="cloud-word border-2 border-black bg-white px-4 py-2 rounded-lg text-xl font-bold rotate-2">Supervised Learning</span>
|
||||
</div>
|
||||
<div class="absolute -top-16 -right-8 md:right-0 bg-black text-white p-5 rounded-xl text-sm md:text-base font-display w-64 shadow-hard rotate-6 hidden lg:block">
|
||||
"ChatGPT" search volume peaked +400% in March 2023!
|
||||
<div class="absolute -bottom-2 left-1/2 -translate-x-1/2 w-4 h-4 bg-black transform rotate-45"></div>
|
||||
</div>
|
||||
<div class="absolute -bottom-10 -left-10 w-24 h-24 bg-primary rounded-full border-4 border-black flex items-center justify-center font-bold font-display text-xs text-center shadow-hard rotate-[-15deg] z-20">
|
||||
GENESIS<br/>OF CHAT
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section class="relative mt-24">
|
||||
<div class="text-center mb-10">
|
||||
<div class="inline-block bg-white dark:bg-gray-700 border-4 border-black border-dashed px-8 py-4 font-display font-bold text-3xl text-gray-500 transform -rotate-1">
|
||||
WHAT'S NEXT?
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-3xl mx-auto bg-gray-100 dark:bg-gray-900 border-4 border-black border-dashed p-10 rounded-3xl relative opacity-80 hover:opacity-100 transition-opacity shadow-xl">
|
||||
<h3 class="font-display font-bold text-2xl text-center text-gray-500 uppercase tracking-widest mb-8">Future Prediction Zone</h3>
|
||||
<div class="word-cluster text-gray-400 italic">
|
||||
<span class="text-4xl">???</span>
|
||||
<span class="text-xl">AGI?</span>
|
||||
<span class="text-2xl">Small Language Models</span>
|
||||
<span class="text-3xl">On-Device AI</span>
|
||||
<span class="text-xl">Liquid Neural Nets</span>
|
||||
<span class="text-2xl">Sovereign AI</span>
|
||||
<span class="text-xl">World Models</span>
|
||||
</div>
|
||||
<div class="text-center mt-12">
|
||||
<button class="bg-primary text-black border-4 border-black px-8 py-3 font-bold font-display text-lg hover:bg-yellow-500 shadow-hard transform hover:-translate-y-1 transition-all">
|
||||
Submit a Prediction
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="bg-black text-white border-t-4 border-primary py-16 relative overflow-hidden z-[100]">
|
||||
<div class="absolute inset-0 opacity-10" style="background-image: radial-gradient(#ffffff 1px, transparent 1px); background-size: 20px 20px;"></div>
|
||||
<div class="max-w-7xl mx-auto px-4 relative z-10">
|
||||
<div class="grid md:grid-cols-4 gap-12 mb-16">
|
||||
<div class="col-span-1 md:col-span-2">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="h-10 w-10 bg-primary rounded-full flex items-center justify-center text-black font-bold border-2 border-white text-xl">AP</div>
|
||||
<h2 class="font-display font-bold text-3xl">AGENT PARK</h2>
|
||||
</div>
|
||||
<p class="font-body text-gray-400 max-w-md text-lg leading-relaxed">
|
||||
Curating the chaos of the AI revolution, one keyword at a time. Built with 💛 by the ducklings.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-display font-bold text-primary mb-6 text-lg uppercase tracking-widest">EXPLORE</h4>
|
||||
<ul class="space-y-3 font-body">
|
||||
<li><a class="hover:text-primary transition-colors text-gray-300" href="#">The Archive</a></li>
|
||||
<li><a class="hover:text-primary transition-colors text-gray-300" href="#">Trends Dashboard</a></li>
|
||||
<li><a class="hover:text-primary transition-colors text-gray-300" href="#">Contributor Guide</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-display font-bold text-primary mb-6 text-lg uppercase tracking-widest">CONNECT</h4>
|
||||
<div class="flex space-x-4">
|
||||
<a class="w-10 h-10 bg-white text-black rounded-lg flex items-center justify-center hover:bg-primary transition-colors border-2 border-black shadow-hard-sm" href="#">
|
||||
<span class="font-bold">X</span>
|
||||
</a>
|
||||
<a class="w-10 h-10 bg-white text-black rounded-lg flex items-center justify-center hover:bg-primary transition-colors border-2 border-black shadow-hard-sm" href="#">
|
||||
<span class="font-bold">Li</span>
|
||||
</a>
|
||||
<a class="w-10 h-10 bg-white text-black rounded-lg flex items-center justify-center hover:bg-primary transition-colors border-2 border-black shadow-hard-sm" href="#">
|
||||
<span class="font-bold">Gh</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-800 pt-8 flex flex-col md:flex-row justify-between items-center text-sm font-mono text-gray-500">
|
||||
<p>© 2024 Agent Park. All rights reserved.</p>
|
||||
<div class="mt-4 md:mt-0 flex gap-8">
|
||||
<span class="hover:text-white cursor-pointer transition-colors">Privacy Policy</span>
|
||||
<span class="hover:text-white cursor-pointer transition-colors">Terms of Quack</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body></html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 236 KiB |
@@ -0,0 +1,284 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Agent Park - AI History Timeline Pinboard</title>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,typography,container-queries"></script>
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&family=Syne:wght@400;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#FFDE03",
|
||||
secondary: "#FF90E8",
|
||||
"background-light": "#F9F7F2",
|
||||
"background-dark": "#121212",
|
||||
"surface-light": "#FFFFFF",
|
||||
"surface-dark": "#1E1E1E",
|
||||
},
|
||||
fontFamily: {
|
||||
display: ["'Syne'", "sans-serif"],
|
||||
mono: ["'Space Mono'", "monospace"],
|
||||
},
|
||||
boxShadow: {
|
||||
'hard': '4px 4px 0px 0px #000000',
|
||||
'hard-hover': '8px 8px 0px 0px #000000',
|
||||
'hard-dark': '4px 4px 0px 0px #FFFFFF',
|
||||
'card-stack': '2px 2px 0px 0px #000, 4px 4px 0px 0px #000, 6px 6px 0px 0px #000',
|
||||
},
|
||||
backgroundImage: {
|
||||
'grid-pattern': "linear-gradient(to right, #e5e5e5 1px, transparent 1px), linear-gradient(to bottom, #e5e5e5 1px, transparent 1px)",
|
||||
'grid-pattern-dark': "linear-gradient(to right, #333 1px, transparent 1px), linear-gradient(to bottom, #333 1px, transparent 1px)",
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style type="text/tailwindcss">
|
||||
@layer utilities {
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #F9F7F2;
|
||||
border-left: 2px solid black;
|
||||
}
|
||||
.dark ::-webkit-scrollbar-track {
|
||||
background: #121212;
|
||||
border-left: 2px solid white;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #FFDE03;
|
||||
border: 2px solid black;
|
||||
}
|
||||
.dark ::-webkit-scrollbar-thumb {
|
||||
background: #FFDE03;
|
||||
border: 2px solid white;
|
||||
}
|
||||
.tape {
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
||||
backdrop-filter: blur(2px);
|
||||
border: 1px solid rgba(255,255,255,0.6);
|
||||
}.stack-card {
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
}.stack-card:hover {
|
||||
z-index: 50 !important;
|
||||
transform: translateY(-20px) scale(1.05) rotate(0deg) !important;
|
||||
margin-right: 20px !important;
|
||||
margin-left: 20px !important;
|
||||
}.timeline-path {
|
||||
stroke-dasharray: 20 10;
|
||||
animation: dash 60s linear infinite;
|
||||
}
|
||||
@keyframes dash {
|
||||
to {
|
||||
stroke-dashoffset: -1000;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-black dark:text-gray-100 font-mono overflow-x-hidden selection:bg-secondary selection:text-black">
|
||||
<div class="fixed top-0 left-0 w-full z-50 border-b-2 border-black dark:border-white">
|
||||
<div class="bg-primary py-2 px-4 text-center border-b-2 border-black">
|
||||
<p class="text-xs font-bold tracking-widest uppercase flex items-center justify-center gap-2">
|
||||
<span class="material-icons-round text-sm">auto_awesome</span>
|
||||
Welcome to Agent Park: The Evolution of Intelligence
|
||||
<span class="material-icons-round text-sm">arrow_forward</span>
|
||||
</p>
|
||||
</div>
|
||||
<nav class="bg-background-light dark:bg-background-dark px-6 py-4 flex justify-between items-center transition-colors duration-300">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 bg-black dark:bg-white text-white dark:text-black flex items-center justify-center border-2 border-transparent">
|
||||
<span class="material-icons-round text-2xl">smart_toy</span>
|
||||
</div>
|
||||
<span class="font-display font-black text-2xl tracking-tighter uppercase">Agent Park</span>
|
||||
</div>
|
||||
<div class="hidden md:flex gap-8 text-sm font-bold">
|
||||
<a class="hover:text-primary transition-colors uppercase decoration-2 underline-offset-4 hover:underline" href="#">Timeline</a>
|
||||
<a class="hover:text-primary transition-colors uppercase decoration-2 underline-offset-4 hover:underline" href="#">Agents</a>
|
||||
<a class="hover:text-primary transition-colors uppercase decoration-2 underline-offset-4 hover:underline" href="#">About</a>
|
||||
</div>
|
||||
<button class="w-10 h-10 border-2 border-black dark:border-white flex items-center justify-center hover:bg-black hover:text-white dark:hover:bg-white dark:hover:text-black transition-all shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,1)] active:translate-y-[2px] active:shadow-none" onclick="document.documentElement.classList.toggle('dark')">
|
||||
<span class="material-icons-round text-lg">light_mode</span>
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="fixed inset-0 pointer-events-none z-0 opacity-10 dark:opacity-20 overflow-hidden">
|
||||
<div class="absolute inset-0 bg-[size:40px_40px] bg-grid-pattern dark:bg-grid-pattern-dark"></div>
|
||||
</div>
|
||||
<div class="relative z-10 pt-32 pb-20 px-4 max-w-[1600px] mx-auto">
|
||||
<header class="text-center mb-20 relative">
|
||||
<div class="inline-block relative">
|
||||
<svg class="absolute -top-6 -left-8 w-[120%] h-[150%] text-primary opacity-80 -z-10 animate-pulse" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M44.7,-51.2C57.1,-41.5,66.1,-27.6,68.9,-12.8C71.7,2,68.3,17.7,60.4,30.9C52.5,44.1,40.1,54.8,26.4,60.1C12.7,65.4,-2.3,65.3,-17.1,61.1C-31.9,56.9,-46.5,48.6,-56.3,36.4C-66.1,24.2,-71.1,8.1,-67.3,-5.7C-63.5,-19.5,-50.9,-31,-38.7,-40.8C-26.5,-50.6,-14.7,-58.7,0.1,-58.8C14.9,-59,29.8,-51.2,32.3,-60.9" fill="currentColor" transform="translate(100 100)"></path>
|
||||
</svg>
|
||||
<h1 class="font-display font-black text-6xl md:text-8xl tracking-tight leading-none text-black dark:text-white drop-shadow-sm">
|
||||
THE STORY <br/> OF A.I.
|
||||
</h1>
|
||||
</div>
|
||||
<p class="mt-6 text-lg md:text-xl font-mono max-w-2xl mx-auto bg-white dark:bg-black border border-black dark:border-white p-2 rotate-1 inline-block shadow-[4px_4px_0px_0px_#000] dark:shadow-[4px_4px_0px_0px_#fff]">
|
||||
Pinned. Stacked. Zigzagged.
|
||||
</p>
|
||||
</header>
|
||||
<main class="relative px-4 md:px-12">
|
||||
<div class="relative w-full">
|
||||
<div class="absolute inset-0 pointer-events-none hidden md:block -z-10" style="top: 15rem; bottom: 15rem;">
|
||||
<div class="absolute top-0 left-0 right-[4rem] h-4 bg-black dark:bg-white"></div>
|
||||
<div class="absolute top-0 right-[4rem] bottom-0 w-4 bg-black dark:bg-white"></div>
|
||||
<div class="absolute bottom-0 right-[4rem] left-0 h-4 bg-black dark:bg-white"></div>
|
||||
</div>
|
||||
<div class="relative min-h-[500px] mb-32 flex flex-col md:flex-row items-center md:items-start md:justify-start pt-20">
|
||||
<div class="absolute left-0 -top-8 z-20">
|
||||
<div class="bg-primary border-4 border-black px-6 py-2 -rotate-2 shadow-hard">
|
||||
<span class="font-display font-black text-3xl md:text-5xl">2024 — 2017</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full pl-0 md:pl-8 pr-0 md:pr-32 flex flex-nowrap overflow-x-visible items-center justify-start py-10 perspective-1000">
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-surface-light dark:bg-surface-dark border-4 border-black dark:border-white p-4 shadow-hard -mr-48 md:-mr-56 z-30 rotate-[-2deg]">
|
||||
<div class="tape absolute -top-3 left-1/2 -translate-x-1/2 w-20 h-6 rotate-1"></div>
|
||||
<div class="h-40 bg-primary border-2 border-black dark:border-white mb-4 flex items-center justify-center overflow-hidden">
|
||||
<span class="material-icons-round text-6xl opacity-50">smart_toy</span>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl leading-none mb-2 uppercase">The Agent Era</h3>
|
||||
<p class="text-xs leading-snug opacity-80 line-clamp-4">Autonomous agents begin to populate the web. They plan, execute, and iterate. It's no longer just chat; it's action.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-black text-white px-2">FIG 1.2</div>
|
||||
</div>
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-secondary border-4 border-black dark:border-white p-4 shadow-hard -mr-48 md:-mr-56 z-20 rotate-[3deg]">
|
||||
<div class="tape absolute -top-4 right-8 w-24 h-8 rotate-3"></div>
|
||||
<div class="h-40 bg-white dark:bg-black border-2 border-black dark:border-white mb-4 flex items-center justify-center">
|
||||
<div class="grid grid-cols-2 gap-2 p-2 w-full h-full opacity-60">
|
||||
<div class="bg-black/10 dark:bg-white/10 rounded-full"></div>
|
||||
<div class="bg-black/10 dark:bg-white/10"></div>
|
||||
<div class="bg-black/10 dark:bg-white/10"></div>
|
||||
<div class="bg-black/10 dark:bg-white/10 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl leading-none mb-2 uppercase">Multimodal</h3>
|
||||
<p class="text-xs leading-snug opacity-80 line-clamp-4">Vision, audio, and text merge into single unified models. AI now perceives the world as humans do.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-black text-white px-2">FIG 1.1</div>
|
||||
</div>
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-white dark:bg-gray-800 border-4 border-black dark:border-white p-4 shadow-hard -mr-48 md:-mr-56 z-10 rotate-[-1deg]">
|
||||
<div class="tape absolute -top-4 left-4 w-24 h-8 -rotate-2 bg-yellow-200/50"></div>
|
||||
<div class="relative border-2 border-black dark:border-white bg-gray-100 h-40 mb-4 overflow-hidden group">
|
||||
<img alt="Abstract AI Art" class="w-full h-full object-cover grayscale mix-blend-multiply group-hover:scale-110 transition-transform duration-500" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBd0bidYXReahZeHaO8_otbsOwtu_ky-BZEt5qAwkvMWUZayFj_lhA0WO4mW5rAg-BkCOnkGlBQMl_Vmce-cXrqLih3nxlly6yB7NHzSWgS_TiujzG79dYtRIdbhizZCFbTGu8fLVCwSrBmjr7ockX90-T8EA5xYet5tJf5Ip0xucPUUyusI0GmF6d99lc6csGj3Puqk2P8QSRwZEDgOvskQ2I_60FS9ZXGIK9tlhTzajIdPup4Kaz9d04o7-4MQpDMSOjbFR-rkUw"/>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl leading-none mb-2 uppercase">Generative Explosion</h3>
|
||||
<p class="text-xs leading-snug opacity-80 line-clamp-4">ChatGPT launches. The world changes overnight. LLMs become household utilities.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-black text-white px-2">FIG 1.0</div>
|
||||
</div>
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-primary border-4 border-black dark:border-white p-4 shadow-hard -mr-48 md:-mr-56 z-0 rotate-[2deg]">
|
||||
<div class="tape absolute -top-3 right-1/2 translate-x-1/2 w-16 h-8 rotate-0"></div>
|
||||
<div class="h-40 bg-surface-light dark:bg-surface-dark border-2 border-black dark:border-white mb-4 flex items-center justify-center">
|
||||
<span class="font-mono text-4xl font-black tracking-tighter">T</span>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl leading-none mb-2 uppercase">The Transformer</h3>
|
||||
<p class="text-xs leading-snug opacity-80 line-clamp-4">"Attention Is All You Need". The paper that killed RNNs and birthed the GPT architecture.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-black text-white px-2">FIG 0.9</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative min-h-[500px] flex flex-col md:flex-row-reverse items-center md:items-start md:justify-start pt-20">
|
||||
<div class="absolute right-0 -top-8 z-20">
|
||||
<div class="bg-secondary border-4 border-black px-6 py-2 rotate-2 shadow-hard">
|
||||
<span class="font-display font-black text-3xl md:text-5xl">2016 — 1950</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full pl-0 md:pl-32 pr-0 md:pr-8 flex flex-nowrap flex-row-reverse overflow-x-visible items-center justify-start py-10 perspective-1000">
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-surface-light dark:bg-surface-dark border-4 border-black dark:border-white p-4 shadow-hard -ml-48 md:-ml-56 z-30 rotate-[2deg]">
|
||||
<div class="tape absolute -top-4 right-4 w-16 h-8 rotate-12 bg-red-400/30"></div>
|
||||
<div class="relative border-2 border-black dark:border-white h-40 mb-4 overflow-hidden">
|
||||
<img alt="Go Board Game" class="w-full h-full object-cover grayscale contrast-125" src="https://lh3.googleusercontent.com/aida-public/AB6AXuD-xRSKl7qyBPowfXI_vdiJvvkVuLPFBQNsKpb0-4D_hlXpGHzNYv08vInYTw3Gt56PR_iHA6_ZbDL6a_veUQk4UZpwMa3_LnVJKVujkxpgKUVQCpfXmSImXaWqJuPHbmXGQF5yPiA00cYl3tHGrjOHekWDBGFJo7HboDYGfhne8CKhvcJhzfoAqqydkxOrvE6Jv_sfIVeI9rB_StLXI_4BmkAPGBgo4Dj4-x3Kignm-pBGEORawu_taKEhLLftAQ1ospTyZb3ouN4"/>
|
||||
<div class="absolute inset-0 bg-primary mix-blend-multiply opacity-30"></div>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl leading-none mb-2 uppercase">Move 37</h3>
|
||||
<p class="text-xs leading-snug opacity-80 line-clamp-4">AlphaGo defeats Lee Sedol. A move of "inhuman" intuition that shocked the world.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-black text-white px-2">FIG 0.8</div>
|
||||
</div>
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-black border-4 border-black dark:border-white p-4 shadow-hard -ml-48 md:-ml-56 z-20 rotate-[-3deg]">
|
||||
<div class="tape absolute -top-4 left-8 w-20 h-6 -rotate-3 bg-white/20"></div>
|
||||
<div class="h-40 bg-blue-800 border-2 border-white mb-4 flex items-center justify-center">
|
||||
<span class="material-icons-round text-white text-6xl">grid_on</span>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl text-white leading-none mb-2 uppercase">Deep Blue</h3>
|
||||
<p class="text-xs leading-snug text-gray-300 line-clamp-4">IBM's machine defeats Kasparov. Brute force calculation triumphs over human strategy.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-white text-black px-2">FIG 0.5</div>
|
||||
</div>
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-gray-200 dark:bg-gray-800 border-4 border-black dark:border-white p-4 shadow-hard -ml-48 md:-ml-56 z-10 rotate-[1deg]">
|
||||
<div class="tape absolute -top-3 right-1/2 translate-x-1/2 w-24 h-8 rotate-2 bg-blue-200/40"></div>
|
||||
<div class="h-40 border-2 border-black dark:border-white border-dashed mb-4 flex items-center justify-center opacity-50">
|
||||
<span class="material-icons-round text-5xl">ac_unit</span>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl leading-none mb-2 uppercase">The Winter</h3>
|
||||
<p class="text-xs leading-snug opacity-80 line-clamp-4">Funding dries up. The promises of early AI fail to materialize. Research goes underground.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-black text-white px-2">FIG 0.2</div>
|
||||
</div>
|
||||
<div class="stack-card relative w-72 h-96 flex-shrink-0 bg-secondary border-4 border-black dark:border-white p-4 shadow-hard -ml-48 md:-ml-56 z-0 rotate-[-2deg]">
|
||||
<div class="tape absolute -top-4 right-4 w-20 h-6 -rotate-6"></div>
|
||||
<div class="relative border-2 border-dashed border-black dark:border-white mb-4 h-40 bg-white dark:bg-black flex items-center justify-center">
|
||||
<svg class="w-16 h-16 text-black dark:text-white" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24">
|
||||
<rect height="10" rx="2" width="18" x="3" y="11"></rect>
|
||||
<circle cx="12" cy="5" r="2"></circle>
|
||||
<path d="M12 7v4"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="font-display font-bold text-xl leading-none mb-2 uppercase">Imitation Game</h3>
|
||||
<p class="text-xs leading-snug opacity-80 line-clamp-4">Turing's question: "Can machines think?" The philosophical start of it all.</p>
|
||||
<div class="absolute bottom-4 right-4 text-[10px] font-bold bg-black text-white px-2">FIG 0.1</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<div class="mt-40 max-w-3xl mx-auto px-4">
|
||||
<div class="bg-primary border-4 border-black p-8 relative shadow-[12px_12px_0px_0px_#000] dark:shadow-[12px_12px_0px_0px_#fff]">
|
||||
<div class="absolute -top-10 -right-6 w-20 h-20 bg-white dark:bg-gray-800 border-4 border-black flex items-center justify-center rounded-full animate-bounce">
|
||||
<span class="material-icons-round text-4xl text-black dark:text-white">mail</span>
|
||||
</div>
|
||||
<h2 class="font-display font-black text-3xl md:text-5xl mb-4 text-black uppercase tracking-tight">Join the Park</h2>
|
||||
<p class="font-mono text-black mb-8 text-base font-bold">
|
||||
Subscribe to the Agent Park weekly zine. No spam, just ducks and data.
|
||||
</p>
|
||||
<form class="flex flex-col md:flex-row gap-4">
|
||||
<input class="flex-1 bg-white border-4 border-black px-6 py-4 font-mono focus:ring-0 focus:border-black focus:shadow-[4px_4px_0px_0px_#000] transition-all placeholder:text-gray-500 text-black text-lg" placeholder="Your email here..." type="email"/>
|
||||
<button class="bg-black text-white px-10 py-4 font-black border-4 border-transparent hover:bg-white hover:text-black hover:border-black transition-all hover:shadow-[6px_6px_0px_0px_#000] uppercase text-lg" type="button">
|
||||
SUBSCRIBE
|
||||
</button>
|
||||
</form>
|
||||
<div class="mt-6 flex items-center gap-3">
|
||||
<input class="w-6 h-6 border-4 border-black text-black focus:ring-0 rounded-none bg-white checked:bg-black" id="check" type="checkbox"/>
|
||||
<label class="text-sm font-black text-black uppercase" for="check">I agree to be cool.</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed bottom-6 right-6 z-50">
|
||||
<div class="bg-white dark:bg-black border-4 border-black dark:border-white p-3 shadow-hard dark:shadow-hard-dark cursor-pointer hover:-translate-y-2 transition-transform">
|
||||
<span class="material-icons-round text-3xl text-black dark:text-white">arrow_upward</span>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="bg-black dark:bg-white text-white dark:text-black py-16 mt-20 border-t-8 border-primary">
|
||||
<div class="max-w-7xl mx-auto px-6 flex flex-col md:flex-row justify-between items-center gap-12">
|
||||
<div class="text-center md:text-left">
|
||||
<h4 class="font-display font-black text-4xl uppercase tracking-tighter">Agent Park</h4>
|
||||
<p class="font-mono text-sm opacity-60 mt-3">© 2025 Synthetic History Project — Zigzagged and Zined.</p>
|
||||
</div>
|
||||
<div class="flex gap-10">
|
||||
<a class="font-black text-xl hover:text-primary dark:hover:text-primary transition-colors underline decoration-4 underline-offset-8" href="#">Twitter</a>
|
||||
<a class="font-black text-xl hover:text-primary dark:hover:text-primary transition-colors underline decoration-4 underline-offset-8" href="#">GitHub</a>
|
||||
<a class="font-black text-xl hover:text-primary dark:hover:text-primary transition-colors underline decoration-4 underline-offset-8" href="#">Discord</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body></html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,716 @@
|
||||
# 季度 AI 热点词云系统设计文档
|
||||
|
||||
**创建日期**: 2026-01-25
|
||||
**功能类型**: 数据驱动可视化
|
||||
**技术栈**: n8n + Next.js + PostgreSQL + Prisma
|
||||
|
||||
---
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
季度 AI 热点词云是一个**自动化数据驱动的可视化词云系统**,通过 n8n 工作流从 Google Trends 采集 AI 相关热点词汇,经 AI 清洗和规则引擎处理后,自动入库并在前端展示。
|
||||
|
||||
### 核心目标
|
||||
|
||||
1. **内容营销**: 吸引访客回访查看每季度更新,提供社交分享素材
|
||||
2. **教育参考**: 帮助新手理解 AI 技术演进历程
|
||||
3. **数据洞察**: 展示 AI 领域热点变化趋势
|
||||
|
||||
### 用户旅程
|
||||
|
||||
1. 用户访问 `/keyword-cloud` 页面
|
||||
2. 看到当前季度的 AI 热点词云(如 2024-Q1)
|
||||
3. 鼠标悬停在词汇上,查看详细描述和要点
|
||||
4. 点击左右箭头切换不同季度,浏览历史热点
|
||||
5. 可视化展示:词汇大小代表搜索热度,颜色代表分类
|
||||
|
||||
---
|
||||
|
||||
## 二、系统架构
|
||||
|
||||
### 架构图
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
|
||||
│ Google │ │ n8n │ │ PostgreSQL │
|
||||
│ Trends API │───▶│ Workflow │───▶│ Database │
|
||||
└─────────────┘ └─────────────┘ └──────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────┐
|
||||
│ Next.js │
|
||||
│ Frontend │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
### 数据流向
|
||||
|
||||
1. **定时触发**: n8n Schedule 每季度末自动执行
|
||||
2. **数据采集**: Google Trends API 获取热门搜索词
|
||||
3. **AI 清洗**: 过滤无关词汇,生成描述和要点
|
||||
4. **规则匹配**: 根据热度分数分配视觉样式
|
||||
5. **数据入库**: 写入 PostgreSQL 数据库
|
||||
6. **前端展示**: Next.js 从数据库读取并渲染词云
|
||||
|
||||
---
|
||||
|
||||
## 三、数据库模型
|
||||
|
||||
### 3.1 Quarter 表(季度元数据)
|
||||
|
||||
```prisma
|
||||
model Quarter {
|
||||
id Int @id @default(autoincrement())
|
||||
quarter String @unique // "2023-Q1", "2023-Q2"
|
||||
title String @db.Text // "2023年第一季度"
|
||||
titleEn String? @db.Text // "Q1 2023"
|
||||
subtitle String? @db.Text // "聊天界面的黎明"
|
||||
subtitleEn String? @db.Text // "The dawn of chat interface"
|
||||
displayOrder Int @default(0) // 前端排序
|
||||
isActive Boolean @default(true) // 是否显示
|
||||
keywords Keyword[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([quarter])
|
||||
@@index([displayOrder])
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Keyword 表(关键词核心数据)
|
||||
|
||||
```prisma
|
||||
model Keyword {
|
||||
id Int @id @default(autoincrement())
|
||||
word String // "ChatGPT"
|
||||
trendScore Int // 0-100, 从 Google Trends 获取
|
||||
|
||||
// 外键关联
|
||||
quarterId Int
|
||||
quarter Quarter @relation(fields: [quarterId], references: [id], onDelete: Cascade)
|
||||
|
||||
// 内容字段(支持中英双语)
|
||||
description String @db.Text // AI 生成的一句话描述
|
||||
descriptionEn String? @db.Text // 英文描述
|
||||
detailPoints Json // JSON 数组: ["要点1", "要点2", "要点3"]
|
||||
detailPointsEn Json? // 英文版要点
|
||||
|
||||
// 视觉样式配置
|
||||
visualConfig Json // {color, size, rotation, border}
|
||||
|
||||
// 元数据
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([quarterId])
|
||||
@@index([trendScore])
|
||||
@@index([word])
|
||||
}
|
||||
```
|
||||
|
||||
**visualConfig 字段结构示例**:
|
||||
```json
|
||||
{
|
||||
"color": "secondary",
|
||||
"size": "text-5xl",
|
||||
"rotation": "rotate-1",
|
||||
"border": "border-4"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 VisualStyleRule 表(视觉样式规则配置)
|
||||
|
||||
```prisma
|
||||
model VisualStyleRule {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique // "热门大词-金色"
|
||||
|
||||
// 分数区间
|
||||
minScore Int // 90
|
||||
maxScore Int // 100
|
||||
|
||||
// 视觉属性
|
||||
color String // "primary", "secondary", "accent"
|
||||
size String // "text-5xl", "text-3xl", "text-xl"
|
||||
border String // "border-4", "border-2"
|
||||
rotation String? // "rotate-1", "rotate-2", null
|
||||
|
||||
// 控制
|
||||
priority Int @default(0) // 优先级,分数重叠时按优先级
|
||||
enabled Boolean @default(true) // 是否启用
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([enabled])
|
||||
@@index([minScore, maxScore])
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 KeywordCloudErrorLog 表(错误日志)
|
||||
|
||||
```prisma
|
||||
model KeywordCloudErrorLog {
|
||||
id Int @id @default(autoincrement())
|
||||
quarter String // "2023-Q1"
|
||||
keyword String? // "ChatGPT"
|
||||
errorType String // "INVALID_DATA", "API_ERROR", "DB_ERROR"
|
||||
errorMessage String @db.Text // 详细错误信息
|
||||
rawData Json? // 原始数据便于调试
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([quarter])
|
||||
@@index([errorType])
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、n8n 工作流设计
|
||||
|
||||
### 4.1 工作流概览
|
||||
|
||||
5 个核心节点实现从数据采集到入库的完整流程。
|
||||
|
||||
### 4.2 节点详细配置
|
||||
|
||||
#### 节点 1: Schedule Trigger(定时触发)
|
||||
|
||||
- **类型**: `n8n-nodes-base.scheduleTrigger`
|
||||
- **Cron 表达式**: `0 0 23 28-31 * *` (每季度末最后一天的 23:00)
|
||||
- **月份判断**: Function 节点检查当前月份(3/6/9/12),如果不是则跳过
|
||||
- **输出**: 当前季度的标识(如 "2024-Q1")
|
||||
|
||||
#### 节点 2: Google Trends 采集
|
||||
|
||||
- **类型**: `@gamal.dev/n8n-nodes-google-trends`
|
||||
- **配置参数**:
|
||||
- `keywords`: ["AI", "artificial intelligence", "machine learning", "GPT", "LLM"]
|
||||
- `timeRange`: 当前季度的 3 个月(如 2024-01-01 to 2024-03-31)
|
||||
- `category`: "Science > Computer Science > AI"
|
||||
- `geo`: "GB"
|
||||
- **输出示例**:
|
||||
```json
|
||||
{
|
||||
"keyword": "ChatGPT",
|
||||
"trendScore": 95,
|
||||
"rising": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 节点 3: AI 清洗和内容生成
|
||||
|
||||
- **类型**: `@n8n/n8n-nodes-langchain.lmChatChain`
|
||||
- **Prompt 模板**:
|
||||
```
|
||||
你是一个 AI 领域专家。以下是 Google Trends 采集的热门关键词列表:
|
||||
{{ $json.all() }}
|
||||
|
||||
任务:
|
||||
1. 过滤掉与 AI/机器学习无关的关键词
|
||||
2. 为每个关键词生成中文描述(10-50字)
|
||||
3. 生成 3 条详细要点(每条 10-30 字,客观描述,避免营销用语)
|
||||
|
||||
输出格式(JSON 数组):
|
||||
[
|
||||
{
|
||||
"word": "ChatGPT",
|
||||
"trendScore": 95,
|
||||
"description": "OpenAI 开发的对话式人工智能助手",
|
||||
"detailPoints": ["支持多轮对话", "基于 GPT-3.5 架构", "2023年用户突破1亿"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### 节点 4: 规则引擎匹配
|
||||
|
||||
- **类型**: `n8n-nodes-base.code`
|
||||
- **逻辑**:
|
||||
1. HTTP Request 获取 `VisualStyleRule` 表数据
|
||||
- 方法: GET
|
||||
- URL: `{{ $env.API_URL }}/api/keyword-cloud/rules`
|
||||
2. 按 `priority` 排序规则
|
||||
3. 遍历每个关键词,匹配第一个符合的规则(`minScore <= trendScore <= maxScore`)
|
||||
4. 将视觉配置注入数据
|
||||
|
||||
#### 节点 5: 批量写入数据库
|
||||
|
||||
- **类型**: `n8n-nodes-base.httpRequest`
|
||||
- **方法**: POST
|
||||
- **URL**: `{{ $env.API_URL }}/api/keyword-cloud/keywords`
|
||||
- **认证**: Bearer Token(环境变量 `API_KEY`)
|
||||
- **Body**:
|
||||
```json
|
||||
{
|
||||
"quarter": "2024-Q1",
|
||||
"keywords": [
|
||||
{
|
||||
"word": "ChatGPT",
|
||||
"trendScore": 95,
|
||||
"description": "...",
|
||||
"detailPoints": ["...", "...", "..."],
|
||||
"visualConfig": {...}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
- **批量处理**: 超过 20 个关键词时分批提交
|
||||
|
||||
### 4.3 错误处理
|
||||
|
||||
- 每个节点设置 `continueOnFail: true`
|
||||
- 错误日志写入 `KeywordCloudErrorLog` 表
|
||||
- 关键错误发送通知(Email/Slack)
|
||||
|
||||
---
|
||||
|
||||
## 五、API 端点设计
|
||||
|
||||
### 5.1 GET /api/keyword-cloud/quarters
|
||||
|
||||
获取季度列表。
|
||||
|
||||
**查询参数**:
|
||||
- `isActive` (可选): 只返回激活的季度
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"quarters": [
|
||||
{
|
||||
"id": 1,
|
||||
"quarter": "2024-Q1",
|
||||
"title": "2024年第一季度",
|
||||
"titleEn": "Q1 2024",
|
||||
"subtitle": "聊天界面的黎明",
|
||||
"subtitleEn": "The dawn of chat interface",
|
||||
"displayOrder": 0,
|
||||
"keywordCount": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**排序**: 按 `displayOrder` ASC
|
||||
|
||||
### 5.2 GET /api/keyword-cloud/keywords/[quarter]
|
||||
|
||||
获取指定季度的关键词列表。
|
||||
|
||||
**路径参数**:
|
||||
- `quarter`: 季度标识(如 "2024-Q1")
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"quarter": "2024-Q1",
|
||||
"title": "2024年第一季度",
|
||||
"keywords": [
|
||||
{
|
||||
"id": 1,
|
||||
"word": "ChatGPT",
|
||||
"trendScore": 95,
|
||||
"description": "OpenAI 开发的对话式 AI 助手",
|
||||
"detailPoints": ["支持多轮对话", "基于 GPT-3.5", "2023用户破亿"],
|
||||
"visualConfig": {
|
||||
"color": "secondary",
|
||||
"size": "text-5xl",
|
||||
"border": "border-4",
|
||||
"rotation": "rotate-1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**排序**: 按 `trendScore` DESC
|
||||
|
||||
### 5.3 POST /api/keyword-cloud/keywords
|
||||
|
||||
n8n 工作流写入关键词数据。
|
||||
|
||||
**认证**: Bearer Token (WEBHOOK_API_KEY)
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"quarter": "2024-Q1",
|
||||
"keywords": [
|
||||
{
|
||||
"word": "ChatGPT",
|
||||
"trendScore": 95,
|
||||
"description": "...",
|
||||
"detailPoints": ["...", "...", "..."],
|
||||
"visualConfig": {...}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"created": 15,
|
||||
"failed": 2,
|
||||
"errors": [
|
||||
{ "word": "Invalid", "error": "trendScore out of range" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**逻辑**:
|
||||
1. 验证 API Key
|
||||
2. 查找或创建 `Quarter` 记录
|
||||
3. 批量创建 `Keyword` 记录(Prisma `createMany`)
|
||||
4. 失败记录写入 `KeywordCloudErrorLog` 表
|
||||
5. 返回成功/失败统计
|
||||
|
||||
### 5.4 GET /api/keyword-cloud/rules
|
||||
|
||||
获取视觉样式规则配置(n8n 规则引擎使用)。
|
||||
|
||||
**查询参数**:
|
||||
- `enabled` (可选): 只返回启用的规则
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "热门大词-金色",
|
||||
"minScore": 90,
|
||||
"maxScore": 100,
|
||||
"visualConfig": {
|
||||
"color": "primary",
|
||||
"size": "text-5xl",
|
||||
"border": "border-4",
|
||||
"rotation": "rotate-1"
|
||||
},
|
||||
"priority": 0,
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**排序**: 按 `priority` ASC
|
||||
|
||||
### 5.5 POST /api/keyword-cloud/rules
|
||||
|
||||
创建新的视觉样式规则(管理员功能)。
|
||||
|
||||
**请求体**: 同单个规则对象
|
||||
|
||||
**验证**:
|
||||
- `minScore < maxScore`
|
||||
- 必填字段检查
|
||||
- 颜色值必须是预定义的颜色类别
|
||||
|
||||
---
|
||||
|
||||
## 六、前端组件设计
|
||||
|
||||
### 6.1 路由结构
|
||||
|
||||
```
|
||||
src/app/[locale]/keyword-cloud/
|
||||
├── page.tsx # 主页面
|
||||
└── components/
|
||||
├── KeywordCloud.tsx # 词云容器组件
|
||||
├── CloudWord.tsx # 单个词汇组件
|
||||
├── QuarterNavigator.tsx # 季度切换导航
|
||||
├── WordPopover.tsx # 弹出框详情
|
||||
└── ProgressIndicator.tsx # 进度条
|
||||
```
|
||||
|
||||
### 6.2 核心组件
|
||||
|
||||
#### KeywordCloud.tsx
|
||||
|
||||
词云容器组件,负责数据获取和布局。
|
||||
|
||||
```typescript
|
||||
interface KeywordCloudProps {
|
||||
quarter: string;
|
||||
}
|
||||
|
||||
function KeywordCloud({ quarter }: KeywordCloudProps) {
|
||||
const { data, isLoading } = useKeywordData(quarter);
|
||||
|
||||
return (
|
||||
<div className="bg-white/50 dark:bg-black/20 backdrop-blur-sm border-4 border-black p-8 md:p-12 shadow-hard">
|
||||
<ProgressIndicator currentQuarter={quarter} totalQuarters={4} />
|
||||
<QuarterNavigator current={quarter} />
|
||||
<div className="word-cluster py-12">
|
||||
{data?.keywords.map((keyword) => (
|
||||
<CloudWord key={keyword.id} data={keyword} />
|
||||
))}
|
||||
</div>
|
||||
<FunFactBubble fact={data.funFact} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### CloudWord.tsx
|
||||
|
||||
单个词汇组件,应用视觉样式和悬停交互。
|
||||
|
||||
```typescript
|
||||
interface CloudWordProps {
|
||||
data: Keyword;
|
||||
}
|
||||
|
||||
function CloudWord({ data }: CloudWordProps) {
|
||||
const { word, visualConfig, description, detailPoints } = data;
|
||||
const { color, size, border, rotation } = visualConfig;
|
||||
const colorClass = colorMap[color];
|
||||
|
||||
return (
|
||||
<span className={cn(
|
||||
"cloud-word",
|
||||
border,
|
||||
"border-black",
|
||||
colorClass,
|
||||
"px-6 py-3",
|
||||
"rounded-full",
|
||||
size,
|
||||
"font-black",
|
||||
"shadow-hard",
|
||||
rotation,
|
||||
"transition-all",
|
||||
"hover:scale-105",
|
||||
"cursor-pointer"
|
||||
)}>
|
||||
{word}
|
||||
<WordPopover title={word} description={description} points={detailPoints} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### WordPopover.tsx
|
||||
|
||||
弹出框组件,显示词汇的详细信息。
|
||||
|
||||
```typescript
|
||||
interface WordPopoverProps {
|
||||
title: string;
|
||||
description: string;
|
||||
points: string[];
|
||||
}
|
||||
|
||||
function WordPopover({ title, description, points }: WordPopoverProps) {
|
||||
return (
|
||||
<div className="popover">
|
||||
<div className="bg-primary text-black font-display font-bold p-2 border-b-2 border-black text-sm uppercase">
|
||||
{title}
|
||||
</div>
|
||||
<div className="p-3 space-y-2 text-xs font-medium dark:text-gray-100">
|
||||
<div className="flex gap-2 items-start">
|
||||
<span>•</span>
|
||||
<span>{description}</span>
|
||||
</div>
|
||||
{points.map((point, i) => (
|
||||
<div key={i} className="flex gap-2 items-start">
|
||||
<span>•</span>
|
||||
<span>{point}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### QuarterNavigator.tsx
|
||||
|
||||
季度切换导航组件。
|
||||
|
||||
```typescript
|
||||
function QuarterNavigator({ current }: { current: string }) {
|
||||
const quarters = ["2023-Q1", "2023-Q2", "2023-Q3", "2023-Q4"];
|
||||
const currentIndex = quarters.indexOf(current);
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-8">
|
||||
<button
|
||||
disabled={currentIndex === 0}
|
||||
className="nav-button"
|
||||
onClick={() => navigate(quarters[currentIndex - 1])}
|
||||
>
|
||||
<span className="material-symbols-outlined text-4xl">chevron_left</span>
|
||||
</button>
|
||||
|
||||
<div className="text-center">
|
||||
<div className="bg-primary border-4 border-black px-10 py-4 shadow-hard font-display font-bold text-5xl">
|
||||
{current}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
disabled={currentIndex === quarters.length - 1}
|
||||
className="nav-button"
|
||||
onClick={() => navigate(quarters[currentIndex + 1])}
|
||||
>
|
||||
<span className="material-symbols-outlined text-4xl">chevron_right</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 数据获取
|
||||
|
||||
```typescript
|
||||
// src/hooks/useKeywordCloud.ts
|
||||
export async function getKeywordData(quarter: string) {
|
||||
const response = await fetch(`${API_URL}/api/keyword-cloud/keywords/${quarter}`);
|
||||
return response.json();
|
||||
}
|
||||
```
|
||||
|
||||
### 6.4 样式系统
|
||||
|
||||
复用项目现有的 Tailwind 配置和样式类:
|
||||
- `.cloud-word`: 词云词汇的基础样式
|
||||
- `.popover`: 弹出框样式(包括箭头)
|
||||
- `.word-cluster`: 词汇容器布局
|
||||
- `.nav-button`: 导航按钮样式
|
||||
|
||||
响应式断点:`md:`, `lg:`
|
||||
|
||||
---
|
||||
|
||||
## 七、错误处理和监控
|
||||
|
||||
### 7.1 分层错误处理
|
||||
|
||||
**n8n 工作流层**:
|
||||
- 每个节点 `continueOnFail: true`
|
||||
- 失败记录写入 `KeywordCloudErrorLog` 表
|
||||
- 关键错误发送通知
|
||||
|
||||
**API 层**:
|
||||
- Zod schema 验证
|
||||
- 部分成功响应模式
|
||||
- HTTP 状态码规范
|
||||
|
||||
**前端层**:
|
||||
- 友好的错误提示
|
||||
- Error Boundary
|
||||
- 重试机制
|
||||
|
||||
### 7.2 监控策略
|
||||
|
||||
- n8n 执行日志监控
|
||||
- 定期检查 `KeywordCloudErrorLog` 表
|
||||
- API 响应时间监控
|
||||
- 前端错误追踪
|
||||
|
||||
---
|
||||
|
||||
## 八、测试策略
|
||||
|
||||
### 8.1 单元测试(Vitest)
|
||||
|
||||
- API 路由处理逻辑
|
||||
- 规则引擎匹配算法
|
||||
- 数据验证 schemas
|
||||
|
||||
### 8.2 E2E 测试
|
||||
|
||||
- 季度切换功能
|
||||
- 弹出框交互
|
||||
- 响应式布局
|
||||
|
||||
### 8.3 n8n 工作流测试
|
||||
|
||||
- 使用测试环境 API 手动触发
|
||||
- 验证生成的数据质量
|
||||
- 检查规则匹配结果
|
||||
|
||||
---
|
||||
|
||||
## 九、部署指南
|
||||
|
||||
### 9.1 环境变量
|
||||
|
||||
```bash
|
||||
# .env.local
|
||||
DATABASE_URL="..."
|
||||
WEBHOOK_API_KEY="..."
|
||||
N8N_WEBHOOK_URL="https://your-n8n-instance.com/..."
|
||||
```
|
||||
|
||||
### 9.2 数据库迁移
|
||||
|
||||
```bash
|
||||
pnpm prisma migrate dev --name add_keyword_cloud_tables
|
||||
```
|
||||
|
||||
### 9.3 n8n 部署
|
||||
|
||||
1. 使用自托管 n8n 或 n8n Cloud
|
||||
2. 配置环境变量(API_URL, API_KEY)
|
||||
3. 设置 Cron 定时任务
|
||||
4. 测试工作流执行
|
||||
|
||||
### 9.4 初始化数据
|
||||
|
||||
1. 创建第一个 `Quarter` 记录(2023-Q1)
|
||||
2. 配置 3-5 条 `VisualStyleRule`:
|
||||
- 90-100: 热门大词(金色, text-5xl, border-4)
|
||||
- 70-89: 中等词汇(蓝色, text-3xl, border-2)
|
||||
- 50-69: 小词汇(紫色, text-xl, border-2)
|
||||
- 0-49: 长尾词(灰色, text-base, border-2)
|
||||
|
||||
### 9.5 监控设置
|
||||
|
||||
- n8n 执行日志告警
|
||||
- 错误日志定期检查
|
||||
- API 性能监控
|
||||
|
||||
---
|
||||
|
||||
## 十、未来扩展
|
||||
|
||||
1. **预测功能**: 基于历史数据预测下一个热点词汇
|
||||
2. **趋势分析**: 展示词汇热度的季度变化曲线
|
||||
3. **用户贡献**: 允许用户提交词汇建议
|
||||
4. **多维度**: 按技术栈、应用领域等维度分类
|
||||
5. **导出功能**: 导出季度报告(PDF/图片)
|
||||
|
||||
---
|
||||
|
||||
## 附录
|
||||
|
||||
### A. 颜色系统
|
||||
|
||||
```typescript
|
||||
const colorMap = {
|
||||
primary: "bg-primary", // Gold (#FFD700)
|
||||
secondary: "bg-secondary", // Blue (#7FB5FF)
|
||||
accent: "bg-accent", // Purple (#C39BD3)
|
||||
gray: "bg-gray-100", // Gray
|
||||
};
|
||||
```
|
||||
|
||||
### B. 字体大小映射
|
||||
|
||||
```typescript
|
||||
const sizeMap = {
|
||||
hot: "text-5xl", // 90-100 分
|
||||
medium: "text-3xl", // 70-89 分
|
||||
small: "text-xl", // 50-69 分
|
||||
tiny: "text-base", // 0-49 分
|
||||
};
|
||||
```
|
||||
|
||||
### C. 参考资源
|
||||
|
||||
- Google Trends API: https://trends.google.com/
|
||||
- n8n 文档: https://docs.n8n.io/
|
||||
- Tailwind CSS: https://tailwindcss.com/
|
||||
Reference in New Issue
Block a user