GitHub Trending 我经常看,真正费时间的是看完之后。榜单上冒出一个项目,我得先点进去,再翻 README、找启动命令、看目录,最后还要自己判断它是短期热度,还是确实值得继续研究。项目一多,这个过程很快就变成了重复劳动。
所以我做了一个小工具,名字就叫 GitHub 热榜 AI 解读器。它不替我读完源码,也不根据 star 数直接下结论;它先把热榜、README 和目录这些资料收拢起来,再给出一份带依据的整理结果。模型这一层我接在蓝耘元生代 MaaS 上,用的是 DeepSeek-V3.2,流程放在 Dify Chatflow 里,GitHub 仍然是数据来源。
我先做了热榜查询,再拿一个真实仓库跑指定项目分析。两条路径都能从同一个输入框发起,这样更接近我平时查项目的习惯:看到一个名字就问一句,不用先想应该点哪个功能。
一、先把热榜和指定仓库两条路径跑通
这个工具没有把入口做成一排固定的筛选框,而是保留了自然语言输入。比如我可以直接问“今天 GitHub 有什么热门 Python 项目?”,也可以把仓库地址和问题放在一起:https://github.com/acowbo/health-reminder 帮我分析一下这个项目。
两种输入看起来差别很小,后面的数据路径却不一样。热榜问题需要请求 Trending 页面,整理当天的候选项目;仓库分析则需要读取仓库元信息、README 和目录结构。让模型先做意图识别,用户就不用先猜应该点哪个模式。
工作流面板里把这条路径拆成了四步:意图识别、真实数据获取、结构化清洗、生成技术简报。这里的“真实数据”不是模型凭记忆补全,而是 Chatflow 运行时去读取 GitHub 的公开内容;模型的任务是对已经拿到的材料进行归纳、判断和组织。
二、为什么这次把模型放在蓝耘元生代上
我选模型服务时,先看的是接入成本,而不是宣传页上的模型数量。这个项目要放进 Dify,至少要满足三个条件:有 OpenAI 兼容接口,模型名能稳定锁定,调用结果可以在平台侧查到。蓝耘元生代的 MaaS 平台把 DeepSeek、通义、智谱、Kimi、MiniMax 等模型放在同一个模型广场里,切换模型时不需要重写业务层。
蓝耘首页的模型卡片会同时给出模型类型、上下文长度、供应商和 API 示例入口。对我来说,这比只看到一个模型下拉框更实用:选型时可以先看能力标签,再决定把哪个模型放进 Dify。
在模型详情页可以直接看到 OpenAI 兼容的请求示例。本文使用的模型名是 /maas/deepseek-ai/DeepSeek-V3.2,Base URL 是 https://maas-api.lanyun.net/v1。这里有一个容易写错的细节:Base URL 已经包含 /v1,请求时只再拼 /chat/completions,不要重复拼成 /v1/v1/chat/completions。
我先用最小请求做连通性验证,再把它交给 Dify。返回内容、模型名称和 usage 都能正常拿到,说明问题还没有进入 Chatflow,接口层已经先过了一遍。
这一步也让我确认了蓝耘在项目里的边界:它承担的是模型推理,不负责抓 GitHub 数据,也不替代 Dify 的分支和代码节点。这样拆开之后,哪一层出了问题都比较容易定位。
调用记录还可以回到蓝耘控制台查看。一次最小请求会留下模型名称、调用次数和 token 消耗,这对排查“请求到底有没有到模型”很有帮助。
三、在 Dify 里把蓝耘接进 Chatflow
Dify 里先添加 OpenAI-API-compatible 模型供应商。配置时使用下面这组值:
模型名称:lanyun-dp3
模型类型:LLM
API Base URL:https://maas-api.lanyun.net/v1
API endpoint 中的模型名称:/maas/deepseek-ai/DeepSeek-V3.2
API Key:蓝耘 MaaS 控制台创建的 Key
模型配置好以后,Chatflow 的应用信息里把这个项目的用途写清楚:获取近期热门开源项目,或者对指定 GitHub 仓库生成架构报告、启动指南、贡献建议和技术价值分析。应用信息不是装饰,它决定了后来维护这个工作流的人能不能快速理解入口和输出。
整个流程可以按下面的顺序理解:
- 开始节点接收
sys.query。 - “LLM 意图识别”判断是
trending还是repository。 - 输入规范化节点把语言、时间范围、仓库 URL 等字段整理出来。
- 条件分支选择热榜路径或指定仓库路径。
- HTTP 请求节点获取 GitHub Trending、仓库元信息、README 和目录内容。
- 代码节点清洗返回数据,避免把整页 HTML 原样塞进提示词。
- 报告节点输出结构化 Markdown。
工作流里有三个 LLM 节点,意图识别和两条报告生成路径都统一选择蓝耘模型。它们不是“看起来用了蓝耘”,而是每个需要模型推理的位置都落到同一个 MaaS 配置上。
前端没有直接把蓝耘 Key 或 Dify App Key 放进浏览器。Next.js 的 API 路由只从服务端环境变量读取 Dify 配置,再把请求转发给 Chatflow:
const chatClient = new ChatClient(
process.env.DIFY_API_KEY,
(process.env.DIFY_API_URL || '').replace(/\/$/, ''),
);
const response = await chatClient.createChatMessage(
{},
query,
'lanyun-github-insight-web',
true,
);
return new Response(response.data, {
headers: { 'Content-Type': 'text/event-stream' },
});
本地运行时,.env.local 只保存 Dify 应用地址和 App Key,蓝耘的模型地址则保存在 Dify 的供应商配置中:
DIFY_API_URL=https://api.dify.ai/v1
DIFY_API_KEY=app-xxxxxxxxxxxxxxxx
这两个地址不要混在一起:前者是应用调用 Dify 的地址,后者是 Dify 调用蓝耘模型的地址。
四、先跑热榜,再看报告是不是有内容
我先用“今天 GitHub 有什么热门 Python 项目?”做热榜路径测试。请求提交后,页面状态会从“服务就绪”变成“正在连接工作流”,右侧的四个步骤按顺序推进。这个状态变化很重要,因为 GitHub 请求和模型生成都不是瞬间完成的,用户需要知道请求还在工作,而不是误以为按钮失效。
最终报告包含日期、数据范围、候选项目数量和报告性质。一次运行返回了 7 个候选项目,范围是 GitHub Trending Daily,报告聚焦 AI、开发者工具和基础设施。模型没有只复述项目简介,而是先提炼趋势,再把项目放进推荐表里。
推荐表是我比较在意的输出形式。它把项目、语言、今日 star、总 star、核心价值、适合人群和推荐指数放到一张表里。例如 public-apis/public-apis、cordiverse/cordis、sponsors/unslothai 会被放在同一套字段下比较,读者可以先看表,再决定要不要点开某个仓库。
运行记录也会回到 Dify 的日志中。热榜查询和仓库分析都显示为 SUCCESS,用户标识统一为 lanyun-github-insight-web,右侧可以打开完整对话,检查输入和生成结果是否对应。
五、指定仓库分析:从 README 走到模块推断
热榜是发现入口,真正体现工具价值的还是指定仓库分析。我输入的是 acowbo/health-reminder,页面会把仓库地址原样保留在输入框里,同时仍然显示同一条四步处理链路。
报告先给出项目定位,再列出技术栈、目录结构和成熟度判断。对于 health-reminder,输出识别到 React 19、TypeScript、Vite、Tauri 2、Rust、Web Notification API、GitHub Actions 和 npm 等技术线索,并把这些判断和 README、src/ 文件、工作流文件关联起来。
这种分析不等于模型“看懂了全部源代码”。报告里把依据写出来,结论就有了边界:README 写了什么、目录里有没有对应文件、配置文件是否存在,都是可以回头核对的证据。比如许可证字段在仓库元数据里显示为 Unknown,但 README 的 License 章节写明是 MIT,这种差异也会被保留下来,而不是直接给出一个过于确定的结论。
模块推断部分则把“功能描述”与“可能的实现路径”分开。状态栏倒计时、提醒调度、运动数据、设置持久化、通知服务等模块,都标注了推断前提和可能涉及的目录或文件。这样读者可以把它当作继续阅读代码的索引,而不是把推断当成已经验证过的事实。
六、实际遇到的问题:报告是 Markdown,但页面一开始不会完整渲染
第一次接通工作流时,Dify 返回的报告内容本身没有问题,问题出在前端。最初的页面只手写支持了标题、简单无序列表和表格,遇到 > 引用、--- 分隔线、单星号斜体和代码块时,页面会把 Markdown 标记直接显示出来。报告里出现的判断依据和警告信息因此很难读。
解决方式不是继续往正则表达式里堆规则,而是把 Markdown 解析交给 GFM 解析器 marked,再用 DOMPurify 清理生成的 HTML。这样表格、引用、有序列表、代码块和强调语法走同一套解析规则,模型偶尔输出 HTML 片段时也不会直接执行脚本。流式输出时仍然按 160 毫秒合并刷新,解析范围只是从“自己拼 HTML”换成了完整 Markdown 渲染。
报告生成以后还可以直接复制。复制的不是屏幕上的纯文本,而是原始 Markdown,这样粘贴到文档或知识库里还能保留标题、表格和代码块。
七、把项目跑起来
项目是一个 Next.js 应用,Dify 通过服务端 API 代理访问,前端不接触任何密钥。准备好 Dify Chatflow 和蓝耘模型后,执行:
npm install
cp .env.example .env.local
# 编辑 .env.local,填写 Dify 应用 API
npm run dev
打开 http://localhost:3000 后,可以先用“查看演示报告”检查页面和 Markdown 样式,再提交真实热榜问题。Dify 端需要确认 Chatflow 的三个 LLM 节点都选择了蓝耘模型,API Base URL 保持 https://maas-api.lanyun.net/v1,模型名保持 /maas/deepseek-ai/DeepSeek-V3.2。
这个项目里,蓝耘元生代承担的是可替换但明确的模型服务角色:它接收经过 GitHub 数据清洗后的上下文,完成意图识别和报告生成;Dify 保留了流程、分支和日志;GitHub 提供项目事实;Next.js 把这些能力收束成一个可以直接使用的入口。换句话说,换模型不会把 GitHub 数据层和前端页面一起推倒重来。
结尾
跑完热榜和 health-reminder 两种输入后,我现在会把这份报告当成打开仓库前的第一轮筛选。它能帮我先看清项目定位、技术栈、目录和风险,但不会替我完成源码审查;报告里写了“可能的实现路径”,我仍然会回到仓库里核对。
蓝耘在这个项目里的位置也很明确:Dify 需要一个能直接接入的 OpenAI 兼容模型,三个 LLM 节点统一使用 DeepSeek-V3.2;GitHub 数据怎么取、分支怎么走、结果怎么展示,仍然由 Chatflow 和 Next.js 处理。把这几层分开之后,调试时不必在一大段生成文字里猜问题出在哪,模型地址、数据请求和页面渲染可以各自检查。
以后再遇到一个突然冲上热榜的仓库,我会先把地址丢进这个工具,等报告把 README 和目录整理出来,再决定要不要花时间把项目拉下来。