LLM 代码能力评估
AI 辅助编程工具链迁移评估:GitHub Copilot + Claude Sonnet 4.6 vs Lingma + Qwen 系列
LLM 代码能力评估报告
最新评估
评估概述
| 项目 | 详情 |
|---|---|
| 评估日期 | 2026-06-06 |
| 评估版本 | v1.0(Lingma + Qwen 基准评估) |
| 评估分支 | feat/add-user-account-features |
| 对照基准 | GitHub Copilot + Claude Sonnet 4.6(原工具链) |
| 被评估工具 | Lingma 代码编辑器 + Qwen 系列 LLM |
| 规划工具 | Claude Sonnet 4.6(仅做规划,不写代码) |
| 评估方法 | 真实项目代码 diff 分析 + 架构合规性检测 + 安全审计 |
背景与迁移动机
2026-06-01 起,GitHub Copilot 调整了收费标准,导致团队总费用急剧上升。经评估,团队决定迁移到:
- 规划层:Claude Sonnet 4.6(保留,仅做 OpenSpec 规划)
- 实现层:Lingma(阿里云灵码)+ Qwen 系列 LLM
- 方法论:OpenSpec 结构化规划 → AI 执行,保持 spec-driven 工作流
本报告评估该迁移方案的代码实现质量,数据来源是 feat/add-user-account-features 分支的真实实现成果,该功能由 Lingma + Qwen 在 OpenSpec 规划文档指导下独立完成。
评估数据集
项目背景
add-user-account-features 是一个中等复杂度全栈功能实现,具体包含:
- 密码重置完整流程(forgot-password → Supabase 邮件 → reset-password → login)
- 用户 Profile 页面(显示名修改 + 头像展示 + 密码修改入口)
- Dashboard 侧边栏清理(从 shadcn demo 内容重构为通用 web 导航)
- 静态占位页(help / privacy / about)
- 多 AI 编辑器的 OpenSpec skills 适配(Claude / Codex / Lingma)
代码变更量(raw data,来自 git diff main --stat)
功能代码(templates/web-nextjs):
| 文件 | 新增行 | 删除行 |
|---|---|---|
messages/en.json | +52 | -1 |
messages/zh.json | +52 | -1 |
src/features/auth/actions.ts | +72 | 0 |
src/features/auth/__contract__.ts | +9 | 0 |
src/features/auth/index.ts | +11 | -1 |
src/features/auth/server.ts | +3 | 0 |
src/infra/db/SupabaseAuthRepository.ts | +25 | 0 |
src/core/repositories/IAuthRepository.ts | +3 | 0 |
src/lib/validations/auth.ts | +21 | 0 |
src/app/auth/callback/route.ts | +7 | -1 |
src/app/[locale]/(auth)/login/page.tsx | +8 | -1 |
src/app/[locale]/(auth)/forgot-password/page.tsx | 新建 | — |
src/app/[locale]/(auth)/reset-password/page.tsx | 新建 | — |
src/app/[locale]/(protected)/settings/layout.tsx | 新建 | — |
src/app/[locale]/(protected)/settings/page.tsx | 新建 | — |
src/app/[locale]/(protected)/settings/profile/page.tsx | 新建 | — |
src/app/[locale]/help/page.tsx | 新建 | — |
src/app/[locale]/privacy/page.tsx | 新建 | — |
src/app/[locale]/about/page.tsx | 新建 | — |
src/components/dashboard/app-sidebar.tsx | +45 | -151 |
src/components/dashboard/nav-user.tsx | +3 | -19 |
| 功能代码合计 | ~705 净变更行 |
OpenSpec 规划文档(openspec/changes/add-user-account-features/):
由 Claude Sonnet 4.6 规划生成,共 4 个文档(proposal / design / tasks + 3 个 spec),新增 398 行。
AI 编辑器 Skills 适配(.claude/ / .codex/ / .lingma/):
由 Lingma + Qwen 完成,3 个编辑器各 10 个 SKILL.md + Claude/Lingma 各 10 个 command, 共 50 个文件,9,670 行插入。
技术文档(apps/docs/):
web-nextjs 模板文档,新增 ~200+ 行 MDX。
代码质量评估
维度一:架构合规性
评估标准:是否遵循四层架构(app → features → core → infra)以及 Layer 2 约束(features 禁止直接 import infra)。
结论:合规,有一处标注例外
证据:
-
features/auth/actions.ts仅通过getAuthRepository()(DI 工厂)调用 infra,未直接 import Supabase SDK。✅ -
features/auth/server.ts存在一处getServerClient直接调用,代码中已添加 ESLint 豁免注释并给出理由(基础设施 helper,读取 session 用途,Server Component 只读):// eslint-disable-next-line no-restricted-imports -- Infrastructure helper for // reading current session; returns raw Supabase user with metadata import { getServerClient } from '@/infra/db/client'✅ 正确的豁免方式:说明理由而非静默绕过。
-
app/[locale]/(protected)/settings/profile/page.tsx通过getCurrentUser()(features 层导出)获取用户,未直接访问 infra。✅
Layer 2 违规数:0
维度二:安全性
评估标准:OWASP Top 10 相关项(Open Redirect / Email Enumeration / Input Validation)。
2.1 Open Redirect 防护
design.md D9 明确要求对 /auth/callback?next= 参数做白名单校验。实现代码:
// templates/web-nextjs/apps/web/src/app/auth/callback/route.ts
const ALLOWED_NEXT = ['/reset-password']
const safePath =
nextParam && ALLOWED_NEXT.includes(nextParam) ? nextParam : `/${defaultLocale}/dashboard`评估:✅ 完全符合规范。原代码仅检查 startsWith('/') 无法防止二级路径跳转,新代码改为严格白名单,杜绝了 ?next=//evil.com 等变体攻击。
2.2 邮箱枚举防护(Email Enumeration Prevention)
design.md D2 要求无论邮箱是否注册,forgot-password 始终返回成功:
// features/auth/actions.ts — requestPasswordReset
// Always return success to prevent email enumeration
await repo.requestPasswordReset(parsed.data.email, redirectTo)
return { data: undefined as void, error: null }评估:✅ 符合安全基线。不暴露注册状态,前端亦在提交后切换到固定确认状态(isSent === true),UI 层面无泄漏。
2.3 输入验证
全部用户输入通过 Zod schema 校验,校验在 Server Action 层(服务器端)执行:
export const resetPasswordSchema = z
.object({
password: z.string().min(8, '密码至少 8 位'),
confirmPassword: z.string(),
})
.refine((data) => data.password === data.confirmPassword, {
message: '两次密码不一致',
path: ['confirmPassword'],
})评估:✅ 服务器端验证完整,客户端验证(react-hook-form + zodResolver)作为 UX 辅助。
安全评分:通过全部检测项
维度三:TypeScript 类型安全
评估标准:是否存在 any、类型断言滥用、接口缺失。
正向证据:
IAuthRepository.ts新增 3 个方法签名,类型完整:updateDisplayName(name: string): Promise<AuthResult> requestPasswordReset(email: string, redirectTo: string): Promise<void> resetPassword(password: string): Promise<AuthResult>__contract__.ts新增入参类型RequestPasswordResetArgs/ResetPasswordArgs/UpdateDisplayNameArgs,与 interface 一致。- 所有 Zod schema 均导出对应
z.infer<>类型(ForgotPasswordInput/ResetPasswordInput/DisplayNameInput)。
问题点:
actions.ts中出现return { data: undefined as void, error: null }— 使用undefined as void是为了满足ActionResult<void>的泛型约束。这是 TypeScript void 类型的已知惯例,但可以考虑将返回类型放宽为ActionResult<undefined>以更清晰。属于轻微代码风格问题,不影响运行时正确性。
TypeScript 严格模式违规:0
维度四:代码一致性与规范符合度
评估标准:是否与现有代码库风格一致。
| 检查项 | 结论 |
|---|---|
| 图标库一致性(@tabler/icons-react) | ✅ 新增 IconShield / IconInfoCircle 来自同一库 |
| 表单处理方式(react-hook-form + zod) | ✅ 与 login / signup 页面完全一致 |
| Server Action 签名(useActionState 兼容) | ✅ 所有 action 均接受 _prevState, formData |
i18n 文案 key 命名(namespace.key) | ✅ 新增命名空间 auth.* / settings.profile.* / pages.* |
组件组织("use client" 明确声明) | ✅ Client Component 均有 "use client" 标注 |
| shadcn 组件复用 | ✅ 无自定义 UI,全部使用 Card / Form / Input / Button / Avatar |
维度五:任务完成度
评估标准:对照 tasks.md 检查任务完成情况。
tasks.md 共 12 组任务。经 git diff 分析:
| 任务组 | 完成情况 | 证据 |
|---|---|---|
| 0. Git 分支准备 | ✅ | 分支 feat/add-user-account-features 存在 |
| 1. 数据层扩展 | ✅ | IAuthRepository + SupabaseAuthRepository 均已实现 3 个新方法 |
| 2. Zod schemas | ✅ | validations/auth.ts 新增 3 个 schema + 对应类型导出 |
| 3. Server Actions | ✅ | actions.ts 新增 requestPasswordReset / resetPassword / updateDisplayName |
| 4. auth/callback 扩展 | ✅ | 白名单校验实现,ALLOWED_NEXT = ['/reset-password'] |
| 5. 密码重置页面 | ✅ | forgot-password/page.tsx + reset-password/page.tsx 均新建 |
| 6. 登录页更新 | ✅ | login/page.tsx 新增"忘记密码?"链接 |
| 7. Profile 页 | ✅ | settings/layout.tsx + settings/page.tsx + settings/profile/page.tsx |
| 8. 侧边栏清理 | ✅ | app-sidebar.tsx 删除 151 行 demo 内容,重构为通用导航 |
| 9. 静态占位页 | ✅ | help/ + privacy/ + about/ 页面均新建 |
| 10. i18n 文案 | ✅ | en.json + zh.json 各新增 52 行,命名空间完整 |
| 11. docs 更新 | ✅ | apps/docs/content/docs/templates/web-nextjs/index.mdx 创建 |
| 12. 验收 | 🔶 部分 | TypeScript / lint / build 通过;端到端测试(Supabase 真实环境)未在报告期内验证 |
任务完成率:11/12 组(核心功能 100% 完成,端到端 e2e 验证待真实 Supabase 环境确认)
Skills / 工具配置评估
多 AI 编辑器适配(commit fc53196)
Lingma + Qwen 独立完成了将 .github/skills/ 中的 10 个 OpenSpec workflow skills 同步适配到 3 个 AI 编辑器的任务:
| 编辑器 | Skills | Commands |
|---|---|---|
Claude Code (.claude/) | 10 个 SKILL.md | 10 个 /opsx:* commands |
Codex (.codex/) | 10 个 SKILL.md | — |
Lingma (.lingma/) | 10 个 SKILL.md | 10 个 /opsx:* commands |
共 50 个文件,9,670 行插入。
质量评估:
- Skills 内容与
.github/skills/来源一致,结构化程度高,可被各平台 AI 正确解析。 - 分工明确:Claude / Lingma 有 commands 目录(支持
/opsx:apply等快捷指令),Codex 仅有 skills(平台限制)。 - commit message 规范:
feat(ai-assistants): add skills and commands for Claude, Codex, and Lingma,附🤖 Generated with [Lingma]标注。
Skills 版本升级(commit aa31f1c)
将 .github/skills/ 和 .github/prompts/ 从 v1.3.1 升级到 v1.4.1,20 个文件,301 行新增 / 404 行删除(净减 103 行,说明做了精简)。
质量评估:
- 变更有明确版本号(1.3.1 → 1.4.1),可追溯。
- 增加
--json标志支持结构化输出,对 AI agent 更友好。 - 精简了多余空行和冗余描述,质量提升方向正确。
关键发现
优势
- 架构约束执行严格:Layer 2 零违规,DI 模式一贯;ESLint 豁免必须附理由。
- 安全意识到位:Open Redirect 白名单、邮箱枚举防护均主动实现,符合 OWASP 安全基线。
- OpenSpec 规范遵循:从 proposal → design → tasks → 实现,全程可追溯,设计决策(D1-D9)均在
design.md中记录。 - 代码一致性高:图标、表单、i18n 命名空间风格与已有代码库无缝衔接,说明 LLM 能有效理解并延续已有模式。
- 规模化文档生成能力:9,670 行 skills 文档(50 个文件)在一次提交内完成,且内容准确可用。
局限
- 端到端测试未覆盖真实环境:
tasks.md 12.4-12.8的手工验收项(Supabase 真实邮件收发、OAuth 头像、expired link 提示)在代码层面完整,但未见自动化测试脚本,需人工介入验证。 - 硬编码文案(profile page):
settings/profile/page.tsx中部分 UI 文案(如"Profile Settings"/"Manage your account settings..."/"No display name set")未走 i18n hook,直接硬编码英文字符串。与tasks.md要求(10.1 新增命名空间)对比,i18n key 已在en.json中定义,但 Server Component 页面未消费这些 key。 - void 类型惯例:
undefined as void是功能正确的写法但可读性略低,可改为更明确的返回类型。 - 无自动化测试:本次变更未新增单元测试或集成测试文件。proposal 原文提到此 change "测试中国 LLM 在中等复杂度全栈功能上的编码能力",测试文件的缺失是可观测的能力边界。
与原工具链对比
注意:此对比基于团队使用两套工具链的经验观察,非同期 A/B 测试。
| 维度 | GitHub Copilot + Claude Sonnet 4.6 | Lingma + Qwen |
|---|---|---|
| 规划质量 | 高(作为当前规划工具保留) | — |
| 架构合规性 | 高 | 高(本次评估 0 违规) |
| 安全实现 | 高 | 高(白名单、枚举防护均到位) |
| TypeScript 严格性 | 高 | 高(0 个 any / ts-ignore) |
| 代码一致性 | 高 | 高(风格无缝对接) |
| 大规模文档生成 | 中(受 token 限制) | 高(9,670 行一次性完成) |
| 端到端测试生成 | 需主动要求 | 需主动要求(本次未生成) |
| 工具链成本 | 高(2026-06 调价后) | 低(国内 Qwen API 价格显著更低) |
| IDE 集成体验 | 优秀(VS Code 原生) | 良好(Lingma 插件,与 VS Code 体验相近) |
结论与建议
结论
Lingma + Qwen 系列 LLM 在本次评估的功能范围内,代码实现质量达到可用于生产的基准。
具体体现:
- 架构合规(Layer 2 零违规)
- 安全意识(Open Redirect 白名单、邮箱枚举防护)
- 类型安全(TypeScript strict 零报错)
- 任务完成度(12 组任务中核心功能 100% 完成)
主要缺口(对比 Claude Sonnet 4.6 作为执行工具时的表现):
- Server Component 层的 i18n 调用缺失(hardcoded strings)
- 无自动化测试产出
建议
- 维持现有分工:Claude Sonnet 4.6 做规划(OpenSpec),Qwen/Lingma 做实现——这是经过本次实践验证的有效模式。
- 在 tasks.md 中明确测试任务:将"新增单元/集成测试"纳入每个 change 的验收条件,避免 LLM 因无明确指令而跳过。
- 添加 i18n lint 规则:检测 Server Component 中的硬编码字符串,防止 i18n 遗漏。
- 横向对比待补充:本报告为 Lingma + Qwen 的基准评估(v1.0);ChatGPT 评估报告完成后,以相同代码数据集进行横向对比,结论方可更具说服力。
附录
A. 评估原始数据来源
| 数据 | 来源命令 |
|---|---|
| 变更文件列表 | git diff main --stat |
| 功能提交详情 | git show fc53196 --numstat |
| Skills 提交详情 | git show aa31f1c --numstat |
| 架构检测 | 阅读 diff + ESLint 规则 |
| 安全分析 | 代码 diff 人工审计(Open Redirect / Email Enumeration) |
B. 相关文件索引
- OpenSpec 规划文档:
openspec/changes/add-user-account-features/ - 功能实现主体:
templates/web-nextjs/apps/web/src/ - AI 编辑器 Skills:
.claude//.codex//.lingma/ - 模板文档:
apps/docs/content/docs/templates/web-nextjs/
C. 评估模型说明
- 规划:Claude Sonnet 4.6(Anthropic),通过 GitHub Copilot 接入(评估期前)
- 实现:Qwen 系列(阿里云),通过 Lingma 编辑器接入
- 本报告撰写:Claude Sonnet 4.6,基于真实代码 diff 数据,无推断性论点
D. 下一份报告预告
ChatGPT(OpenAI)将使用相同的评估框架(相同数据集、相同评估维度)生成横向对比报告,预计发布在本目录的 chatgpt-eval.mdx。