Vibe-Trading Wiki 静态站点架构与 AI-Agent 流量分析实战指南
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
本篇技术指南围绕 Vibe-Trading 官方文档站点(vibetrading.wiki)的静态源码仓库展开,系统讲解 Wiki 的本地预览方式、Cloudflare Pages 部署配置,以及内置的匿名 AI-Agent / 爬虫 / 人类流量分类统计层(Pages Functions + D1)。读完本文,你将掌握如何在无构建步骤的纯静态站点上叠加"请求路径级"的服务端分析,理解 User-Agent 分类正则、D1 聚合与降级缓存的完整实现细节,并能直接复用到自己的文档站或内容站中。
一、文档定位:Wiki 静态源码与站点结构
wiki/README.md是整个vibetrading.wiki站点的构建与运维说明文档,其核心信息可归纳为三点:
- 站点性质:纯静态站点,无需任何构建步骤("The site is static and needs no build step");
- 唯一的动态部分:位于
functions/下的 Cloudflare Pages Functions 分析层,用于按 User-Agent 分类并统计站点访问流量; - 隐私姿态:统计为匿名、第一方、仅聚合("no cookies, no per-visitor identifier, no IP retention")。
Wiki 站点本身承载了 Vibe-Trading 项目的全部对外内容体系。仓库根目录下的wiki/目录结构如下:
wiki/ ├── README.md # 本文档:构建、预览、部署与分析层说明 ├── index.html # 根入口:立即跳转到 /home/ ├── _redirects # Cloudflare Pages 路由重写规则 ├── _headers # 全局安全响应头与缓存策略 ├── wrangler.toml # Pages Functions + D1 本地配置 ├── main.js # 页脚流量统计、GitHub Star、主题等前端逻辑 ├── styles.css / theme.js / theme-init.js ├── functions/ # 唯一的动态部分(Pages Functions) │ ├── _middleware.js # 请求路径级 AI-Agent 分类计数器 │ └── api/stats.js # 页脚聚合统计 API(含 PyPI 降级缓存) ├── home/ # 落地页 ├── docs/ # 产品文档(SPA:content.js + index.html) ├── tutorials/ # 上手教程 ├── alpha-library/ # Alpha 因子库 ├── research-lab/ # 研究实验室 ├── locales/en.json # i18n 文案 └── assets/ # 图标与特性配图二、本地预览:零依赖 HTTP 服务与路径重写差异
wiki/README.md给出了最简单直接的本地预览方式——利用 Python 标准库自带的 HTTP 服务器:
cd wiki python3 -m http.server 8088随后打开以下地址即可访问各内容分区:
http://localhost:8088/home/—— 落地页http://localhost:8088/docs/—— 产品文档http://localhost:8088/tutorials/—— 上手教程http://localhost:8088/alpha-library/—— Alpha 库http://localhost:8088/research-lab/—— 研究实验室
这里有一个非常关键的实操注意事项:生产环境中的"美观短链"式文档地址(如/docs/latest/getting-started/vibe-trading-overview)是由 Cloudflare Pages 通过 wiki/_redirects 的重写规则处理的;而python3 -m http.server这类朴素静态服务器不会应用任何重写规则。因此本地调试时必须以/docs/作为文档入口,而不是直接访问/docs/latest/...这类深链,否则会得到 404。
阅读 wiki/_redirects 的完整规则,可以看到生产环境的完整路由设计:
/ /home/ 302 /docs /docs/latest/getting-started/vibe-trading-overview 302 /docs/ /docs/latest/getting-started/vibe-trading-overview 302 /tutorials /tutorials/ 302 /alpha /alpha-library/ 302 /alpha-library /alpha-library/ 302 /research-lab /research-lab/ 302 /docs/latest/* /docs/ 200 /docs/0.1.7/* /docs/ 200值得注意的细节:/docs/latest/*与/docs/0.1.7/*使用200 状态码(rewrite,重写而非重定向),把文档深链统一映射到docs/下的 SPA 入口(由 wiki/docs/index.html 配合content.js渲染),其余短链均为 302 跳转。这种"短链 302 + 深链 200 rewrite"的组合,既保证了旧地址可访问,又避免了版本化文档链接的重复抓取问题。此外,仓库根目录的 wiki/index.html 还通过<meta http-equiv="refresh">与location.replace("/home/")双重机制把根路径引导到/home/落地页,并声明了 canonical 地址。
三、Cloudflare Pages 部署配置
wiki/README.md给出了生产部署的最小配置清单:
- 项目根目录:
wiki - 构建命令:留空(纯静态,无需构建)
- 输出目录:
.(即wiki目录本身) - 自定义域名:
vibetrading.wiki
由于站点是纯静态文件,不需要任何框架打包流程,index.html、main.js、styles.css等文件直接作为产物发布。这一点在 wiki/wrangler.toml 中也有对应体现:
name = "vibetrading-wiki" compatibility_date = "2026-01-01" pages_build_output_dir = "." [[d1_databases]] binding = "DB" database_name = "vibetrading-analytics" database_id = "3c1eca42-91e1-45e9-adcf-400559ba1b99"wrangler.toml的注释明确说明了两件事:其一,D1 生产绑定(binding 名DB、数据库vibetrading-analytics)也在项目级配置中设置,以便覆盖 CI 部署;其二,该文件可以直接用于在本地跑cd wiki && wrangler pages dev或wrangler pages deploy,从而在部署/预览时一并接通分析层。
四、核心动态部分:请求路径级 AI-Agent 流量分类器
wiki/README.md用一个自然段概括了分析层的设计:
唯一的动态部分是
functions/中一个很小的分析层:_middleware.js按 User-Agent 把每个页面请求分类为 AI-agent / bot / human,并计数写入 D1 数据库(vibetrading-analytics,绑定DB);api/stats.js负责向页脚提供聚合计数,并附带公开的 PyPI 与 GitHub 数字。计数器匿名且第一方,无 cookie、无逐访问者标识、无 IP 留存。
4.1 为什么放在请求路径而不是页面 JS 里
wiki/functions/_middleware.js 文件头注释揭示了设计动机:分类器在**请求路径中(in-path)**运行,而非依赖页面 JavaScript。这意味着即使 AI 爬虫(如 GPTBot、ClaudeBot)根本不执行 JS,也会被计入统计。这是与服务端计数相对"前端埋点"的本质差异,也是该设计最核心的技术取舍。
4.2 双层正则分类器
分类的核心逻辑定义在两个正则集合上。AI-Agent 集合(wiki/functions/_middleware.js)同时覆盖了两类来源:
- 主流 AI 服务爬虫:
GPTBot、ChatGPT-User、OAI-SearchBot、ClaudeBot、Claude-User、PerplexityBot、Google-Extended、Bytespider、CCBot、cohere-ai、Meta-ExternalAgent、Amazonbot、Applebot-Extended、YouBot、MistralAI等; - 常见编程 HTTP 客户端:
python-requests、aiohttp、\bhttpx\b、Go-http-client、node-fetch、axios、okhttp、Scrapy、\bcurl\b、Wget、HeadlessChrome、Playwright、Puppeteer、Selenium等。
把无头浏览器与通用编程客户端也归入 "agent" 类别,是因为它们同样可能是 Agent 工具链的抓取载体。泛化爬虫则归入独立的 GENERIC_BOT 集合(wiki/functions/_middleware.js):Googlebot、bingbot、YandexBot、Baiduspider、AhrefsBot、SemrushBot、UptimeRobot、Twitterbot、Slackbot、TelegramBot,以及通用的\bbot\b、\bcrawler\b、\bspider\b、\bslurp\b词边界匹配。
最终判定函数classify(wiki/functions/_middleware.js)遵循严格优先级:
function classify(ua) { if (!ua) return "bot"; // a real browser always sends a User-Agent if (AI_AGENT.test(ua)) return "agent"; if (GENERIC_BOT.test(ua)) return "bot"; return "human"; }三个可读性极佳的边界设定:无 User-Agent 的请求一律视为 bot(真实浏览器总是携带 UA);AI-Agent 优先级高于泛化爬虫;其余请求全部视为 human。整个正则均以"i"标志忽略大小写匹配。
4.3 页面浏览判定与 D1 计数
onRequest(wiki/functions/_middleware.js)负责在每个请求上执行计数逻辑。页面浏览(page view)需要同时满足三个条件:
const isPageView = request.method === "GET" && accept.includes("text/html") && !url.pathname.startsWith("/api/");即:GET 方法、Accept 头包含text/html(排除静态资源与 API 请求)、且路径不以/api/开头。满足条件且环境存在 D1 绑定(env.DB)时,执行按日聚合的upsert语句:
INSERT INTO visits (day, klass, n) VALUES (?1, ?2, 1) ON CONFLICT(day, klass) DO UPDATE SET n = n + 1其中day取 UTC 日期的YYYY-MM-DD(new Date().toISOString().slice(0, 10)),klass即 agent / bot / human 三者之一。整条语句用context.waitUntil(...)包裹,确保计数在响应返回后仍能完成,不阻塞页面交付。
两个值得借鉴的工程细节:
- Bulletproof by construction(构造级健壮):整个计数逻辑包在
try/catch中,且任何失败都直接落到return next(),计数失败永远不会影响页面服务; - 异常全量吞掉:D1 写入失败使用
.catch(() => {})静默处理,符合"分析必须透明无感"的定位。
4.4 数据模型推论
结合_middleware.js的INSERT ... ON CONFLICT(day, klass)与stats.js的GROUP BY klass查询,可以从源码结构推断 D1 中的visits表结构为:以(day, klass)为唯一键、每行三个字段(day文本、klass文本、n整数)的日聚合计数表。这也是 "three integers per day in D1" 注释的落点——全站每天最多三行数据(agent / bot / human 各一行),存储成本与隐私暴露面都被压缩到最小。
五、聚合统计 API:页脚数据的完整链路
5.1/api/stats响应结构
wiki/functions/api/stats.js 实现了GET /api/stats端点,返回结构如下:
return Response.json( { web, // { human, agent, bot } 全站累计页面浏览 pypi, // { last_day, last_week, last_month } 安装量 note: "anonymous · first-party · aggregate sample", generated_at: new Date().toISOString(), }, { headers }, );响应头包含Access-Control-Allow-Origin: *(允许任何来源的页脚读取)与Cache-Control: public, max-age=60(公共缓存 60 秒,缓解访问频率)。
web聚合来自对visits表的SELECT klass, SUM(n) AS total FROM visits GROUP BY klass查询,只有human/agent/bot三个合法键会被计入,未知分类被丢弃。
5.2 PyPI 安装量:last-good 降级缓存
getPypi(wiki/functions/api/stats.js)体现了"上游不稳定时的优雅降级"设计:
- 首先请求
pypistats.org公开 API 获取vibe-trading-ai包的近 1 天 / 1 周 / 1 月安装量; - 成功后把结果 JSON 化写入 D1 的
cache表(同样是ON CONFLICT(key) DO UPDATE的 upsert 语义); - 若上游失败或限流,则回退读取 D1 中上次成功的缓存值;
- 连缓存都没有时返回
null,页脚对应区块保持隐藏。
5.3 前端的克制:为什么 GitHub Star 不在这里取
stats.js文件头注释明确解释了设计决策:GitHub Star 数刻意不在服务端 API 中获取,而是由 wiki/main.js 的initStars()在客户端直接调用 GitHub API,并配合 localStorage 缓存(STARS_CACHE_KEY、12 小时 TTL)实现"先显示缓存、后台刷新"。这样避免了重复拉取与不必要的限流配额占用。
5.4 页脚渲染:数据未到前保持隐藏
页脚流量区块由 wiki/main.js 的initTraffic()渲染:请求/api/stats,成功后才写入 AI 访问数、人类访问数、月安装量三个数值,并显示区块;任何失败(网络异常或 API 不可用)都让区块保持hidden状态,绝不显示破折号占位。这种"无数据不展示"的策略与_middleware.js的"计数失败不影响页面"形成完整呼应——整条分析链路对站点内容的可用性零侵入。
六、隐私与信任姿态:按构造不可作恶
wiki/README.md最后一段明确承诺了隐私边界:计数器匿名且第一方(first-party),无 cookie、无逐访问者标识、无 IP 留存。
这在源码层面是严格兑现的:
- 分类依据仅为请求头中的
User-Agent字符串,不读取、不存储任何其他请求信息; - D1 中落库的最小数据单元就是
(day, klass, n)三个整数,不存在任何可关联单个访问者的维度; _headers中的Referrer-Policy: strict-origin-when-cross-origin进一步收紧了跨源信息暴露;- 由于不设置 cookie 标识,统计天然不构成跨页面用户画像,也规避了 GDPR 类通知义务的复杂度。
用文件头注释的原话概括:"Bulletproof by construction: every path is wrapped so a counting failure can never break page serving"—— 既有隐私的"最小化",又有可用性的"最大化"。
七、安全响应头与静态资源缓存策略
wiki/_headers 为全站配置了现代安全响应头与分层缓存:
/* X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(), geolocation=() /assets/* Cache-Control: public, max-age=31536000, immutable /*.js Cache-Control: public, max-age=3600 /*.css Cache-Control: public, max-age=3600要点解读:
X-Frame-Options: SAMEORIGIN防止被第三方页面 iframe 嵌入(点击劫持防护);X-Content-Type-Options: nosniff禁止浏览器 MIME 类型嗅探;Permissions-Policy显式禁用摄像头、麦克风、地理位置,对纯内容站是最小权限姿态;assets/目录资源带immutable(一年缓存),适合带内容哈希的图片与静态资源;JS/CSS 缓存 1 小时,兼顾更新及时性与带宽成本。
八、结语:文档站与产品的闭环
Vibe-Trading Wiki 是一个"小而完整"的静态站点工程范例:它用零构建成本的 HTML/CSS/JS 承载了产品文档(docs/)、上手教程(tutorials/)、Alpha 因子库(alpha-library/)与研究实验室(research-lab/)四大内容板块,用_redirects优雅处理了版本化文档深链,又用 100 行左右的 Pages Functions 实现了具备隐私意识的 AI-Agent 流量观测。对于希望度量"AI 正在如何消费我的文档"的内容维护者来说,wiki/functions/_middleware.js的分类器与 D1 日聚合模型是一个可直接移植的参考实现;而wiki/README.md则是理解这套架构的入口文档,配合上述源码文件即可完整复现本地预览、部署与统计的全流程。
【免费下载链接】Vibe-Trading"Vibe-Trading: Your Personal Trading Agent"项目地址: https://gitcode.com/GitHub_Trending/vi/Vibe-Trading
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考