跳到内容
Mortal

欲买桂花同载酒,终不似,少年游。 故人已远,山水依旧。

  • 随笔
  • 絮语
  • 小记
  • 归档
  • 关于
© 2026 Mortal认真写字,也认真生活。

一次真实网站改版:5 个 Flash模型 CC 实测

更新于:2026-09-10#模型#AI#价格共 6,646 字约 21 分钟

最近拿自己的一个真实网站修改任务,顺手测试了一下几个模型在 Claude Code 里的实际表现。

这次没有跑 Benchmark,也没有准备专门的测试题,就是让几个模型去完成同一个真实网站改版任务。

测试的方案一共 5 个:

  • GLM5.3-Flash
  • DeepSeek-V4-Flash
  • Qwen3.8-Flash API
  • Qwen3.8-Flash Token Plan
  • GPT5.6-Luna-Max

测试命令:

Text
UTF-8|1 Lines|
把Github上仓库,aluvien/yezi-blog 同步到本地。
Text
UTF-8|2710 Lines|
请先完整阅读当前相关代码,再实施修改。
 
不要凭空重建一套平行系统,不要为了“统一”而推倒现有成熟模块,不要做与本需求无关的大规模重构。
 
本次任务目标是:
 
完整升级「小记」系统
 
在保留现有:
 
* 随笔
* 絮语
* 归档
* 关于
 
等现有产品结构的基础上,把当前经典导航中的「小记」升级成一个新的聚合型页面:
 
/life
 
新的「小记」包含:
 
* 全部
* 生活节点
* 作品
* GitHub
* 收藏引用
 
同时新增:
 
* 独立生活节点数据模型
* 从絮语提取生活节点
* GitHub Repository 登记与同步
* 作品与 GitHub 仓库关联
* 收藏引用增强
* 小记统一时间流
* 后台统一管理入口
 
⸻
 
一、必须遵守的产品导航
 
经典版网站导航必须继续保持:
 
随笔 / 絮语 / 小记 / 归档 / 关于
 
不得改成:
 
首页 / 文章 / 生活小记 / 关于
 
不得把现有导航体系重新设计掉。
 
最终导航关系:
 
随笔
→ /posts
絮语
→ /moments
小记
→ /life
归档
→ /archives
关于
→ /about
 
本次只改变「小记」对应的实际页面和内部功能。
 
⸻
 
二、最终产品语义
 
必须彻底统一现有历史命名。
 
1. 随笔
 
技术实体:
 
posts
Post
 
产品名称:
 
随笔
 
规范入口:
 
/posts
 
保持现有功能。
 
⸻
 
2. 絮语
 
技术实体:
 
moments
Moment
 
产品名称必须统一为:
 
絮语
 
规范入口:
 
/moments
 
以后 UI 中不要再把 moments 称为:
 
想法
 
例如:
 
原:
 
想法
发想法
还没有想法
 
应改成:
 
絮语
写絮语
还没有絮语
 
或者使用更自然的:
 
写一条
 
但栏目名称必须统一为:
 
絮语
 
注意:
 
絮语仍然是完全独立的一级栏目。
 
不得把絮语放进 /life。
 
⸻
 
3. 小记
 
新的规范页面:
 
/life
 
对外名称:
 
小记
 
小记是一个聚合型栏目。
 
其内部包括:
 
全部
生活节点
作品
GitHub
收藏引用
 
注意:
 
「小记」现在代表整个 /life 页面。
 
不再等同于 works。
 
⸻
 
4. 作品
 
技术实体继续保持:
 
works
Work
 
产品名称:
 
作品
 
但作品不再作为经典版一级导航。
 
它成为:
 
小记 → 作品
 
的一种内容类型。
 
不要因为页面调整而重命名:
 
works
Work
listWorks()
createWork()
 
等技术实体。
 
⸻
 
5. GitHub
 
新增:
 
github_repositories
 
用于登记和展示用户自己的 GitHub Repository。
 
产品名称:
 
GitHub
 
作为:
 
小记 → GitHub
 
的一种内容类型。
 
⸻
 
6. 收藏引用
 
继续基于现有:
 
reference_library
 
产品名称:
 
收藏引用
 
作为:
 
小记 → 收藏引用
 
的一种内容类型。
 
不要重新创建:
 
bookmarks
favorites
saved_urls
 
之类重复数据表。
 
⸻
 
三、最终信息架构
 
前台必须遵循:
 
随笔
└── posts
絮语
└── moments
小记
├── 全部
├── 生活节点
├── 作品
├── GitHub
└── 收藏引用
归档
关于
 
特别注意:
 
moments ≠ 小记
works ≠ 小记
 
而是:
 
moments = 絮语
works = 小记里的「作品」
/life = 小记
 
⸻
 
四、修改前必须阅读代码
 
修改前至少完整阅读并理解以下文件及调用关系。
 
数据库
 
src/lib/db/schema.ts
src/lib/db/migrations.ts
src/lib/db/types.ts
src/lib/db/moments.ts
src/lib/db/works.ts
src/lib/db/references.ts
src/lib/db/feed.ts
src/lib/db/fts.ts
 
以及实际数据库导出入口。
 
Server Actions / 服务层
 
src/lib/actions/moments.ts
src/lib/actions/works.ts
src/lib/actions/references.ts
src/lib/actions/posts.ts
src/lib/actions/sync.ts
src/lib/admin/deploy.ts
 
后台
 
