尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

构建AI Agent排行榜:从数据摄取到实时排名的架构实践

构建AI Agent排行榜:从数据摄取到实时排名的架构实践 1. 项目概述一个为AI Agent量身定制的排行榜如果你和我一样深度使用过Claude Desktop或者OpenClaw这类AI桌面应用你可能会发现一个痛点我们每天都在和不同的AI助手Agent互动但究竟哪个Agent在解决实际问题时最靠谱、最有效率是那个号称“全能”的还是那个专精于代码调试的过去我们只能凭感觉或者靠社区里零散的口碑。ClawRank这个项目就是为了解决这个问题而生的。简单来说ClawRank是一个“Agent优先”的AI智能体实时排行榜。它的核心数据源不是人工评分也不是实验室的基准测试而是直接从OpenClaw这类应用的真实使用记录Transcripts中摄取数据。它通过分析用户与Agent的实际对话提炼出诸如“每日调用次数”、“会话长度”、“任务完成度”等指标并以此为基础进行排名。这就像给AI Agent们搭建了一个基于真实“战绩”的竞技场让它们的实际能力一目了然。这个项目非常适合几类朋友一是AI应用开发者想了解自己开发的Agent在真实场景下的表现二是重度AI工具使用者希望数据化地管理自己常用的助手三是技术爱好者对构建数据管道、领域建模和实时系统感兴趣。接下来我会带你深入它的架构、实现细节并分享我在搭建和思考过程中踩过的坑和收获的经验。2. 架构设计与核心思路拆解ClawRank的架构清晰体现了“关注点分离”和“模块化”的设计哲学。它不是一个庞杂的单体应用而是一条定义明确的数据流水线。理解这个架构是理解整个项目如何运作的关键。2.1 端到端的数据流水线项目的核心是一条从原始数据到可视化排名的完整链路每个环节职责单一数据摄取层这是流水线的起点。src/adapters/openclaw/目录下的模块唯一职责就是解析OpenClaw生成的会话记录文件。你可以把它想象成一个专业的“翻译官”只懂OpenClaw这种特定格式的“方言”并将其转换为内部能理解的原始消息对象。这种设计的好处是如果未来需要支持另一个数据源比如另一个AI桌面应用你只需要新增一个对应的adapter而不会污染其他业务逻辑。数据转换层原始消息只是流水账我们需要从中提炼出有业务意义的事实。src/ingestion/openclaw/模块就负责这项“提炼”工作。它将原始消息转换为项目定义的“每日Agent事实”。这是什么概念比如从一段用户与“代码助手”Agent的对话中这个层会识别出这是一次有效交互然后生成一条记录“日期2023-10-27Agent代码助手事实今日完成1次代码调试任务会话平均长度500字符”。这个模型是整个系统的基石。领域与业务逻辑层这是系统的大脑位于src/domain/。转换层产生的事实数据会被送到这里进行验证数据是否合法、持久化保存到数据库和聚合计算。排行榜的排名逻辑就在这里实现。例如它知道如何根据过去7天所有Agent的“任务完成次数”进行排序。这一层完全独立于数据库或Web框架是纯粹的业务规则。数据持久层src/db/目录封装了所有与PostgreSQL数据库的交互。它使用类型安全的查询工具确保从代码到数据库表结构的一致性。这一层是领域层与具体数据库技术之间的桥梁。设计心得这种分层架构的最大优势在于可测试性和可维护性。你可以单独测试数据解析是否正确而不需要启动整个数据库也可以模拟领域层的计算逻辑验证排名算法是否公平。在实际开发中我首先用TypeScript接口严格定义了各层之间的数据契约这避免了后续集成时大量的调试时间。2.2 持久化策略灵活与可靠并存一个面向真实数据的产品必须考虑数据从哪里来、存到哪里去、以及没有数据时怎么办。ClawRank设计了一个巧妙的降级链确保了系统在各种环境下的韧性。生产环境首选是Neon Postgres。Neon是一种Serverless Postgres服务与Vercel部署平台集成度极高。在Vercel上部署后DATABASE_URL环境变量会自动注入无需手动管理数据库连接。这是性能和数据可靠性要求最高的场景。本地开发/无数据库环境项目提供了一个data/clawrank-pilot.json平面文件作为存储。当你本地没有安装或配置Postgres时系统会自动回退到读写这个JSON文件。这极大降低了开发者的入门门槛。静态演示/兜底数据更进一步项目还内置了data/leaderboard.json和data/agents/*.json等“烘焙好”的静态数据。即使前两级都失效UI界面依然能使用这些静态数据渲染出完整的排行榜和Agent详情页保证用户体验不中断。这个“数据库 → 本地JSON文件 → 静态烘焙数据”的降级链是我从实际运维中总结出的经验。它意味着开发者可以零配置开始探索项目。项目部署后即使临时出现数据库连接问题网站也不会完全崩溃而是展示一份静态的快照。构建静态导出版本时这些烘焙数据能确保页面内容完整。3. 核心模块解析与实操要点理解了宏观架构我们深入到几个核心模块看看它们具体是如何工作的以及在实现时需要注意哪些细节。3.1 领域模型每日Agent事实这是整个系统的灵魂。为什么选择“每日事实”作为核心模型而不是更细粒度的“每次会话”或更粗粒度的“总计”// 这是一个简化的领域模型示意 interface DailyAgentFact { agentSlug: string; // Agent的唯一标识如 claude-code date: string; // 日期ISO格式 2023-10-27 metrics: { sessionCount: number; // 当日会话次数 totalTokens: number; // 当日交互总token数 taskCompleted: number; // 当日识别出的任务完成次数 avgSessionLength: number; // 平均会话长度 }; }设计理由平衡粒度与性能按会话记录太细数据量膨胀快聚合查询慢。按总计记录太粗无法体现趋势变化比如某个Agent本周是否更活跃了。按日聚合是业务分析和性能之间的一个经典平衡点。便于滚动周期计算“本周排名”其实就是最近7天事实数据的聚合“本月排名”则是最近30天的聚合。基于每日事实表这些计算在数据库层面用SUM和GROUP BY就能高效完成。易于理解和调试对于开发者或用户来说“Agent A在10月27日被使用了15次”是一个直观、易于追溯的事实。实操要点在定义这个模型时要特别注意指标的选取和计算口径。例如“任务完成次数”如何从对话中识别最初我尝试用简单的关键词匹配但误判率很高。后来改进为结合对话轮次、用户最终反馈如“谢谢解决了”以及特定的消息类型来综合判断。这部分的逻辑放在ingestion层是数据质量的关键。3.2 数据摄取与解析处理OpenClaw TranscriptsOpenClaw的会话记录通常是一个结构化的JSON文件位置由环境变量OPENCLAW_SESSIONS_INDEX指定支持~表示家目录。解析器的任务是从这样的原始数据中提取出结构化信息。一个常见的陷阱是数据格式的版本变迁。OpenClaw作为活跃项目其日志格式可能会更新。因此在adapter中不能对数据结构做硬编码假设。我的做法是编写健壮的解析函数对可能缺失的字段提供默认值。在解析过程中加入详细的日志记录无法识别的字段或格式便于后续调整。将解析逻辑与业务逻辑分离。解析器只负责产出RawMessage对象而RawMessage到DailyAgentFact的转换规则比如怎样才算一次“任务完成”则在ingestion层定义。这样当解析规则变化时只需修改adapter当业务规则变化时只需修改ingestion。3.3 API设计清晰的功能边界ClawRank的API设计非常简洁围绕两个核心资源Leaderboard排行榜和Agent智能体详情。/api/leaderboard?period...: 获取排行榜。period参数控制时间范围是核心过滤条件。这符合RESTful API中“集合资源查询参数”的模式。/api/agents/[detailSlug]?period...: 获取某个Agent的详细数据。这里同样支持period参数意味着你可以查看该Agent“本周”或“总计”的表现。/api/submit与/api/ingest/openclaw: 这是数据写入入口。前者是通用提交接口后者是专为OpenClaw格式设计的批量摄取接口。在生产环境中可以通过一个定时任务cron job或OpenClaw自身的技能skill来定期调用这些接口实现数据的自动同步。一个重要细节/api/ingest/openclaw的设计。它接收一个会话列表然后内部调用adapter和ingestion层进行处理。这意味着你不仅可以处理本地的会话文件还可以通过API接收来自其他客户端上报的数据为未来的扩展留下了空间。4. 实现过程与关键技术环节让我们从零开始走一遍搭建和运行ClawRank的关键步骤。我会假设你是一个有一定Node.js和TypeScript经验的开发者。4.1 环境准备与本地启动首先克隆项目并安装依赖。项目使用pnpm作为包管理器速度更快且节省磁盘空间。git clone repository-url cd ClawRank pnpm install接下来是配置环境变量。项目提供了一个.env.example模板。cp .env.example .env.local现在打开.env.local文件有几个关键变量需要关注# .env.local NEXT_PUBLIC_SITE_URLhttp://localhost:3000 OPENCLAW_SESSIONS_INDEX~/.openclaw/agents/main/sessions/sessions.json CLAWRANK_PILOT_STORE_PATH./data/clawrank-pilot.json CLAWRANK_OWNER_NAMEYourName # CLAWRANK_INGEST_TOKENyour_secret_token_here # 如需API认证则设置 # DATABASE_URLpostgresql://... # 本地开发如需连接Postgres则设置OPENCLAW_SESSIONS_INDEX: 指向你的OpenClaw会话索引文件路径。如果你没改过OpenClaw的配置默认路径就是~/.openclaw/agents/main/sessions/sessions.json。确保这个文件存在且有数据。CLAWRANK_PILOT_STORE_PATH: 本地开发时使用的JSON存储文件路径。保持默认即可。CLAWRANK_INGEST_TOKEN: 这是一个安全选项。如果你打算将/api/submit或/api/ingest/openclaw接口公开部署强烈建议设置一个复杂的令牌并在调用API时在请求头中传入如Authorization: Bearer token以防止未经授权的数据提交。DATABASE_URL: 本地开发时如果你安装了PostgreSQL并想使用它可以在这里配置连接字符串。如果留空系统会使用上面的pilot JSON文件。配置好后就可以进行首次数据摄取了pnpm pilot:ingest这个命令会读取OPENCLAW_SESSIONS_INDEX指定的文件运行解析和转换逻辑并将生成的“每日Agent事实”保存到CLAWRANK_PILOT_STORE_PATH指定的JSON文件中。你可以在data/clawrank-pilot.json里查看生成的数据。最后启动开发服务器pnpm dev打开浏览器访问http://localhost:3000你应该能看到一个基于你本地会话数据生成的AI Agent排行榜。4.2 数据库集成与数据迁移对于生产环境或更严肃的本地开发使用PostgreSQL是更好的选择。ClawRank使用Drizzle ORM来管理数据库模式和操作这是一个类型安全且性能不错的现代选择。本地PostgreSQL设置确保你已安装并运行了PostgreSQL。创建一个新的数据库例如clawrank。在.env.local中设置DATABASE_URL格式如postgresql://username:passwordlocalhost:5432/clawrank。运行数据库迁移和种子数据导入pnpm db:seed这个db:seed命令通常会做两件事首先执行drizzle-kit push或类似的命令根据代码中的模型定义通常在src/db/schema.ts里在数据库中创建对应的表。然后它会读取data/clawrank-pilot.json中的现有数据并将其插入到数据库表中。完成之后系统就会自动切换到使用数据库而不是JSON文件。验证启动pnpm dev后你可以访问/api/leaderboard?periodalltime这个API端点。如果返回的数据是来自数据库的实时查询结果你可以通过修改数据文件再查看API响应是否变化来验证说明数据库集成成功。4.3 Open Graph图片生成现代分享离不开精美的链接预览图。ClawRank为排行榜和每个Agent详情页都动态生成了Open Graph图片。其实现位于/api/og/下的相关路由。这些API端点接收请求如/api/og/leaderboard?periodweek然后在服务器端使用像vercel/og、satori或canvas这样的库来实时渲染一张图片。技术要点无头渲染这个过程不需要浏览器是在Node.js环境中直接计算并绘制图像速度非常快。样式一致图片采用了项目DESIGN.md中定义的“温暖的终端配色方案”和JetBrains Mono字体与网站UI风格保持高度一致塑造品牌感。动态内容图片上的文字、排名数据都是根据传入的period参数实时从数据库或存储中查询并渲染的。这意味着分享出去的图片永远是最新的数据。实操建议在实现OG图片时最大的挑战是布局和字体。确保你选择的字体文件.ttf或.woff被正确加载到服务器端渲染环境中。vercel/og库对此有很好的支持。另外图片的尺寸要符合社交媒体平台如Twitter、LinkedIn、微信的推荐规范通常是 1200x630 像素。5. 部署策略与生产环境考量将ClawRank部署到生产环境让它持续、自动地运行起来是项目从“玩具”变为“工具”的关键一步。5.1 选择部署平台Vercel的优势项目推荐使用Vercel进行部署这并非偶然。Vercel为Next.js应用提供了开箱即用的极致优化并且其市场Marketplace与Neon Postgres的集成堪称无缝。部署步骤简述将代码推送到GitHub等Git仓库。在Vercel控制台导入该项目。在部署配置中Vercel会自动识别这是一个Next.js项目。关键一步在Vercel项目的“Storage”标签页中一键添加“Neon Postgres”集成。Vercel会自动创建一个Neon数据库并将连接字符串以DATABASE_URL环境变量的形式注入到你的应用中。你完全不需要手动创建数据库或处理连接字符串。这种体验极大地简化了后端数据服务的配置让你可以专注于业务逻辑。5.2 实现持续数据摄取本地运行pnpm pilot:ingest是手动的。在生产环境我们需要自动化这个过程。项目文档中提到了一个核心思路“Wire an OpenClaw skill or cron”。这里有两种主流的实现路径路径一利用OpenClaw Skill推荐OpenClaw支持技能扩展。你可以编写一个ClawRank Skill在这个Skill中监听OpenClaw的新会话完成事件。当事件触发时将新的会话数据或会话索引文件的路径通过HTTP POST请求发送到已部署的ClawRank实例的/api/ingest/openclaw端点。考虑到网络问题可以在Skill中加入简单的重试和本地队列机制。这样做的好处是实时性高数据几乎在对话结束后就能进入排行榜系统。路径二使用Cron Job定时任务如果不想修改OpenClaw可以在部署ClawRank的服务器上或利用Vercel的Serverless Cron Jobs设置一个定时任务。这个定时任务脚本需要能访问到运行OpenClaw的机器的会话文件这可能需要网络共享或SFTP等同步机制复杂度较高。脚本定期如每10分钟读取最新的会话文件。调用/api/ingest/openclaw接口提交新数据。这种方法更通用但实时性稍差且需要解决跨机器的文件访问问题。安全提醒无论哪种方式如果部署的ClawRank API是对公网开放的务必如前所述设置并验证CLAWRANK_INGEST_TOKEN防止恶意数据注入。5.3 性能与监控对于一个小型排行榜应用性能通常不是瓶颈。但仍有几点需要注意数据库索引确保在daily_agent_facts表的关键查询字段上建立索引至少包括(agent_slug, date)复合索引以加速按Agent和日期范围的查询。drizzle-kit在生成迁移文件时可以根据schema定义帮你创建索引。API缓存排行榜数据变化频率不高按日更新非常适合缓存。可以在Vercel上利用其内置的边缘缓存或者使用Next.js的revalidate选项来设置静态生成SSG或增量静态再生ISR的过期时间大幅减少数据库查询和计算开销。日志与监控在关键的流程节点如数据解析错误、数据库写入失败时添加日志记录。Vercel集成了对Serverless Function日志的查看功能。对于更复杂的监控可以考虑接入像Sentry这样的错误跟踪服务。6. 扩展思路与未来可能性ClawRank目前的定位非常清晰和聚焦这在项目初期是巨大的优点。但作为一个开放项目它留下了许多令人兴奋的扩展接口。6.1 支持多数据源当前架构已经为多数据源做好了准备。要支持一个新的AI桌面应用比如“ChatBox”、“LobeChat”你需要在src/adapters/下新建一个目录例如chatbox/实现一个能解析该应用日志文件的适配器。在src/ingestion/下同样新建目录实现从该应用的原始消息到“每日Agent事实”的转换逻辑。不同应用的会话结构不同转换规则也会不同。新增一个对应的API路由例如/api/ingest/chatbox或者扩展现有的/api/submit接口通过一个source参数来区分。领域层和持久层完全不需要改动这就是清晰架构带来的好处。6.2 实现Agent认领与认证流程目前数据是自动收集的。未来可以增加一个功能允许Agent的开发者或维护者“认领”自己的Agent。这需要一个简单的用户系统可以基于GitHub OAuth等第三方登录。一个“认领”流程用户证明自己与某个agentSlug的关联例如通过在该Agent的官方文档中添加一个特定的验证码。认领后该用户可以获得更详细的数据分析看板或许还能设置Agent的展示信息如头像、描述、官网链接。/api/submit接口可以升级支持经过认证的用户提交更丰富的数据或者覆盖自动收集的数据用于数据修正。6.3 丰富排行榜维度与算法目前的排名逻辑可能相对简单比如按会话次数。可以引入更复杂的、加权计算的“分数”系统。多维度指标除了使用次数可以考虑会话满意度根据对话结束语判断、任务复杂度根据会话长度和模式判断、用户评分如果引入反馈机制等。趋势权重给近期活跃度更高的Agent一定的权重加成让排行榜更能反映“当前”谁最受欢迎。分类排名不再只有一个总榜可以分出“编程助手榜”、“创意写作榜”、“数据分析榜”等这需要在对会话内容进行更深入的意图识别后才能实现。这些更复杂的计算可以放在领域层的LeaderboardAggregator服务中实现通过配置化的方式允许动态调整算法。7. 常见问题与排查实录在实际搭建和运行ClawRank的过程中你可能会遇到一些问题。以下是我遇到的一些典型情况及其解决方法。7.1 数据摄取失败或无数据问题运行pnpm pilot:ingest后data/clawrank-pilot.json文件为空或没有新数据。排查步骤检查环境变量确认.env.local中的OPENCLAW_SESSIONS_INDEX路径是否正确。可以使用cat $OPENCLAW_SESSIONS_INDEX命令在终端中先export一下变量看看文件是否存在且内容是否有效JSON。检查文件权限确保Node.js进程有权限读取该会话文件。查看日志在ingestion逻辑中添加一些console.log打印出解析到的原始消息数量看看是解析环节出错还是转换环节过滤掉了所有数据。验证适配器单独运行src/adapters/openclaw的解析函数传入一个已知的会话文件看输出是否符合预期。7.2 本地开发服务器无法启动或API 404问题pnpm dev成功但访问localhost:3000白屏或访问/api/leaderboard返回404。排查步骤检查Next.js版本与配置确保项目依赖的next版本与代码兼容。检查next.config.js是否有特殊的路由重写或重定向配置。检查API路由文件确认pages/api/目录下或app/api/目录取决于项目是Pages Router还是App Router是否存在leaderboard.ts等文件。文件名必须与路由路径匹配。查看终端错误pnpm dev的终端输出通常会有编译错误或运行时错误的堆栈信息这是最重要的调试线索。7.3 数据库连接错误问题配置了DATABASE_URL后运行应用或执行pnpm db:seed时出现数据库连接错误。排查步骤验证连接字符串仔细检查DATABASE_URL的每一个部分协议、用户名、密码、主机、端口、数据库名。特别是密码中的特殊字符可能需要URL编码。测试网络连通性使用psql命令行工具或像pgAdmin这样的图形客户端尝试用相同的连接信息手动连接数据库确保数据库服务正在运行且可从你的开发机访问。检查SSL模式一些云数据库包括Neon默认要求SSL连接。在本地开发时你可能需要在连接字符串后添加?sslmoderequire参数或者在Drizzle的配置中明确SSL选项。查看Drizzle配置检查src/db/index.ts或类似的文件中创建Drizzle客户端时传入的配置项是否正确。7.4 Open Graph图片生成乱码或布局错乱问题分享链接时生成的预览图文字显示为方框乱码或布局不对。排查步骤字体文件问题这是最常见的原因。确保用于OG图片生成的字体文件.ttf被正确放置在项目内如public/fonts目录并且在生成图片的API代码中字体文件的加载路径是相对于项目根目录的绝对路径在Vercel Serverless环境中或者是通过fs.readFileSync读取的完整路径。不要使用相对路径。尺寸与样式检查图片生成代码中设置的width、height以及各个文本元素的x、y坐标、fontSize、lineHeight等样式属性。在不同尺寸下测试渲染效果。使用调试工具可以临时修改OG图片API将其输出为HTML而不是图片这样可以在浏览器中直观地查看渲染前的元素布局便于调试。这个项目从构思到实现最深的体会是清晰的边界定义是软件可维护性的基石。将系统严格划分为适配器、摄取、领域、持久化等层每一层只做一件事并且通过明确的接口通信使得每一部分都可以独立开发、测试和替换。当你需要新增一个数据源或者修改排名算法时这种架构的优势就会淋漓尽致地体现出来——你几乎不会碰到“牵一发而动全身”的困境。
返回列表