返回博客

如何用 Astra 为独立开发找项目

作者 约 4 分钟读完

用 ChatGPT 6 Astra 写了个机会研究工具:把有收入的软件业务收进来,让模型拆出客户为什么付费、哪些功能能砍、最小 MVP 长什么样。附完整技术栈、CSV/HTML/URL 三种数据入口,以及 Zod 结构化输出和 Prisma 事务写入的实现细节。


如何用 Astra 为独立开发找项目

ChatGPT 6 Astra 出来之后,我拿它写了个小工具,给自己找独立开发的项目用。

思路不复杂:把那些已经有收入的软件业务收集起来,交给模型拆一遍——用户真正掏钱买的是什么,现有产品里哪些功能其实可以删掉,还有哪些痛点没人解决,砍到最小能做成什么样的 MVP,如果自己下场,差异化的点又在哪。

界面做成什么样

首页是一个列表,收进来的都是已经过市场验证的业务,可以按收入和分析状态筛,点进去看完整的拆解报告。

我刻意没做成营销落地页的样子。收入、利润率、售价、分析状态都用明确的数据层级排开,方便横着扫一眼做比较。产品本身就是"从复杂业务里找更小的产品",界面就没必要再堆装饰——留白、清晰的边界、每块只讲一件事,把结论放在最显眼的位置。

顶部数据条只放四个全局指标:机会数量、AI 分析覆盖率、总月收入、总月利润。看的是当前样本够不够大、整体商业质量如何。

报告本身分四块:

  1. What customers need:客户为什么付费。
  2. Where the market still hurts:现有方案仍未解决的问题。
  3. The MVP worth shipping:最值得构建的精简功能。
  4. What to cut:不该进入第一个版本的复杂功能。

每条结论都带序号。AI 生成的内容往往偏长,有编号好扫得多,讨论的时候也能直接指第几条。

收入排序的机会列表,点开是完整拆解报告

技术原理

整条链路是这么走的:

  1. 从 CSV、浏览器保存的 HTML 或者 API 接收软件业务信息。
  2. 把不同来源的数据统一转成 ListingInput。
  3. 按来源 URL 去重,写入数据库。
  4. 把待处理的项目丢给大语言模型,用 Zod 约束返回结构。
  5. 分析报告和处理状态原子化写入数据库。
  6. 页面走服务端渲染,提供筛选、概览和报告阅读。

三种数据入口收敛成统一结构,再入库、过模型、出报告

技术栈

层级技术作用
Web 框架Next.js 16 App Router路由、服务端渲染、API Route
UIReact 19页面与组件结构
样式Tailwind CSS 4 + Global CSS基础样式能力、设计令牌和响应式布局
ORMPrisma ORM 7数据模型、类型生成和数据库访问
数据库驱动pg / better-sqlite3PostgreSQL 与 SQLite 连接
AIVercel AI SDK调用模型并生成结构化结果
数据校验Zod校验 AI 返回的数据结构
HTML 解析Cheerio从保存的网页中提取业务信息
CSV 解析csv-parse将 CSV 转换为标准数据
部署VercelNext.js 托管与定时任务
语言TypeScript静态类型检查

统一输入模型

所有数据入口最终都会转成 ListingInput:

type ListingInput = {
  sourceUrl: string;
  title: string;
  category?: string;
  askingPrice?: number;
  monthlyRevenue?: number;
  monthlyProfit?: number;
  description: string;
  pricingInfo?: string;
  reviewsSnippet?: string;
  rawData?: string;
};

这样"数据从哪来"和"数据怎么存"就不互相牵扯了。以后要接浏览器插件、第三方采集服务或者别的交易平台,只要能吐出同样的结构就行。

CSV 导入

npm run import:csv -- path/to/file.csv

scripts/import-csv.ts 读文件,parseListingsCsv() 按表头逐行解析,检查 sourceUrl、title、description 三个必填字段,把金额里的货币符号和千分位清掉,最后交给统一入库函数。

CSV 是目前最稳的入口,它不依赖目标网站的页面结构,也不用管人家的反爬策略。

HTML 导入

npm run import:html -- path/to/html-directory

解析分两级。先找页面里的 application/json 或 __NEXT_DATA__,在里面递归找同时带标题、价格或收入特征的对象;实在找不到结构化数据,才退回 DOM、Meta 标签和正则去抠。

递归最多下六层,提取到的原始对象截断后存进 rawData,解析出错的时候好排查。

网页结构随时会变,所以这套解析是启发式的,别当成稳定 API 用。

URL 直接抓取

npm run fetch:listings -- urls.txt

逐行读 URL,普通 HTTP 请求拿 HTML,每次请求之间等三秒,然后交给上面那个解析器,最后汇总成功和失败的清单。

它不会去绕验证码、浏览器挑战、代理限制或设备指纹。碰到 403 就老实换 CSV 或者浏览器保存的 HTML。

AI 分析

单条项目分析

analyzeListing() 把项目名称和类别、售价、月收入月利润、原始业务描述、定价信息、用户评价拼进提示词。

结构化输出

输出这块直接用:

Output.object({ schema: ReportSchema })

让模型按 Zod 定义好的结构返回:

{
  summary: string;
  coreNeeds: string[];
  redundantFeatures: string[];
  unmetPainPoints: string[];
  suggestedMvpFeatures: string[];
  differentiation: string;
}

字段名稳定,数组和字符串类型明确,页面就不用去猜自然语言的格式。不符合 Schema 的输出直接算失败。

Schema 是固定形状的槽位,对不上的输出被挡在外面

批量分析

analyzePendingListings(limit) 捞出状态是 PENDING 的项目,一条一条处理。

单条分析成功后,用 Prisma 事务同时创建或更新 Report、把 Listing.status 改成 ANALYZED。两件事都成功事务才提交,否则就会出现报告已经生成但状态没更新(或者反过来)的中间状态。模型调用、结构校验、数据库写入任何一步挂了,状态就置成 FAILED。

现在是串行跑的。逻辑简单、调用速率好控制,代价是数据一多就慢。后面想加受控并发、重试次数和错误原因字段。

现在怎么用

整个工程都是 Astra 写的,但运行时不用 Astra 模型(太贵),一般用 GPT 5.6 Terra 分析效果也够用。眼下主要拿它分析 AppStore 上的产品,从里面挑能搬到鸿蒙端做的 App。