在现有个人网站中实现“需求雷达”:完整扩展开发方案
在现有个人网站中实现“需求雷达”:可直接执行的扩展开发方案
本文是一份面向现有项目的开发规格。实施时不新建另一套网站、账号系统或内容后台,而是在原有 Next.js 网站中增加管理界面,并新增一个隔离运行的 Python 分析服务。
1. 开发目标
“需求雷达”要帮助我从公开讨论中提取真实问题,再根据原文证据决定是否进入产品验证。
完整链路如下:
公开数据源
→ Python 服务采集
→ 原文进入现有数据库的 radar_* 表
→ AI 提取需求证据
→ Embedding 召回相似问题
→ 在原网站中人工审核
→ 形成需求簇和机会卡
→ 关联文章、验证页、组件和开发任务
→ 通过现有 MCP 提供给大模型
系统的目标不是自动宣布“应该开发什么产品”,而是建立一条可追溯的证据链:
原始表达 → 使用场景 → 问题 → 当前方案 → 不满意之处 → 需求簇 → 验证假设
2. 与原项目的集成原则
这不是一个新的独立产品,而是原网站的内部运营模块。
2.1 直接复用
- 原网站的 Next.js 应用;
- 原有登录和管理员权限;
- 原有数据库及迁移机制;
- 原有 UI 组件和管理页面布局;
- 原有文章、动态组件和模板系统;
- 原有 MCP 服务及身份验证;
- 原有部署、日志和配置方式。
2.2 新增但保持隔离
- Python Radar Worker;
- 采集器、文本清洗和模型调用;
- Embedding 与相似需求召回;
- 定时任务;
- 所有以
radar_为边界的数据表; - Next.js 中的
radar管理路由; - MCP 中只读优先的 Radar 工具。
2.3 明确禁止重复建设
第一版不得:
- 新建另一套用户表;
- 新建另一个登录页面;
- 新建另一套文章系统;
- 为 Radar 单独创建公共前台;
- 让浏览器直接访问 Python 服务;
- 让 Python 服务取得整个主站数据库权限;
- 为了加入一个模块先重构全站 Monorepo;
- 把 Playwright、Embedding 或批量模型任务放进普通 Next.js 请求生命周期。
3. 开发前先审查现有项目
文章不能预先假设原项目使用 Prisma、Drizzle、PostgreSQL 或 MySQL。实际开发的第一步必须读取项目并生成《接入审查结果》。
至少确认以下项目:
| 检查项 | 需要得到的结果 |
|---|---|
| Next.js 结构 | App Router 或 Pages Router |
| 数据库 | PostgreSQL、MySQL、SQLite 或其他 |
| ORM | Prisma、Drizzle、TypeORM 或自研 |
| 身份认证 | Session、JWT、Auth.js 或自研 |
| 管理员判断 | 现有角色字段或权限函数 |
| API 模式 | Route Handler、Server Action 或独立 API |
| 部署方式 | Node 常驻、Serverless、Docker 或面板进程 |
| MCP 位置 | 同仓库、独立服务或远程服务 |
| 文章关联 | Article 主键和关系建模方式 |
| 组件关联 | 生成组件的主键和版本方式 |
| 测试工具 | Vitest、Playwright、pytest 等 |
| 目录规范 | 当前模块、服务、数据库代码放置规则 |
审查结束后只输出差异化落点,例如:
现有 ORM:Prisma
新增模型位置:prisma/schema.prisma
管理员守卫:src/server/auth/require-admin.ts
内部 API:src/app/api/internal/radar/*
Python 服务:services/demand-radar/
数据库:复用现有 PostgreSQL
不能因为本文给出了 SQL 示例,就绕开原有 ORM 和迁移体系直接建表。
4. 目标架构
系统采用“同一个产品、同一个仓库、同一个管理入口、两个运行进程”。
浏览器
│
▼
现有 Next.js 网站
├─ 复用登录与管理员权限
├─ /radar/inbox
├─ /radar/clusters
├─ /radar/opportunities
└─ /api/internal/radar/*
│
│ 内网请求 + 服务密钥
▼
Python Radar Worker / API
├─ Collectors
├─ Normalizer
├─ LLM Extractor
├─ Embedding
├─ Similarity Suggestions
└─ Scheduler
│
▼
现有数据库中的 radar_* 表
职责分工:
| 模块 | 负责 | 不负责 |
|---|---|---|
| Next.js | UI、登录校验、人工审核、数据关联、代理请求 | 长时采集、本地模型、批量任务 |
| Python 服务 | 采集、清洗、AI 提取、Embedding、聚类建议 | 用户登录、公开页面、文章发布 |
| 数据库 | 原文、证据、任务状态、关联关系 | 替代业务判断 |
| MCP | 向模型提供审核后的数据和有限操作 | 执行任意爬虫、任意 SQL |
5. 仓库落点
如果原项目不是 Monorepo,不为此进行大规模目录迁移。推荐直接新增:
<existing-project>/
├─ src/
│ ├─ app/
│ │ ├─ radar/
│ │ │ ├─ layout.tsx
│ │ │ ├─ inbox/page.tsx
│ │ │ ├─ clusters/page.tsx
│ │ │ ├─ clusters/[id]/page.tsx
│ │ │ └─ opportunities/[id]/page.tsx
│ │ └─ api/internal/radar/
│ ├─ components/radar/
│ ├─ features/radar/
│ │ ├─ api/
│ │ ├─ schemas/
│ │ ├─ queries/
│ │ └─ permissions/
│ └─ server/radar/
├─ services/
│ └─ demand-radar/
│ ├─ app/
│ │ ├─ api/
│ │ ├─ collectors/
│ │ ├─ extractors/
│ │ ├─ embeddings/
│ │ ├─ repositories/
│ │ ├─ services/
│ │ ├─ jobs/
│ │ ├─ core/
│ │ └─ main.py
│ ├─ tests/
│ ├─ pyproject.toml
│ └─ Dockerfile
├─ scripts/
└─ docker-compose.yml
如果现有项目已经是 Monorepo,则遵循原有 workspace 规则,把 Python 服务放入已有的 apps 或 services 目录。
6. 数据库策略
6.1 优先复用现有数据库
只要原数据库适合保存业务数据,就在其中增加独立命名空间:
radar_topics
radar_sources
radar_runs
radar_documents
radar_evidence
radar_extractions
radar_embeddings
radar_clusters
radar_cluster_members
radar_reviews
radar_opportunities
radar_links
radar_audit_logs
不要默认再引入 SQLite。只有当原项目没有数据库,或 Python 原型必须完全离线运行时,才使用 SQLite。
6.2 Python 数据库权限
为 Python 服务创建独立数据库账号,只允许:
- 读写
radar_*表; - 读取经过明确批准的少量关联表;
- 不允许修改用户、文章、组件和权限表;
- 不允许执行数据库结构变更。
数据库迁移仍由原项目的迁移工具负责。
6.3 与原业务的关联
Radar 不直接在核心表上增加大量字段,而是通过通用关联表连接:
CREATE TABLE radar_links (
id VARCHAR(36) PRIMARY KEY,
opportunity_id VARCHAR(36) NOT NULL,
target_type VARCHAR(32) NOT NULL,
target_id VARCHAR(128) NOT NULL,
relation_type VARCHAR(32) NOT NULL,
created_at TIMESTAMP NOT NULL,
UNIQUE(opportunity_id, target_type, target_id, relation_type)
);
建议枚举:
target_type:
article | validation_page | generated_component | layout_template | development_task
relation_type:
evidence | explains | implements | validates | documents
这样可以建立:
机会卡
├─ 关联分析文章
├─ 关联问题验证页
├─ 关联生成组件
└─ 关联开发任务
7. 核心数据模型
7.1 radar_topics
记录研究方向:
id
name
description
status
created_at
updated_at
第一期主题:
个人开发者如何利用 AI 降低网站内容管理和运营成本。
7.2 radar_sources
记录数据源与增量游标:
id
topic_id
source_type
name
config_json
cursor_json
enabled
last_collected_at
created_at
updated_at
密钥不能进入 config_json,只保存环境变量引用名称。
7.3 radar_runs
所有长任务统一记录:
id
job_type
source_id
status
started_at
finished_at
scanned_count
inserted_count
skipped_count
failed_count
cursor_before_json
cursor_after_json
error_code
error_message
metadata_json
任务状态:
pending → running → succeeded
↘ partially_failed
↘ failed
↘ cancelled
7.4 radar_documents
保留未经模型改写的原文:
id
source_id
external_id
canonical_url
title
author_external_id
author_name
published_at
raw_text
normalized_text
content_hash
language
metadata_json
processing_status
collected_at
updated_at
唯一约束:
(source_id, external_id)
(canonical_url, content_hash)
7.5 radar_evidence
记录当前可审核的需求证据:
id
document_id
extraction_id
ordinal
user_type
scenario
problem
expected_result
current_solution
dissatisfaction_json
demand_signal
payment_signal
evidence_quote
confidence
review_status
created_at
updated_at
枚举:
demand_signal:
complaint | request | workaround | migration | purchase | discussion
payment_signal:
none | weak | explicit
review_status:
pending | accepted | corrected | rejected
7.6 radar_extractions
单独保存模型运行记录,避免升级模型时覆盖历史:
id
document_id
model_name
extractor_version
prompt_version
input_hash
raw_response
token_usage_json
duration_ms
status
error_message
created_at
人工审核过的证据默认不得被新提取结果覆盖。
7.7 radar_embeddings
evidence_id
model_name
model_revision
dimensions
vector_data
input_hash
created_at
如果原数据库支持向量类型,可使用原生向量列;否则第一版保存 float32 二进制,由 Python 批量读取计算余弦相似度。几百条数据不需要额外部署向量数据库。
7.8 radar_clusters 与 radar_cluster_members
radar_clusters:
id
topic_id
name
summary
target_user
core_problem
status
score_json
opportunity_score
created_at
updated_at
radar_cluster_members:
cluster_id
evidence_id
membership_source
similarity
created_at
membership_source:
suggested | manual | confirmed
7.9 radar_opportunities
id
cluster_id
hypothesis
proposed_solution
validation_method
success_criteria
rejection_criteria
status
created_at
updated_at
状态:
draft | ready_to_validate | validating | validated | rejected | archived
8. 统一采集器接口
每个来源实现统一协议:
from datetime import datetime
from typing import Any, Protocol
from pydantic import BaseModel, HttpUrl
class CollectedDocument(BaseModel):
external_id: str | None
canonical_url: HttpUrl
title: str | None
author_external_id: str | None
author_name: str | None
published_at: datetime | None
raw_text: str
language: str | None
metadata: dict[str, Any]
class CollectResult(BaseModel):
documents: list[CollectedDocument]
next_cursor: dict[str, Any] | None
class Collector(Protocol):
async def collect(
self,
config: dict[str, Any],
cursor: dict[str, Any] | None,
) -> CollectResult: ...
后续新增来源只增加新的 Collector,不修改下游流程。
Crawlee 提供 HTTP、无头浏览器、请求路由、持久队列、并发和重试等能力,可以用于后续网页来源扩展。Crawlee for Python 官方文档
9. 第一数据源:GitHub Issues
第一版先接一个真实数据源,不同时开发多个采集器。
推荐顺序:
- GitHub REST API;
- 指定仓库的 Issues;
- 可选读取有限数量的评论;
- 后续再加入 Discussions 或公开论坛。
配置示例:
{
"repositories": ["owner/repository"],
"state": "all",
"labels": [],
"include_comments": true,
"max_comments": 20,
"updated_since_days": 30,
"max_items_per_run": 100
}
GitHub 的 Issues API 结果可能包含 Pull Request。存在 pull_request 字段时,第一版跳过,避免把代码审查讨论混入需求样本。GitHub Issues REST API
一条 Issue 形成一条 radar_document:
Issue 标题
Issue 正文
[评论 | 作者 | 时间]
评论正文
过滤:
- Bot 评论;
- Issue 模板中未填写的占位符;
- 大段日志和堆栈;
- 重复引用;
- 与问题无关的自动通知。
10. 增量采集和幂等
执行规则:
- 新建
radar_run并保存旧游标; - 拉取一页;
- 标准化每条记录;
- 根据外部 ID 和内容哈希幂等写入;
- 当前页全部持久化后才推进游标;
- 请求失败时保持旧游标;
- 429 按响应头等待;
- 5xx 使用指数退避;
- 单条解析失败只增加失败计数;
- 服务重启时将遗留的
running任务标记为失败或中断。
文本标准化只做:
- Unicode NFKC;
- 换行统一;
- 连续空白折叠;
- 明确模板噪声删除;
- 保留原句、标点和段落。
def content_hash(normalized_text: str) -> str:
return sha256(normalized_text.encode("utf-8")).hexdigest()
raw_text 永久保存,后续清洗规则变化时重新生成 normalized_text,不得反向覆盖原文。
11. AI 结构化提取
Pydantic 用于校验模型输出,并可以生成 JSON Schema 作为结构化输出契约。Pydantic Models 官方文档
from enum import StrEnum
from pydantic import BaseModel, ConfigDict, Field
class DemandSignal(StrEnum):
COMPLAINT = "complaint"
REQUEST = "request"
WORKAROUND = "workaround"
MIGRATION = "migration"
PURCHASE = "purchase"
DISCUSSION = "discussion"
class PaymentSignal(StrEnum):
NONE = "none"
WEAK = "weak"
EXPLICIT = "explicit"
class ExtractedEvidence(BaseModel):
model_config = ConfigDict(extra="forbid")
user_type: str | None
scenario: str | None
problem: str = Field(min_length=4, max_length=300)
expected_result: str | None
current_solution: str | None
dissatisfaction: list[str] = Field(default_factory=list)
demand_signal: DemandSignal
payment_signal: PaymentSignal
evidence_quote: str = Field(min_length=2, max_length=500)
confidence: float = Field(ge=0, le=1)
class ExtractionResult(BaseModel):
model_config = ConfigDict(extra="forbid")
is_demand_evidence: bool
rejection_reason: str | None = None
items: list[ExtractedEvidence] = Field(default_factory=list)
Prompt 固定规则:
- 只提取原文明确表达的问题;
- 不把文章主题当成作者需求;
- 不推断职业和支付能力;
- 没有信息则返回
null或none; - 一篇文档允许零条或多条证据;
- 广告、新闻和泛泛观点标记为无证据;
evidence_quote必须来自输入原文。
程序二次验证引用:
for item in result.items:
if item.evidence_quote not in document.raw_text:
raise UngroundedEvidenceError(item.evidence_quote)
落库时同时记录模型、Prompt、输入哈希、原始响应、耗时和 Token。模型升级产生新 radar_extraction,不覆盖旧结果。
12. Embedding 与相似需求召回
Sentence Transformers 可以生成句向量并计算语义相似度,适合第一版进行本地 Top-K 召回。Semantic Textual Similarity 文档
Embedding 输入只使用结构化字段:
def build_embedding_text(evidence) -> str:
return "\n".join([
f"用户类型:{evidence.user_type or '未知'}",
f"使用场景:{evidence.scenario or '未知'}",
f"核心问题:{evidence.problem}",
f"期望结果:{evidence.expected_result or '未知'}",
f"当前方案:{evidence.current_solution or '未知'}",
])
第一版不自动决定归类:
- 仅处理
accepted和corrected证据; - 计算新证据与已有簇中心向量的余弦相似度;
- 返回 Top 5;
- 大于 0.82:强候选;
- 0.68~0.82:弱候选;
- 小于 0.68:建议创建新簇;
- 人工确认后才写入正式成员关系。
阈值必须使用环境变量配置,并通过人工标注样本校准。
13. Next.js 内部代理
浏览器不直接请求 Python 服务。
请求链路:
浏览器
→ Next.js /api/internal/radar/*
→ 检查现有 Session
→ 检查管理员权限
→ 添加 RADAR_SERVICE_TOKEN
→ 转发给 Python 服务
代理必须:
- 复用原项目的管理员守卫;
- 设置超时;
- 限制请求体大小;
- 过滤不应转发的 Header;
- 统一错误格式;
- 不把内部服务地址和密钥发给浏览器;
- 对修改操作记录当前管理员 ID。
Python 服务只监听内网,或只接受带服务密钥的请求。
14. API 边界
Python 服务提供内部接口:
POST /internal/radar/sources/{id}/crawl
GET /internal/radar/runs
GET /internal/radar/runs/{id}
GET /internal/radar/documents
GET /internal/radar/documents/{id}
GET /internal/radar/evidence
PATCH /internal/radar/evidence/{id}
POST /internal/radar/evidence/{id}/accept
POST /internal/radar/evidence/{id}/reject
POST /internal/radar/evidence/{id}/reprocess
GET /internal/radar/clusters
POST /internal/radar/clusters
GET /internal/radar/clusters/{id}
POST /internal/radar/clusters/merge
POST /internal/radar/clusters/{id}/split
POST /internal/radar/clusters/{id}/members
DELETE /internal/radar/clusters/{id}/members/{evidence_id}
POST /internal/radar/clusters/{id}/opportunity
GET /internal/radar/opportunities/{id}
PATCH /internal/radar/opportunities/{id}
GET /internal/radar/links
POST /internal/radar/links
DELETE /internal/radar/links/{id}
长任务返回 202 Accepted + run_id,Next.js 轮询 radar_runs。
FastAPI 的 BackgroundTasks 适合小型响应后任务;重计算或多进程任务需要更完整的任务队列。第一版可以进程内执行,但必须持久化任务状态并能识别服务重启造成的中断。FastAPI Background Tasks
15. 原网站中的管理页面
页面必须放入现有管理区域,并沿用当前站点视觉和权限。
15.1 /radar/inbox
目标:审核单条需求证据。
- 左侧:原始标题、来源、作者、时间和上下文;
- 中间:AI 字段编辑器;
- 右侧:相似需求簇和模型信息;
- 操作:接受、修改后接受、拒绝、重新提取;
- 筛选:主题、来源、状态、信号、日期;
- 支持键盘快捷键。
15.2 /radar/clusters
每个需求簇显示:
- 名称;
- 目标用户;
- 核心问题;
- 成员数量;
- 独立作者和来源数量;
- 7/30 天出现次数;
- 付费与迁移信号;
- 代表性原文;
- 当前评分。
支持合并、拆分、移除成员和新增人工证据。
15.3 /radar/opportunities/[id]
机会卡回答:
- 谁遇到了问题?
- 问题在哪个流程发生?
- 当前怎样处理?
- 为什么不满意?
- 有多少独立证据?
- 是否出现付费、购买或迁移信号?
- 是否能够触达这些用户?
- 准备验证什么假设?
- 最小验证物是什么?
- 什么结果意味着继续或放弃?
同时显示关联的文章、验证页、组件和开发任务。
16. 与文章、组件和 MCP 的连接
16.1 文章
机会卡可以关联:
- 需求观察文章;
- 技术实现记录;
- 验证结果;
- 最终复盘。
Radar 只能创建“生成文章草稿”的任务,不能绕过现有文章发布流程自动公开。
16.2 动态组件与模板
当某个需求进入验证阶段,可以关联:
- 问题验证组件;
- 交互原型;
- 数据展示组件;
- 页面模板。
组件仍由原有的预览、审核和版本机制保存,Radar 只保存引用。
16.3 MCP
第一版新增只读工具:
radar_list_clusters
radar_get_cluster
radar_list_opportunities
radar_get_opportunity
radar_get_weekly_summary
第二阶段再增加有限写操作:
radar_review_evidence
radar_update_opportunity
radar_create_validation_task
radar_link_article
不提供:
radar_execute_sql
radar_run_arbitrary_crawler
radar_auto_publish_article
radar_auto_contact_users
这样以后可以在手机端询问:
最近一周有哪些重复出现、有行动信号,并且适合个人开发的问题?
MCP 返回审核后的需求簇及证据摘要,而不是未经处理的原始帖子。
17. 机会评分
自动统计:
- 独立作者数;
- 独立来源数;
- 最近 7/30 天次数;
- 明确购买、迁移和 workaround 数量;
- 最早和最近出现时间。
人工填写:
| 维度 | 权重 |
|---|---|
| 痛苦程度 | 20% |
| 重复程度 | 15% |
| 付费迹象 | 20% |
| 现有方案缺口 | 15% |
| 用户可触达性 | 15% |
| 个人匹配度 | 15% |
每项 0~5 分,换算成 0~100。
以下任一情况可以否决:
- 数据取得不合法或不稳定;
- 必须先建立大规模社群;
- 需要双边市场;
- 属于高风险专业领域;
- 一个人无法长期维护;
- 目标用户无法再次触达;
- 只有抱怨,没有任何行动迹象。
18. 部署方式
在现有服务器上运行两个进程:
next-web
radar-worker
如果当前使用 Docker Compose,新增 radar-worker 服务;如果使用进程管理器,则增加独立进程。
要求:
- Python 服务不绑定公网端口;
- Next.js 通过内网地址访问;
- 两个服务分别配置密钥;
- Python 服务设置 CPU 和内存限制;
- Playwright 单独限制并发;
- 数据库连接池设置较小上限;
- 日志包含统一
run_id。
如果原数据库是 SQLite:
- 开启 WAL;
- 缩短写事务;
- Worker 限制并发写;
- 避免 Next.js 和 Worker 长事务竞争;
- 定期备份数据库文件。
如果原数据库是 PostgreSQL 或 MySQL,直接使用原连接,但采用 Radar 专用账号。
19. 测试要求
19.1 不破坏原项目
必须验证:
- 原登录和文章功能不受影响;
- 非管理员无法访问 Radar 页面;
- 浏览器无法获得 Python 服务密钥;
- Python 账号无法修改非
radar_*表; - Radar 失败不会导致主站不可用;
- 原有构建、Lint 和测试继续通过。
19.2 后端
覆盖:
- GitHub Issue 转换;
- 文本标准化和哈希;
- 重复采集幂等;
- 增量游标提交;
- Pydantic 输出校验;
- 引用必须存在于原文;
- 人工审核结果不会被覆盖;
- 相似度建议;
- 合并与拆分事务;
- 任务状态恢复。
19.3 前端
覆盖:
- 管理员守卫;
- 审核和修改;
- 筛选、分页和轮询;
- 合并、拆分和撤销;
- 长原文展示;
- 关联文章和组件;
- Worker 不可用时的错误提示。
集成测试使用固定 Fixture,不调用真实 GitHub 或真实模型。重复运行完整流程两次,数据库记录不能翻倍。
20. 分阶段实施
阶段 0:接入审查
交付:
- 当前目录、数据库、ORM、认证、部署和 MCP 的审查结果;
- Radar 的实际文件落点;
- 数据迁移方案;
- 原项目风险清单。
验收:没有创建代码前,已经明确哪些能力复用、哪些模块新增。
阶段 1:采集纵向打通
交付:
radar_topics、radar_sources、radar_runs、radar_documents;- Python 服务骨架;
Collector协议;- GitHub Issue Collector;
- 文本标准化、哈希和幂等写入;
- 手动运行命令;
- 单元与集成测试。
验收:同一批 Issue 执行两次不产生重复记录,主站功能不受影响。
阶段 2:AI 需求提取
交付:
radar_extractions、radar_evidence;- Pydantic Schema;
- Prompt 与版本机制;
- 原文引用校验;
- 批处理和失败重试。
验收:错误结构不能入库;每条证据可以跳回原文。
阶段 3:原站审核页面
交付:
- Next.js 内部代理;
- 管理员守卫;
/radar/inbox;- 修改、接受、拒绝和重新提取;
- 审计日志。
验收:能够连续审核 50 条证据,所有修改可以追踪到管理员。
阶段 4:相似需求与需求簇
交付:
- Embedding;
- Top-K 相似召回;
- 需求簇页面;
- 合并、拆分和撤销。
验收:使用人工标注的相似/不相似样本校准阈值,不出现未经确认的自动正式归类。
阶段 5:机会卡与原项目关联
交付:
- 评分;
- 机会卡;
radar_links;- 关联文章、验证页、组件和开发任务。
验收:生成 3 张有原文证据的机会卡,并能打开关联对象。
阶段 6:MCP 接入
交付:
- 只读工具;
- 权限检查;
- 有界结果与分页;
- 原文链接和证据摘要。
验收:通过手机端模型查询需求簇时,不需要传输全部原文,也不能绕过审核执行高风险操作。
21. 第一版完成定义
- 复用原网站登录、数据库和管理入口;
- Python Worker 与 Next.js 独立运行;
- 至少接通一个真实数据源;
- 保存 300 条以上可追溯原文;
- 提取 50 条以上需求证据;
- 至少人工审核 30 条;
- 形成 5 个以上需求簇;
- 形成 3 张机会卡;
- 选出 1 个验证问题;
- 至少关联一篇文章或一个验证页面;
- MCP 可以只读查询审核后的结果;
- 重复任务不会重复写入;
- 模型升级不会覆盖历史审核;
- Worker 故障不会影响主站阅读;
- 任意结论都能回到原始链接。
22. Codex 的第一条实施指令
后续不要直接把整篇文章交给 Codex 并要求“一次性完成”。第一条指令应当是:
阅读《在现有个人网站中实现“需求雷达”》技术方案。先审查当前仓库的 Next.js 结构、数据库、ORM、身份认证、管理页面、部署方式和 MCP 位置,输出 Radar 的实际接入方案与需要修改的文件清单。当前阶段不要新增依赖、不要创建数据表、不要写功能代码。
确认接入方案后,第二条指令才是:
根据已确认的接入方案实施阶段 1,只完成 Radar 基础数据模型、Python 服务骨架和 GitHub Issue 幂等采集。复用现有数据库迁移方式,不实施 AI 提取、Embedding、审核页面或 MCP 工具。完成后运行相关测试并报告仍未实现的阶段。
这样可以先让 Codex 理解原项目,再按阶段开发,避免它根据通用文章另外搭建一套网站、账号和数据库。
需求雷达最终应该成为原网站的一项内部能力:公开文章负责沉淀思考,验证页面负责接触真实用户,组件负责快速试验,MCP 负责让成熟大模型读取审核后的上下文,而 Python Worker 负责处理不适合放进主站请求生命周期的采集和分析任务。