src/components/admin/AdminNav.tsx
src/app/admin/(protected)/moments/**
src/app/admin/(protected)/works/**
src/app/admin/(protected)/references/**
src/components/admin/MomentForm.tsx
src/components/admin/WorkForm.tsx
src/components/admin/AdminReferenceAddButton.tsx
src/components/admin/ArticleReferenceDialog.tsx
src/components/admin/ArticleReferenceArchiveActions.tsx
 
前台
 
src/app/(site)/moments/page.tsx
src/app/(site)/works/page.tsx
src/app/(site)/references/page.tsx
src/app/(site)/memo/page.tsx
src/lib/site-navigation.ts
src/lib/home-feed.ts
 
以及:
 
* classic theme 相关组件
* MomentEntry
* ReferenceLibraryCard
* works 相关展示组件
 
API
 
检查:
 
src/app/api/v1/moments/**
src/app/api/v1/works/**
src/app/api/v1/references/**
src/lib/api.ts
 
以及实际存在的 API 文件。
 
⸻
 
五、现有功能必须保留
 
moments
 
当前絮语已有能力必须保留:
 
* 文本
* 图片
* 标签
* 城市位置
* 音乐
* 评论
* 点赞
* 浏览量
* 编辑
* 删除
* FTS 搜索
 
不要为了生活节点功能破坏这些能力。
 
⸻
 
reference_library
 
现有引用系统已有:
 
* URL
* canonical URL
* 标题
* 来源
* 作者
* 发布时间
* 封面
* 描述
* 摘要
* key points
* 分类
* 标签
* article references
* reader archive
* archive jobs
* canonical URL 去重
 
这些都必须保留。
 
尤其不得破坏:
 
article_references
reference_library
article_reference_archives
article_reference_archive_jobs
 
之间现有关系。
 
现有文章引用快照机制必须继续存在。
 
⸻
 
六、前台导航修改
 
修改:
 
src/lib/site-navigation.ts
 
经典版导航最终必须变成:
 
随笔 → /posts
絮语 → /moments
小记 → /life
归档 → /archives
关于 → /about
 
其中仅把原来的:
 
小记 → /works
 
改为:
 
小记 → /life
 
不得删除经典导航结构。
 
⸻
 
七、历史路由兼容
 
/memo
 
当前:
 
/memo → /works
 
应修改为:
 
/memo → /life
 
因为 /life 才是新的「小记」页面。
 
⸻
 
/works
 
旧:
 
/works
 
必须保留兼容。
 
建议:
 
/works → /life?type=works
 
使用永久重定向或与项目当前路由策略一致的兼容方式。
 
不得直接造成旧链接 404。
 
⸻
 
/references
 
现有:
 
/references
 
可以继续作为兼容入口。
 
建议可保留现有独立页面,或者后续重定向到:
 
/life?type=references
 
本轮优先保证兼容,不要求强制删除原独立页面。
 
⸻
 
八、后台新的信息架构
 
当前后台已有:
 
仪表盘
文章
想法
数据
页面
设置
 
需要清理。
 
新的主要结构建议:
 
仪表盘
文章
絮语
小记
数据
设置
 
其中:
 
絮语
 
继续保留独立入口:
 
/admin/moments
 
或者迁移到更规范位置,但不要强制合并进小记。
 
对外名称统一:
 
絮语
 
不要再显示:
 
想法
 
⸻
 
小记
 
新增一级后台入口:
 
小记
 
进入:
 
/admin/life
 
其顶部 Tabs:
 
生活节点
作品
GitHub
收藏引用
 
推荐路由:
 
/admin/life/milestones
/admin/life/works
/admin/life/github
/admin/life/references
 
/admin/life
 
默认跳转:
 
/admin/life/milestones
 
抽取共享:
 
LifeAdminTabs
 
或类似组件。
 
要求:
 
* 当前 Tab active 明显
* 移动端可横向滚动或合理适配
* 不重复复制四套顶部结构
* 延续当前后台视觉风格
 
⸻
 
九、生活节点必须使用独立数据模型
 
此前不要使用:
 
moments.kind = milestone
 
方案。
 
生活节点必须新增独立数据表:
 
life_events
 
因为:
 
絮语
 
是当时留下的原始记录,
 
而:
 
生活节点
 
是后来整理的人生时间索引。
 
一条絮语可以被提取成生活节点,但原始絮语必须继续保留。
 
⸻
 
十、life_events 数据表
 
新增:
 
life_events
 
建议字段至少包括:
 
id
title
content
occurred_at
date_precision
cover
images
tags
location
source_type
source_moment_id
created_at
updated_at
 
根据当前数据库现有字段风格调整 SQLite 类型。
 
⸻
 
十一、生活节点日期设计
 
必须区分:
 
created_at
 
和:
 
occurred_at
 
含义:
 
created_at
= 什么时候录入博客
occurred_at
= 事情实际什么时候发生
 
例如:
 
2026 年录入:
 
2002 年第一次做网站
 
时间线应显示到:
 
2002
 
而不是 2026。
 
⸻
 
十二、date_precision
 
支持:
 
day
month
year
 
例如:
 
2002
2025-07
2026-09-03
 
前端不得为了存储方便强制把:
 
2002
 
展示成:
 
2002-01-01
 
数据库可以内部采用统一日期格式,但 UI 必须尊重精度。
 
⸻
 
十三、生活节点来源
 
source_type:
 
manual
moment
 
手动添加
 
source_type = manual
source_moment_id = NULL
 
从絮语提取
 
source_type = moment
source_moment_id = moments.id
 
⸻
 
十四、source_moment_id 外键
 
建议:
 
FOREIGN KEY(source_moment_id)
REFERENCES moments(id)
ON DELETE SET NULL
 
删除原始絮语时:
 
* 不得删除生活节点
* 仅断开来源关系
 
因为生活节点已经是独立整理好的记录。
 
⸻
 
十五、防止重复提取
 
默认:
 
一条絮语只允许直接提取成一个生活节点。
 
建议给非 NULL:
 
source_moment_id
 
建立唯一约束或 partial unique index。
 
如果 SQLite 当前版本和项目结构适合,可使用:
 
UNIQUE INDEX WHERE source_moment_id IS NOT NULL
 
避免重复点击产生多个节点。
 
⸻
 
十六、生活节点后台
 
后台:
 
/admin/life/milestones
 
顶部至少提供:
 
+ 添加生活节点
从絮语提取
 
列表按照:
 
occurred_at DESC
 
排序。
 
不是:
 
created_at DESC
 
建议展示:
 
* 日期
* 日期精度
* 标题
* 内容摘要
* 标签
* 图片数量
* 位置
* 来源
* 编辑
* 删除
 
⸻
 
十七、手动创建生活节点
 
支持填写:
 
标题
内容
发生日期
日期精度
封面
图片
标签
位置
 
如项目已有适合复用的:
 
* 图片上传
* 标签输入
* 位置
* 音乐
* Markdown / textarea
 
优先复用现有组件。
 
不要复制大量 MomentForm 代码。
 
⸻
 
十八、从絮语提取生活节点
 
这是本次核心功能之一。
 
后台提供:
 
从絮语提取
 
点击打开絮语选择器。
 
默认优先显示:
 
尚未提取
 
支持:
 
全部
未提取
已提取
 
以及搜索。
 
每条显示:
 
* 时间
* 内容摘要
* 图片
* 标签
* 是否已提取
 
⸻
 
十九、提取流程
 
选择絮语后:
 
不要直接静默创建生活节点。
 
必须进入整理界面。
 
根据原絮语自动预填:
 
content
occurred_at
images
tags
location
 
标题可以:
 
* 留空让用户填写
* 或通过现有 AI 能力生成建议
 
但不得未经用户确认直接覆盖。
 
用户可以修改:
 
* 标题
* 内容
* 日期
* 日期精度
* 图片
* 标签
* 位置
 
确认后才创建:
 
life_events
 
同时:
 
source_type = moment
source_moment_id = 原 moments.id
 
原絮语保持完全不变。
 
⸻
 
二十、絮语后台增加提取入口
 
现有絮语列表操作:
 
查看
编辑
删除
 
增加:
 
提取节点
 
如果已经提取:
 
已提取节点
 
并可以点击跳转到对应:
 
/admin/life/milestones/{id}/edit
 
或实际编辑路径。
 
⸻
 
二十一、前台生活节点来源展示
 
如果生活节点来自絮语,可以轻量显示:
 
来自一条 2026-09-03 的絮语
 
链接:
 
/moments#moment-{id}
 
如果当前 moment DOM anchor 命名不同,则复用现有规则。
 
不要重复完整展示原絮语正文。
 
⸻
 
二十二、生活节点产品语义
 
代码和 UI 必须遵循:
 
絮语
= 当时留下的原始记录
生活节点
= 对经历整理后的时间索引
 
不得因为提取:
 
* 删除原絮语
* 隐藏原絮语
* 修改原絮语类型
* 将原絮语迁移到 life_events
 
提取是:
 
复制 + 整理 + 建立来源关系
 
不是:
 
移动
 
⸻
 
二十三、数据库 migration
 
当前项目 migration 已有连续版本管理。
 
必须先检查:
 
src/lib/db/migrations.ts
 
确认当前最新版本。
 
然后新增下一版本。
 
不要:
 
* 修改已经发布的旧 migration
* 只改 BASE_SCHEMA_SQL
* 直接假设 migration 版本号
 
新增表和字段必须:
 
1. 修改 base schema
2. 新增 migration
3. 更新 types
4. 更新 DAO
5. 更新 tests
6. 检查 schema version
 
⸻
 
二十四、life_events DAO
 
新增独立 DAO,例如:
 
src/lib/db/life-events.ts
 
或者遵循项目命名规则。
 
至少实现:
 
createLifeEvent()
updateLifeEvent()
deleteLifeEvent()
getLifeEvent()
listLifeEvents()
countLifeEvents()
getLifeEventBySourceMoment()
 
需要分页。
 
避免列表页 N+1。
 
⸻
 
二十五、作品 works 保持独立
 
现有:
 
works
 
不重构成 life_events。
 
作品和人生事件不是一个数据模型。
 
作品继续支持现有:
 
* title
* description
* cover
* link
* sort_order
 
如果未来有必要可以扩展:
 
published_at
tags
featured
 
但本轮不是必须。
 
⸻
 
二十六、新增 GitHub Repository 模型
 
新增:
 
github_repositories
 
建议字段:
 
id
owner
name
full_name
repo_url
description
homepage
primary_language
topics
stars
forks
license
default_branch
archived
visibility
github_created_at
github_updated_at
pushed_at
custom_title
custom_description
cover
tags
featured
registered_at
synced_at
sync_status
sync_error
 
⸻
 
二十七、GitHub 唯一标识
 
使用:
 
full_name
 
例如:
 
aluvien/yezi-blog
 
并:
 
UNIQUE(full_name)
 
避免重复登记。
 
⸻
 
二十八、GitHub 仓库登记
 
后台:
 
/admin/life/github
 
提供:
 
+ 登记 GitHub 仓库
 
允许输入:
 
https://github.com/aluvien/yezi-blog
 
或者:
 
aluvien/yezi-blog
 
规范化:
 
owner = aluvien
name = yezi-blog
full_name = aluvien/yezi-blog
repo_url = https://github.com/aluvien/yezi-blog
 
必须验证:
 
* GitHub owner 合法
* repo name 合法
* 必须是真正 GitHub Repo
* github.com 之外 URL 不得当作 GitHub Repo
* 不允许重复 full_name
 
⸻
 
二十九、GitHub 元数据同步
 
新增专门 Repository metadata service。
 
当前项目已有:
 
syncLatestGithubAction
 
但它属于:
 
服务器部署 / 代码更新
 
不得复用成 Repository 元数据同步。
 
新功能建议命名:
 
syncGithubRepositoryMetadata()
syncAllGithubRepositoryMetadata()
 
明确与 deploy sync 区分。
 
⸻
 
三十、GitHub 同步字段
 
至少同步:
 
name
full_name
description
homepage
stars
forks
primary_language
topics
license
archived
visibility
default_branch
created_at
updated_at
pushed_at
 
同步成功:
 
sync_status = success
synced_at = now
sync_error = null
 
失败:
 
sync_status = error
sync_error = 人类可理解的错误
 
批量同步:
 
* 单个失败不得导致全部中止
* 返回成功 / 失败统计
 
⸻
 
三十一、GitHub Token
 
使用环境变量:
 
GITHUB_TOKEN
 
禁止:
 
* 写死 token
* 打印 token
* 返回 token 到前端
 
没有 Token 时:
 
* 公共仓库可以尝试 GitHub 公共 API
* 正确处理 rate limit
* 后台给出明确错误
 
⸻
 
三十二、GitHub 手动数据优先
 
自动同步字段和手工字段必须分离。
 
自动字段:
 
description
homepage
stars
forks
primary_language
topics
license
...
 
手动字段:
 
custom_title
custom_description
cover
tags
featured
 
展示:
 
custom_title || name
custom_description || description
 
GitHub 同步绝对不得覆盖:
 
custom_title
custom_description
cover
tags
featured
 
⸻
 
三十三、作品与 GitHub 关联
 
新增:
 
work_github_repositories
 
至少包含:
 
work_id
repository_id
created_at
 
推荐:
 
PRIMARY KEY(work_id, repository_id)
 
允许:
 
* 一个作品无仓库
* 一个作品一个仓库
* 一个作品多个仓库
* 一个仓库根据需求关联多个作品
 
不要在:
 
works
 
中增加:
 
github_repo_id
 
这种单关系设计。
 
⸻
 
三十四、作品后台
 
在作品编辑页面增加:
 
关联 GitHub 仓库
 
支持:
 
0 个
1 个
多个
 
优先使用多选控件。
 
不要破坏现有 WorkForm。
 
⸻
 
三十五、收藏引用继续使用 reference_library
 
禁止新增:
 
bookmarks
web_bookmarks
favorites
saved_pages
 
作为平行收藏系统。
 
继续使用:
 
reference_library
 
⸻
 
三十六、reference_library 增强
 
新增字段:
 
note
status
favorite
saved_at
last_checked_at
 
其中:
 
note
 
必须实现。
 
含义:
 
为什么收藏这个资料
准备如何使用
它与什么内容有关
 
示例:
 
博客升级 Next.js 16 缓存体系时重点参考。
 
⸻
 
三十七、收藏状态
 
建议:
 
inbox
read
archived
 
如果为了控制本轮复杂度,也可以:
 
inbox
archived
 
但 schema 设计要易于后续扩展。
 
⸻
 
三十八、发布时间和收藏时间必须分开
 
published_at
 
表示:
 
原网页发布时间
saved_at
 
表示:
 
我什么时候收藏
 
小记时间流中的收藏项目排序:
 
优先使用:
 
saved_at
 
绝对不要使用 published_at 替代收藏时间。
 
⸻
 
三十九、URL canonical normalization 增强
 
保留现有 canonical 逻辑。
 
在此基础上谨慎去除常见 tracking 参数:
 
utm_source
utm_medium
utm_campaign
utm_term
utm_content
fbclid
gclid
 
不要暴力删除所有 query 参数。
 
对于:
 
spm
from
ref
 
等参数需要谨慎。
 
部分网站使用 query 参数确定实际内容。
 
现有:
 
X / Twitter
 
专门 URL normalization 逻辑必须保留。
 
新增测试覆盖:
 
* utm 去除
* hash 去除
* 内容型 query 保留
* X URL
* 同 canonical 去重
 
⸻
 
四十、通用 reference relations
 
现有:
 
article_references
 
继续负责:
 
文章中的引用快照
 
不要删除。
 
另新增:
 
reference_relations
 
用于更广泛关联。
 
建议:
 
id
reference_id
target_type
target_id
context
created_at
 
支持:
 
post
life_event
work
github_repository
 
如果 moment 也有明确需求,可以支持:
 
moment
 
但优先保持实际使用场景。
 
⸻
 
四十一、引用关系语义
 
例如一个 Next.js 官方文档可以关联:
 
文章
作品
GitHub Repository
生活节点
 
其中:
 
article_references
 
仍然是“文章实际发表时引用的稳定快照”。
 
而:
 
reference_relations
 
表示:
 
这个资料与哪个内容有关
 
职责不可混淆。
 
⸻
 
四十二、引用后台增强
 
收藏引用列表可以增加:
 
备注 note
状态
收藏标记
关联内容
收藏时间
 
例如:
 
关联内容
文章 2
作品 1
GitHub 1
生活节点 1
 
点击可以查看具体关系。
 
必须避免明显 N+1。
 
优先:
 
* JOIN 聚合
* 批量查询
* Map hydrate
 
不要每张卡片单独请求数据库。
 
⸻
 
四十三、引用搜索
 
当前如果仍使用:
 
instr(lower(...))
 
可以暂时保留。
 
如果本轮实现 fts_references 成本合理,可复用现有 FTS5 trigram 架构。
 
搜索:
 
title
source_name
author
description
summary
key_points
category
tags
note
 
如果增加 FTS:
 
* 必须版本化
* 必须 triggers
* migration 支持 rebuild
* 不影响 posts / moments FTS
 
如果本轮变更过大:
 
可以将 reference FTS 明确标记为:
 
后续优化
 
不要为了 FTS 阻塞核心功能。
 
⸻
 
四十四、新增前台 /life 页面
 
新增:
 
src/app/(site)/life/page.tsx
 
或按项目真实路由结构实现。
 
页面名称必须:
 
小记
 
不要叫:
 
生活小记
 
作为用户界面主标题。
 
因为经典导航名称已经确定为:
 
小记
 
可以使用类似副标题:
 
记录经历,也留下做过的事。
 
具体文案保持与 classic theme 风格一致。
 
⸻
 
四十五、小记 Tabs
 
/life 包含:
 
全部
生活节点
作品
GitHub
收藏引用
 
建议:
 
/life?type=all
/life?type=milestones
/life?type=works
/life?type=github
/life?type=references
 
如果项目路由风格更适合子路由,也可以采用子路由。
 
优先:
 
* 简单
* 可分享
* 可后退
* SSR 友好
* 与项目现有风格统一
 
⸻
 
四十六、絮语不要放入 /life
 
再次强调:
 
/moments
 
继续独立。
 
/life 中禁止增加:
 
絮语
 
Tab。
 
最终:
 
/life
├── 全部
├── 生活节点
├── 作品
├── GitHub
└── 收藏引用
 
⸻
 
四十七、小记“全部”时间流
 
不要简单:
 
const items = [
  ...allLifeEvents,
  ...allWorks,
  ...allGithubRepos,
  ...allReferences,
].sort(...)
 
然后一次性全部加载。
 
必须参考现有:
 
src/lib/db/feed.ts
src/lib/home-feed.ts
 
现有架构思想:
 
UNION ALL
只查询轻量 type / id / time
数据库排序
LIMIT/OFFSET
批量 hydrate
 
新的 Life Feed 应沿用同样设计。
 
⸻
 
四十八、Life Feed 类型
 
可以定义:
 
type LifeFeedItem =
  | LifeEventFeedItem
  | WorkFeedItem
  | GithubRepositoryFeedItem
  | ReferenceFeedItem
 
每种 item 保留:
 
type
id
sort_time
 
然后根据 type 批量 hydrate。
 
⸻
 
四十九、Life Feed 时间来源
 
必须使用符合产品语义的时间。
 
生活节点
 
occurred_at
 
作品
 
如果当前没有真实发布日期:
 
第一版使用:
 
created_at
 
但不要使用:
 
sort_order
 
作为时间。
 
后续可扩展:
 
published_at
 
GitHub
 
使用:
 
registered_at
 
表示:
 
什么时候登记到自己的小记
 
不要使用:
 
synced_at
 
作为生活时间线时间。
 
收藏引用
 
使用:
 
saved_at
 
不要使用:
 
published_at
 
⸻
 
五十、Life Feed 查询
 
建议新增:
 
src/lib/db/life-feed.ts
 
或遵循当前命名。
 
使用类似:
 
SELECT 'life_event', id, occurred_at AS sort_time
FROM life_events
UNION ALL
SELECT 'work', id, created_at AS sort_time
FROM works
UNION ALL
SELECT 'github_repository', id, registered_at AS sort_time
FROM github_repositories
UNION ALL
SELECT 'reference', id, saved_at AS sort_time
FROM reference_library
ORDER BY sort_time DESC
LIMIT ? OFFSET ?
 
实际 SQL 按当前 SQLite/schema 结构优化。
 
然后分别批量:
 
getLifeEventsByIds
getWorksByIds
getGithubRepositoriesByIds
getReferencesByIds
 
最后恢复统一顺序。
 
⸻
 
五十一、单独 Tab 分页
 
以下所有 Tab:
 
生活节点
作品
GitHub
收藏引用
 
都必须支持合理分页。
 
不要一次性加载无限量数据。
 
复用当前:
 
* pagination
* query params
* page size
 
设计风格。
 
⸻
 
五十二、前台生活节点展示
 
生活节点建议采用:
 
时间轴
 
而不是普通作品 Card。
 
日期精度:
 
2026-09-03
2025-07
2002
 
必须按实际 precision 展示。
 
内容建议:
 
年份 / 日期
标题
内容
图片
标签
位置
来源絮语
 
保持简洁。
 
⸻
 
五十三、前台作品展示
 
继续复用现有作品展示能力。
 
但现在属于:
 
/life?type=works
 
不要大幅重写视觉设计。
 
在“全部”流中可以使用精简版卡片。
 
⸻
 
五十四、GitHub 前台展示
 
Repository 卡片建议展示:
 
名称
描述
语言
stars
forks
topics
最后 pushed 时间
GitHub 链接
homepage
 
但避免变成完整 GitHub Dashboard。
 
用户真正的自定义内容:
 
custom_title
custom_description
cover
tags
featured
 
应优先显示。
 
⸻
 
五十五、收藏引用前台
 
复用现有:
 
ReferenceLibraryCard
 
尽量不要复制第二套。
 
根据 /life 场景适配:
 
note
saved_at
favorite
category
tags
 
公开前端不要泄露:
 
archive private body
archive job
内部同步错误
后台私有字段
 
⸻
 
五十六、API
 
现有 API 必须保持兼容。
 
不要因为新功能破坏:
 
/api/v1/moments
/api/v1/works
/api/v1/references
 
新增:
 
/api/v1/life-events
 
如果现有 API 命名使用别的习惯,则遵循项目约定。
 
新增 GitHub API:
 
/api/v1/github-repositories
 
如有必要新增:
 
/api/v1/life
 
作为统一 feed API。
 
⸻
 
五十七、公开 serializer
 
更新:
 
src/lib/api.ts
 
增加:
 
publicLifeEvent()
publicGithubRepository()
 
如果增加 Life Feed:
 
增加:
 
publicLifeFeedItem()
 
必须明确过滤私有字段。
 
GitHub 不得公开:
 
sync_error
 
如果其内容可能包含内部错误信息。
 
Reference 不得因为 life API 暴露 private archive 数据。
 
⸻
 
五十八、后台 Server Actions
 
新增或扩展:
 
life event actions
github repository actions
reference relation actions
 
所有写操作必须继续使用项目已有:
 
* admin 权限检查
* 输入 validation
* revalidatePath
* 错误处理
 
不要创建绕过现有权限体系的新接口。
 
⸻
 
五十九、安全要求
 
所有后台新增操作:
 
* 必须验证管理员身份
* 不相信客户端传入的 id
* GitHub URL 必须严格解析
* 防止任意 URL 被当 GitHub API 请求
* 不允许 SSRF
* 不允许用户控制服务端 fetch 任意 host
* 不把 GitHub token 返回客户端
* 不把服务器内部异常 stack 暴露给页面
 
引用抓取继续使用当前安全约束。
 
⸻
 
六十、缓存要求
 
检查当前:
 
* revalidate
* no-store
* unstable cache
* API cache
 
策略。
 
管理后台:
 
优先保证实时一致性。
 
公开页面:
 
按现有项目策略处理。
 
新增/编辑/删除后必须正确:
 
revalidate /life
revalidate 对应 Tab
 
同时保持:
 
/moments
/works
/references
 
兼容页面缓存正确。
 
⸻
 
六十一、删除行为
 
删除生活节点
 
不得删除来源絮语。
 
删除来源絮语
 
life_events.source_moment_id
 
应:
 
SET NULL
 
生活节点继续存在。
 
删除 GitHub Repository
 
正确处理:
 
work_github_repositories
reference_relations
 
不要留下脏关系。
 
删除 Work
 
正确处理 work-repository relation。
 
删除 Reference
 
保留当前引用系统原有语义。
 
不要因为新增 relation 改坏:
 
article_references
 
快照机制。
 
⸻
 
六十二、后台 Dashboard
 
当前后台已经有:
 
* Articles
* Moments
* Works
* References
* Comments
* Views
* Likes
* Attachments
 
更新显示名称:
 
Moments → 絮语
 
增加:
 
生活节点
GitHub
 
Works 对外:
 
作品
 
References:
 
收藏引用
 
不要为了小记聚合把各统计全部合成一个数字。
 
可以增加一个:
 
小记
 
聚合统计,但必须保留分项统计可见。
 
⸻
 
六十三、页面 Meta / SEO
 
统一页面 title。
 
/moments
 
絮语
 
不要再:
 
想法
 
/life
 
小记
 
/works 兼容页
 
若 redirect,无需独立重复 SEO。
 
/references
 
保留现有或根据兼容策略处理。
 
⸻
 
六十四、Classic Theme
 
重点检查 classic theme。
 
因为当前:
 
小记
 
历史上实际指向:
 
works
 
本次必须清理。
 
Classic 导航:
 
随笔
絮语
小记
归档
关于
 
其中:
 
小记 → /life
 
Classic 现有:
 
ClassicMemoPage
 
如果它本质上只是 works 页面:
 
不要继续把它当成完整小记页面。
 
可以:
 
* 重构为 /life 的某个作品 Section
* 或保留为作品组件
* 或重新抽取
 
但不得让:
 
works
 
继续拥有:
 
生活小记
 
的页面语义。
 
⸻
 
六十五、现代主题
 
如果 modern theme 当前导航不同,可以在不破坏其设计的情况下适配新 /life。
 
但此次最重要的产品约束是:
 
经典版五项导航必须保持不变。
 
不要为了 modern theme 改坏 classic。
 
⸻
 
六十六、可访问性
 
新增:
 
* Tabs
* Dialog
* GitHub form
* 时间线
* 选择絮语
* 多选 Repository
 
必须检查:
 
* keyboard navigation
* focus
* aria-current
* aria-label
* button type
* form label
* dialog focus trap
* 图片 alt
* 色彩不能是唯一状态表达方式
 
⸻
 
六十七、移动端
 
重点检查:
 
/life
/admin/life/**
 
要求:
 
* Tab 小屏可横向滚动
* 时间线不溢出
* GitHub repo 长 full_name 正确换行
* URL 不撑爆 Card
* Tags 换行
* 后台操作按钮不挤压
* modal 在窄屏可正常使用
* 图片布局正常
 
⸻
 
六十八、性能
 
重点避免:
 
N+1
全量加载
JS 端全量 sort
每张卡片单独查关系
每次 render 请求 GitHub
 
GitHub 数据必须:
 
后台同步到数据库
前台读取数据库快照
 
绝对不要前台访问 /life 时实时调用 GitHub API。
 
⸻
 
六十九、GitHub 同步不进入页面渲染关键路径
 
GitHub API 失败时:
 
/life
 
仍然必须正常打开。
 
前端显示数据库最近一次成功同步结果。
 
管理员可手动:
 
同步
 
GitHub 外部服务不可用不应导致站点不可用。
 
⸻
 
七十、测试
 
必须补充或更新测试。
 
至少覆盖:
 
life_events
 
* create
* update
* delete
* source moment
* source moment delete SET NULL
* duplicate extraction prevention
* date precision
* pagination
 
提取絮语
 
* 原 moment 不变
* life_event 正确创建
* 来源关系正确
* 已提取不能重复创建
 
GitHub parser
 
* full URL
* owner/repo
* invalid host
* invalid repo
* duplicate
 
GitHub sync
 
* success
* 404
* rate limit
* invalid token
* API error
* custom fields 不被覆盖
 
Works ↔ GitHub
 
* 关联
* 多仓库
* 删除关系
* 删除 repo
* 删除 work
 
References
 
* tracking params normalization
* canonical 去重
* note
* relation
 
Life Feed
 
* 混合排序
* pagination
* 时间字段正确
* hydrate 后顺序不乱
 
⸻
 
七十一、迁移兼容
 
部署到已有数据库时必须:
 
自动 migration
 
不能要求用户:
 
* 删除数据库
* 手工重建
* 清空数据
 
当前:
 
* posts
* moments
* works
* references
* comments
* metrics
 
数据必须保留。
 
⸻
 
七十二、禁止事项
 
不要:
 
1. 把 moments 改名成 whispers
2. 把 works 改名成 memos
3. 把 reference_library 重做成 bookmarks
4. 把生活节点做成 moments.kind
5. 把絮语合并进 /life
6. 把经典导航改掉
7. 删除 /moments
8. 直接删除 /works 造成 404
9. 删除文章引用快照机制
10. 把 GitHub deploy sync 和 repo metadata sync 混在一起
11. 每次前端渲染实时请求 GitHub
12. 大规模重构与本需求无关代码
13. 修改历史 migration
14. 为了 UI 命名修改数据库核心技术实体
15. 创建重复的收藏系统
16. 在 JS 内加载全部小记数据再 sort
17. 引入明显 N+1
18. 破坏 Next.js 当前版本兼容性
19. 输出 secret/token
20. 静默吞掉 GitHub 同步错误
 
⸻
 
七十三、推荐实施顺序
 
严格建议按以下顺序实施。
 
Phase 1:命名与路由
 
先完成:
 
moments UI → 絮语
小记导航 → /life
/memo → /life
/works → /life?type=works
 
建立 /life 基础页面。
 
不要先删除旧页面。
 
⸻
 
Phase 2:数据库
 
新增:
 
life_events
github_repositories
work_github_repositories
reference_relations
 
扩展:
 
reference_library
 
新增正式 migration。
 
⸻
 
Phase 3:Types / DAO
 
实现:
 
* life events DAO
* GitHub DAO
* relation DAO
* Work ↔ repo DAO
* reference metadata 更新
* bulk hydrate
 
⸻
 
Phase 4:后台生活节点
 
实现:
 
/admin/life/milestones
 
包括:
 
* 手动添加
* 编辑
* 删除
* 从絮语提取
 
再给絮语后台加入:
 
提取节点
 
⸻
 
Phase 5:GitHub 管理
 
实现:
 
/admin/life/github
 
包括:
 
* 登记
* 编辑自定义字段
* 同步
* 批量同步
* 删除
* 状态展示
 
⸻
 
Phase 6:作品关联 GitHub
 
在现有作品编辑中加入多 Repository 关联。
 
⸻
 
Phase 7:引用增强
 
实现:
 
* note
* status
* favorite
* saved_at
* relations
* URL normalization 增强
 
不要重写现有 article references。
 
⸻
 
Phase 8:前台 /life
 
实现:
 
全部
生活节点
作品
GitHub
收藏引用
 
⸻
 
Phase 9:统一 Life Feed
 
参考现有 feed 架构完成:
 
UNION ALL
数据库排序
分页
批量 hydrate
 
⸻
 
Phase 10:兼容与测试
 
完整检查:
 
* old URLs
* classic theme
* modern theme
* API
* mobile
* accessibility
* migrations
* build
* lint
* typecheck
* tests
 
⸻
 
七十四、验收标准
 
最终必须满足:
 
导航
 
经典导航仍然是:
 
随笔 / 絮语 / 小记 / 归档 / 关于
 
絮语
 
/moments
 
继续独立。
 
UI 不再称:
 
想法
 
小记
 
/life
 
正式成为新的小记首页。
 
包含:
 
全部
生活节点
作品
GitHub
收藏引用
 
生活节点
 
可以:
 
后台手动添加
 
也可以:
 
从絮语提取
 
提取后:
 
原絮语仍存在
 
作品
 
继续使用:
 
works
 
并可关联多个 GitHub Repository。
 
GitHub
 
可以:
 
* 登记
* 同步
* 自定义展示
* 查看同步错误
* 不影响前台可用性
 
收藏引用
 
继续使用:
 
reference_library
 
并支持:
 
note
status
favorite
saved_at
relation
 
全部
 
/life?type=all
 
按照正确业务时间混合展示:
 
生活节点
作品
GitHub
收藏引用
 
并有真正数据库分页。
 
兼容
 
旧:
 
/memo
/works
/references
 
不能无故 404。
 
数据
 
升级后旧数据库全部数据保留。
 
工程
 
必须通过项目实际存在的:
 
typecheck
lint
test
build
 
如果某条命令项目不存在,不要自行假造 package script。
 
⸻
 
七十五、最终交付要求
 
完成代码后,不要只告诉我“已完成”。
 
请输出一份实施报告,包含:
 
1. 修改了哪些文件
2. 新增了哪些文件
3. 新增了哪些 migration
4. 数据库结构变化
5. 路由变化
6. 后台变化
7. 前台变化
8. GitHub 同步实现方式
9. 絮语提取生活节点的完整流程
10. Reference 系统做了哪些增强
11. 旧地址如何兼容
12. 做了哪些测试
13. typecheck / lint / test / build 结果
14. 是否存在需要人工配置的环境变量
15. 是否还有未完成项
16. 是否存在需要我确认的设计选择
 
如果发现当前仓库实际实现和本提示词中的路径、字段或假设不完全一致:
 
优先服从当前 main 分支真实代码架构。
 
不要机械创建重复模块。
 
如果已有能力可以扩展:
 
优先扩展。
 
如果已有组件可以复用:
 
优先复用。
 
如果发现本需求会破坏已有:
 
* 安全
* 数据一致性
* migration
* API
* classic theme
* comments
* metrics
* FTS
 
必须采用兼容方案,而不是强行实现。
 
最终目标不是“代码改得最多”,而是:
 
用尽可能小、清晰、可维护的改动,把「小记」升级成一个真正记录经历、作品、代码和收藏资料的长期个人档案系统。

最终 5 个方案都完成了任务。

真正让我觉得有意思的,不是“谁能完成”,而是它们完成同一件事的过程差异非常大。

最少的只用了约 1110 万 Token,最多的跑到了 6584 万 Token;最快 25 分钟,最慢 107 分钟。

最后生成出来的东西也并不完全一样。

  • Gpt-Luna-Max
    Gpt-Luna-Max
  • Qwen3.8-Flash
    Qwen3.8-Flash
  • Deepseek-V4-Flash
    Deepseek-V4-Flash
  • Glm5.3-Flash
    Glm5.3-Flash

GLM 和 DeepSeek 的后台代码非常接近,Qwen 的实现方式和它们有一些区别,而 Luna 虽然这次耗时最长,但最终做出来的前端反而是几个方案里我觉得最好看的。

所以这次我主要想看看几个问题:

  • 同一个任务到底要消耗多少 Token
  • 要跑多长时间
  • 实际花多少钱
  • 最后做出来的代码和页面有什么区别

先看最终结果

模型 计费方式 总 Token 缓存命中 Token 缓存命中率 请求数 用时 本次成本
GLM5.3-Flash API / 限时半价 11,103,347 10,155,136 91.76% 121 35 分钟 ¥1.583498
DeepSeek-V4-Flash API / 闲时价 21,319,868 20,967,296 98.76% 190 25 分钟 ¥1.84
Qwen3.8-Flash API API / 原价 65,843,099 62,509,786 95.18% 299 87 分钟 ¥10.24
Qwen3.8-Flash Token Plan 订阅额度分摊 46,208,164 45,130,075 98.01% 未知 70 分钟 ≈ ¥2.38
GPT5.6-Luna-Max 订阅额度分摊 54,568,584 52,273,920 96.28% 未知 107 分钟 $0.20 / ≈ ¥1.34

单看这张表,几个特点已经很明显了。

GLM 最省 Token。

DeepSeek 最快。

Qwen API Token 消耗最高。

Luna 这次跑得最慢。

但如果把最后生成的代码和页面也放进来,情况又没有这么简单。


这次实际用了什么价格

本次测试的 API 价格并不是统一标准原价。

模型 输入价格 输出价格 缓存命中 其他费用 本次状态
Qwen3.8-Flash API ¥0.80/M ¥2.70/M ¥0.10/M 缓存创建 ¥1.25/M 原价
GLM5.3-Flash ¥0.40/M ¥1.40/M ¥0.115/M 无单独缓存创建价格 限时半价
DeepSeek-V4-Flash ¥1.50/M ¥4.50/M ¥0.05/M 无单独缓存创建价格 21:00~22:00 闲时价

另外两个是订阅方案:

  • Qwen3.8-Flash Token Plan:¥39/月
  • GPT5.6-Luna-Max:$20/月订阅额度

所以后面的成本对比,准确说应该是:

这一次实际使用环境下的成本。

并不是 GLM、DeepSeek、Qwen 三家标准原价的横向对比。

尤其 DeepSeek 这次刚好用了闲时价格,GLM 又是限时半价,而 Qwen API 是原价。


GLM:最省 Token,而且后台完成度没问题

GLM 这次一共用了:

text
UTF-8|1 Lines|
11,103,347 Token

耗时:

text
UTF-8|1 Lines|
35 分钟

这是 5 个方案里 Token 最少的。

DeepSeek 虽然更快,但用了 2132 万 Token,差不多是 GLM 的 1.92 倍。

所以从这次实际运行来看,GLM 最大的特点就是:

完成同样的事情,走的路径比较短。

至少没有出现特别夸张的重复读取、上下文膨胀或者长时间反复尝试。

最终后台代码也比较完整,没有因为 Token 少就出现明显的“省步骤”。

如果单纯看 Token 利用率,GLM 这次确实最好。


DeepSeek:最快,而且和 GLM 的后台实现很像

DeepSeek 这次只用了:

text
UTF-8|1 Lines|
25 分钟

是全部方案里最快的。

Token 消耗是:

text
UTF-8|1 Lines|
21,319,868

虽然比 GLM 多不少,但还是远低于 Qwen 和 Luna。

它的缓存命中率也很高:

text
UTF-8|1 Lines|
98.76%

这次还有一个很明显的感受。

我对比最终后台代码后发现,DeepSeek 和 GLM 的实现思路非常接近。

不仅是“都做出来了”,而是一些代码组织、业务处理和实现路径都比较像。

第一反应确实会让人怀疑:

GLM 和 DeepSeek 在 Coding 后训练、代码数据或者 Agent 优化方式上,会不会有一些类似的地方?

不过这个只能算观察,不能当结论。

一次任务完全不足以证明两家的后训练方式类似。

也可能只是因为这个后台任务本身最合理的实现方式就比较集中,两个模型都选择了相似的软件工程方案。

所以更准确的描述是:

在这一次任务里,GLM 和 DeepSeek 的后台输出风格和最终实现存在明显趋同性。

至于这种趋同性来自后训练方式、训练数据、模型偏好,还是单纯来自任务本身,目前没有办法判断。


Qwen:Token 消耗明显偏高

Qwen 是这次 Token 数据里最突出的一组。

Qwen API:

text
UTF-8|2 Lines|
65,843,099 Token
87 分钟

Qwen Token Plan:

text
UTF-8|2 Lines|
46,208,164 Token
70 分钟

尤其普通 API,Token 是全部方案里最高的。

和 GLM 相比:

text
UTF-8|1 Lines|
65.84M ÷ 11.10M ≈ 5.93 倍

也就是说,同一个任务,Qwen API 实际处理的 Token 接近 GLM 的 6 倍。

这也是这次测试里我觉得非常值得关注的一组数据。

因为 Qwen API 的缓存命中率其实并不低:

text
UTF-8|1 Lines|
95.18%

但最终依然累计跑出了超过 6500 万 Token。

从最终代码结果来看,我也没有看到足以解释这接近 6 倍 Token 差距的明显质量提升。

所以至少在这一次任务里,Qwen API 的主要问题可以很直接地概括为:

执行路径偏重,Token 消耗过大。

当然,仅凭一次任务还不能判断这是模型本身的问题,还是 Claude Code 接入方式、上下文管理、缓存策略或者请求方式造成的。

但对于真实使用者来说,最后付费看的就是实际结果,所以这个数字本身依然有参考价值。


Qwen Token Plan 比普通 API 明显更合理

比较有意思的是,同样是 Qwen3.8-Flash,两种调用方式的数据差距非常大。

Token Plan:

text
UTF-8|2 Lines|
46,208,164 Token
70 分钟

普通 API:

text
UTF-8|2 Lines|
65,843,099 Token
87 分钟

Token Plan 少用了大约:

text
UTF-8|1 Lines|
19,635,000 Token

同时快了:

text
UTF-8|1 Lines|
17 分钟

Token 大约下降了 30%。

缓存命中率也从:

text
UTF-8|1 Lines|
95.18%

提高到了:

text
UTF-8|1 Lines|
98.01%

这说明在 Claude Code 这种 Agent 场景里,底层模型一样,也不代表实际表现一样。

接入方式、上下文管理、缓存方式、请求策略,都可能明显影响最终消耗。

至少按照这一次结果,如果已经有 Qwen Token Plan,我会优先用 Plan,而不是再额外走普通 API。


Luna:最慢,但前端反而是这次最好看的

GPT5.6-Luna-Max 这次的数据其实并不好看。

总 Token:

text
UTF-8|1 Lines|
54,568,584

耗时:

text
UTF-8|1 Lines|
107 分钟

是 5 个方案里最慢的。

Token 消耗也比较高,仅低于 Qwen API。

如果只看 Token 和时间,它在这次测试里毫无疑问属于执行效率比较低的一档。

但真正打开最终页面后,我反而觉得:

Luna 做出来的前端,是这几个方案里最好看的。

这里的“最好看”仍然只是横向比较。

这几个模型做出来的前端整体都谈不上特别惊艳,也达不到专业 UI 设计师重新设计一遍的水平。

但 Luna 的页面在:

  • 整体布局
  • 信息层级
  • 视觉协调
  • 页面完成度
  • 细节处理

上,给我的最终观感最好。

这就出现了一个很有意思的情况。

如果只看数字:

text
UTF-8|2 Lines|
54.57M Token
107 分钟

Luna 基本垫底。

但如果把最终页面效果也算进去,它又不能简单被定义为“最差”。

至少这次,它确实用更多时间和 Token 换来了一部分可以直接看到的前端质量。

至于这个提升值不值得 107 分钟和 5457 万 Token,那就取决于具体项目。

如果我做的是后台、API、数据处理或者大量 CRUD,我肯定更倾向 GLM 或 DeepSeek。

但如果本身就是一个用户直接访问的网站,最终页面效果很重要,那么 Luna 这次的结果反而值得参考。


Luna 的订阅成本其实很低

Luna 这次还有一个比较特殊的地方,就是它走的是订阅额度。

本次大约使用月额度的:

text
UTF-8|1 Lines|
1%

如果按:

text
UTF-8|1 Lines|
$20/月

简单分摊:

text
UTF-8|1 Lines|
$20 × 1% = $0.20

大约相当于:

text
UTF-8|1 Lines|
¥1.34

不过这个数字一定要正确理解。

¥1.34 是订阅额度的理论分摊成本,并不是这次任务真的额外扣了 ¥1.34。

如果订阅本来就已经购买,那么跑这次任务实际上并没有再产生一笔 ¥1.34 的 API 账单。

所以 Luna 的情况比较特殊:

  • Token 不低
  • 时间最长
  • 前端最好看
  • 但如果订阅已经买了,额外现金成本很低

它和 API 模型其实很难用单一价格指标直接比较。


缓存命中率高,并不代表一定省

这次还有一个很明显的现象,就是几乎所有模型缓存命中率都很高。

统一按照:

text
UTF-8|1 Lines|
缓存命中输入 ÷ 总输入

计算。

结果是:

模型 缓存命中率
DeepSeek-V4-Flash 98.76%
Qwen3.8-Flash Token Plan 98.01%
GPT5.6-Luna-Max 96.28%
Qwen3.8-Flash API 95.18%
GLM5.3-Flash 91.76%

Qwen API 有 95.18% 的输入都命中了缓存,看起来已经非常高。

但它最终依然用了:

text
UTF-8|1 Lines|
65.84M Token

所以缓存命中率只能说明:

大部分上下文按照更便宜的缓存价格计费。

它并不能说明:

这个模型整体只处理了很少的上下文。

如果每一轮都携带巨大的上下文,哪怕 95% 都命中缓存,最终累计 Token 还是可能非常夸张。


缓存命中率是怎么计算的

为了尽量统一几个平台的统计口径,这次缓存命中率都按照:

text
UTF-8|1 Lines|
缓存命中 Token ÷ 总输入 Token

计算,不把输出 Token 放入分母。

GLM

text
UTF-8|2 Lines|
10,155,136 ÷ (10,155,136 + 911,838)
= 91.76%

DeepSeek

text
UTF-8|2 Lines|
20,967,296 ÷ (20,967,296 + 263,641)
= 98.76%

之前原始记录里的 98.35%,是因为把输出 Token 也算进了分母。

只看输入侧缓存命中,98.76% 更合适。

Qwen API

Qwen API 输入分成三部分:

text
UTF-8|5 Lines|
普通输入:2,792
 
显式缓存创建:3,162,220
 
显式缓存命中:62,509,786

总输入:

text
UTF-8|2 Lines|
2,792 + 3,162,220 + 62,509,786
= 65,674,798

所以:

text
UTF-8|2 Lines|
62,509,786 ÷ 65,674,798
= 95.18%

这里要注意:

缓存创建不等于缓存命中。

第一次把内容写进缓存属于创建,之后再次使用才属于命中。

Qwen Token Plan

text
UTF-8|2 Lines|
45,130,075 ÷ (45,130,075 + 916,119)
= 98.01%

Luna

text
UTF-8|2 Lines|
52,273,920 ÷ 54,293,851
= 96.28%

其中 98,817 个推理输出 Token 已经包含在 274,733 个输出 Token 中,所以不重复计算。


Qwen API 的账单还有一个小问题

Qwen API 后台显示的实际费用是:

text
UTF-8|1 Lines|
¥10.24

但按照我记录的价格重新计算:

text
UTF-8|15 Lines|
普通输入:
2,792 × ¥0.80/M
≈ ¥0.0022
 
缓存创建:
3,162,220 × ¥1.25/M
≈ ¥3.9528
 
缓存命中:
62,509,786 × ¥0.10/M
≈ ¥6.2510
 
输出:
168,301 × ¥2.70/M
≈ ¥0.4544

理论合计:

text
UTF-8|1 Lines|
约 ¥10.66

和实际面板:

text
UTF-8|1 Lines|
¥10.24

相差大约:

text
UTF-8|1 Lines|
¥0.42

具体原因目前不确定。

可能是:

  • 缓存创建实际价格存在差异
  • 平台存在其他折扣
  • 部分请求使用了不同计费规则
  • 平台账单统计口径不同

所以这篇文章统一采用:

  • 实际账单:¥10.24
  • 理论重算:约 ¥10.66

在没有更完整账单明细的情况下,就不继续猜具体原因了。


API 真正花了多少钱

如果只比较真正按照 API 用量产生的账单:

模型 实测费用 平均每百万总 Token
DeepSeek-V4-Flash ¥1.84 ≈ ¥0.086/M
GLM5.3-Flash ¥1.583498 ≈ ¥0.143/M
Qwen3.8-Flash API ¥10.24 ≈ ¥0.156/M

这里有两个不同的“最便宜”。

总账单最低的是:

GLM,约 ¥1.58。

单位 Token 成本最低的是:

DeepSeek,约 ¥0.086/M。

不过 DeepSeek 本次是闲时价格,GLM 是限时半价,所以不能把它理解成三家标准 API 原价排名。

Qwen 这次真正拉高账单的关键也不是缓存单价,而是它跑出了:

text
UTF-8|1 Lines|
65.84M Token

总量太高。


Qwen Token Plan 的成本怎么算

Qwen Token Plan 本次使用了 7 日额度的:

text
UTF-8|1 Lines|
24.4%

简单折算为月额度约:

text
UTF-8|1 Lines|
6.1%

套餐价格:

text
UTF-8|1 Lines|
¥39/月

所以按额度比例分摊:

text
UTF-8|2 Lines|
¥39 × 6.1%
= ¥2.379

也就是约:

text
UTF-8|1 Lines|
¥2.38

这个算法和 API 实际扣费并不是一回事,只是为了方便估算一次任务占用了多少订阅价值。


如果只看 Token 和时间

为了简单比较执行效率,我用了一个比较粗暴的算法。

text
UTF-8|8 Lines|
Token 得分 =
最低 Token ÷ 当前模型 Token × 100
 
用时得分 =
最短用时 ÷ 当前模型用时 × 100
 
综合效率 =
(Token 得分 + 用时得分) ÷ 2

也就是:

text
UTF-8|2 Lines|
Token:50%
时间:50%

结果如下:

模型 Token 得分 用时得分 综合效率
GLM5.3-Flash 100.00 71.43 85.71
DeepSeek-V4-Flash 52.08 100.00 76.04
Qwen3.8-Flash Token Plan 24.03 35.71 29.87
Qwen3.8-Flash API 16.86 28.74 22.80
GPT5.6-Luna-Max 20.35 23.36 21.86

如果只评价:

完成这次任务所需要的 Token 和时间

那么排序很明确:

text
UTF-8|1 Lines|
GLM > DeepSeek > Qwen Token Plan > Qwen API > Luna

但这个排名不能理解成模型能力排名。

因为它完全没有考虑最终代码质量和页面效果。

而 Luna 这次就是一个很好的反例。

它在执行效率里排名最后,但是最终前端却是我认为最好看的。


最终代码实际看下来是什么感觉

如果把最终结果简单总结一下:

模型 后台实现 前端效果 本次感受
GLM5.3-Flash 较完整 一般 Token 最省,后台实现直接
DeepSeek-V4-Flash 较完整 一般 与 GLM 后台非常接近,速度最快
Qwen3.8-Flash API 较完整 一般 Token 消耗最高,执行偏重
Qwen3.8-Flash Token Plan 较完整 一般 明显优于 Qwen API
GPT5.6-Luna-Max 较完整 本次最好 最慢,但前端完成度最高

这里的“最好”完全是这一次任务的主观观察。

并不是说:

Luna 的前端能力一定比其他模型强。

只能说:

这一次测试中,Luna 最终给我的页面观感最好。

而且这几个方案整体前端表现其实都只能算比较普通。

如果真的要正式上线,我后面还是会继续专门做 UI 调整。


这次我最大的感受:模型单价可能没想象中那么重要

以前看 API,最容易比较的是:

text
UTF-8|3 Lines|
输入多少钱 / M
输出多少钱 / M
缓存多少钱 / M

但真正把 Agent 跑起来以后,我越来越觉得,这些只是表面价格。

真实成本更接近:

text
UTF-8|5 Lines|
实际任务成本
=
模型单位 Token 成本
×
完成任务所需要处理的 Token

比如这次:

text
UTF-8|5 Lines|
GLM:
11.10M Token
 
Qwen API:
65.84M Token

相差接近 6 倍。

这种情况下,就算 Qwen 的缓存只有:

text
UTF-8|1 Lines|
¥0.10/M

也扛不住总量太大。

所以以后评测 Coding Agent,我觉得“完成同样任务需要多少 Token”应该成为一个很重要的指标。

一个模型如果能:

text
UTF-8|5 Lines|
理解需求
→ 找到文件
→ 修改
→ 验证
→ 完成

另一个模型却是:

text
UTF-8|7 Lines|
读取
→ 分析
→ 再读取
→ 尝试
→ 回退
→ 再尝试
→ 继续携带大量上下文

即使最后都完成了,成本和使用体验都会完全不同。


但 Token 少,也不能代表模型一定更好

Luna 这次又刚好说明了另一面。

如果只看效率:

text
UTF-8|2 Lines|
54.57M Token
107 分钟

确实不好看。

但最终前端又是几个方案里我最满意的。

所以 Token 多并不一定全部是无效消耗。

真正完整的 Coding Agent 评测,我觉得至少应该同时看:

  • 任务是否完成
  • 需求理解是否准确
  • 最终代码质量
  • 前端页面效果
  • 是否引入 Bug
  • 测试是否通过
  • 返工次数
  • Token 消耗
  • 完成时间
  • 实际成本

只看 Token 和时间,评出来的其实只是:

执行效率。

而不是完整的:

Coding 能力。


如果让我现在选

只根据这一次真实任务,我自己的选择其实比较明确。

如果是:

  • 后台开发
  • API
  • CRUD
  • 业务逻辑
  • 批量代码修改

我会优先考虑:

GLM 或 DeepSeek。

GLM 更省 Token。

DeepSeek 更快。

而且这次两者最后做出来的后台代码非常接近。

如果主要使用 API,而且能够利用 DeepSeek 闲时价格,那这次 DeepSeek 的综合体验确实很好。

如果使用 Qwen,我会明显更倾向:

Qwen Token Plan。

因为同一个模型,这次 Plan 比普通 API:

  • 少约 1963 万 Token
  • 快 17 分钟
  • 缓存命中率更高
  • 成本也低很多

普通 Qwen API 在这次任务里的 Token 消耗确实有点夸张。

至于 Luna,它这次属于一个很特别的情况。

如果我最在意的是:

尽快、尽量少 Token 地完成开发

那我不会优先选 Luna。

但如果做的是用户真正会看到的页面,而且我希望模型顺手把前端做得更完整一些,那么这次 Luna 的最终结果反而是几个模型里最好的。

再考虑到它属于订阅额度,如果本来就已经买了订阅,实际额外现金成本并不高。


一句话总结

这一次真实网站改版跑下来:

GLM 最省 Token,DeepSeek 最快,两者后台实现非常接近。

Qwen 普通 API 的 Token 消耗明显偏高,而 Token Plan 的表现要合理很多。

Luna 虽然耗时最长、Token 也不少,但最终前端反而是这次几个方案里最好看的。

所以我现在越来越觉得,Coding Agent 不能只问一句:

哪个模型最强?

更应该问:

我现在做的是什么任务,我到底在意速度、Token、价格、后台代码,还是最终页面效果?

因为同一个任务,这几个模型最后都能做完。

但它们完成任务的方式、成本和最终结果,确实可以完全不一样。


关于这次测试的限制

这次只有一个真实网站修改任务,样本量很小。

所以不能根据这一次测试就判断某个模型长期一定比另一个强。

而且本次价格条件并不统一:

  • GLM 使用限时半价
  • DeepSeek 使用闲时价格
  • Qwen API 使用原价
  • Qwen Token Plan 使用订阅额度
  • Luna 使用订阅额度

不同模型在 Claude Code 中的:

  • 上下文处理方式
  • 缓存机制
  • 工具调用策略
  • 文件读取次数
  • 重试行为
  • 推理长度

也可能完全不同。

这些因素都会影响最终 Token 和完成时间。

另外,这次没有对最终代码进行标准化评分。

比如:

  • GLM 和 DeepSeek 后台代码非常接近
  • Luna 的前端最终效果最好
  • Qwen 的实现方式和 GLM、DeepSeek 有一些区别

这些都属于这一次任务中的实际观察,不应该直接推广成模型的普遍能力结论。

所以这篇文章更准确的定位不是:

5 个模型到底谁最强?

而是:

同一个真实网站修改任务,5 个方案分别用了多少 Token、多少时间、多少钱,以及最后交出来的东西到底有什么区别。

下一篇计划为小记升级一个收藏功能

还没有留言