昨天晚上,DeepSeek 悄无声息地放出了 V4 Pro。
没有发布会,没有官宣推文,连个预热海报都没有。我就是刷技术群的时候看到有人丢了一条消息:「DeepSeek V4 Pro 上了,DeepSWE 7.3 → 62.7」。
62.7?那个之前只有 7.3 的 DeepSWE?暴涨 8.6 倍?
说实话,跑分这东西我看太多了。Terminal Bench 87.9、DeepSWE 62.7,数字漂亮得很------但作为前端工程师,我关心的不是它在 benchmark 上多拿了零点几分,而是:
能帮我写 React 吗?能找到 bug 吗?能从零搭一个项目吗?
测试一下吧,今天用 4 个前端真实场景,从组件生成到 bug 修复到 Agent 工程任务,拿真实 API 跑一遍,看看 V4 Pro 到底几斤几两。
一、V4 Pro 到底升级了什么
1.1 核心规格
先看看 V4 Pro 的基本盘:
| 规格 | V4 Pro | 对比上一代 |
|---|---|---|
| 上下文窗口 | 1M tokens | 行业顶级 |
| 最大输出 | 384K tokens | 长输出能力大幅提升 |
| 思考模式 | 三档(低/中/高) | 可按需选择推理深度 |
| 模型代号 | deepseek-v4-pro | --- |
1M 上下文意味着你可以把整个前端项目的源码丢进去,让它做全局分析。384K 输出意味着它能一口气生成一个完整的项目脚手架,不会写到一半断掉。
思考模式三档是个有意思的设计------简单问题用低档快速响应,复杂任务用高档深度推理。后面实测你会看到,这个设计直接影响了响应速度和质量。
1.2 Agent 评测数据对比
这次 V4 Pro 最炸的数据在 Agent 评测上:
| 工具 | Terminal Bench 2.1 | DeepSWE |
|---|---|---|
| DeepSeek V4 Pro | 87.9 | 62.7 |
| Claude Fable 5 | 88.0 | --- |
| Claude Opus 4.8 | <87.9 | <62.7 |
| Meta Muse Code | 82.9 | 59.3 |
| OpenAI Codex (GPT-5.6) | 81.8 | --- |
Terminal Bench 上跟 Claude Fable 5 基本打平,87.9 vs 88.0,差 0.1 分可以忽略不计。DeepSWE 上 62.7 直接领先一个身位。
但更震撼的是 DeepSWE 自身的提升:预览版 7.3 → 正式版 62.7,约 8.6 倍提升。这个跃升幅度在模型迭代史上罕见。
中文场景下还有个 SuperCLUE-Terminal 评测值得参考:Kimi K3 第一(60.61),DeepSeek V4 Pro 第二(51.52),GLM-5.2 第三(48.48)。中文场景下 DeepSeek 没拿第一,但差距不大。
再看价格:
| 工具 | 输入价格(每百万 token) | 输出价格(每百万 token) |
|---|---|---|
| DeepSeek V4 Pro | ¥3 | ¥6 |
| Claude Fable 5 | ~¥108($15) | ~¥540($75) |
| Meta Muse Code | ~¥9($1.25) | ~¥30($4.25) |
DeepSeek 的输入价格是 Claude 的 1/36 ,输出价格是 1/90。即使跟最便宜的 Muse Code 比,也便宜了一大截。
按汇率估算,Claude Fable 5 完成一次复杂 Agent 任务(假设消耗 50K 输入 + 100K 输出),成本大约 ¥10.8 + ¥54 = ¥64.8。同样任务在 DeepSeek 上只要 ¥0.15 + ¥0.6 = ¥0.75。Claude 的 1/86。
价格屠夫,名副其实。
1.3 跑分背后的 Harness:跑的不是裸模型
上面这些跑分数据,不是裸模型跑出来的。
V4 Pro 正式版的官方评测,用的是 DeepSeek Harness 极简模式 + max 思考档位。Harness 是什么?简单来说,它是 8/13 跟 V4 Pro 同一天发布的 Agent 框架(v0.1 开发者预览版,MIT 开源),负责调用工具、读写文件、管理上下文、处理报错------让模型能把一件事从头干到尾的那层工程。
DeepSeek Harness 的设计思路是「一切皆插件」------模型、工具、技能、会话、沙箱、存储、循环、调度、UI,全部插件化,可自由替换和重组。
这意味着什么?官方跑分是「模型 + 框架」的组合能力,不是裸模型能力。你自己用 API 裸调的时候,表现可能跟跑分有差距------因为没有 Harness 那层工具调用和上下文管理的加持。
后面我的四轮实测就是裸 API 调用,没有接 Harness,你可以把我的测试结果理解为不带框架的真实表现。
1.4 为什么前端开发者应该关注
2026 年 AI 编程工具的竞争格局已经清晰:Claude Code 走高端路线、Codex 靠 GPT 生态、Muse Code 主打开源免费、DeepSeek 走性价比杀手路线。这些工具的底层模型能力,直接决定了你每天写代码的效率。
前端场景的特殊性在于:代码量大(JSX + CSS + 类型定义)、跨文件关联强(组件 → Hook → Store → API)、对上下文理解要求高(你得理解整个组件树才能改一个 prop 的类型)。
V4 Pro 的 1M 上下文 + 384K 输出 + 深度思考模式,恰好踩在前端开发的痛点上。
那实际效果如何呢?
二、实测 1:React 组件生成
2.1 测试设计
第一个场景最基础也最常见------让 AI 生成一个完整的 React 组件。我给了它一个经典需求:TodoList,但要带状态管理和过滤功能。
Prompt 如下:
用 React + TypeScript 写一个完整的 TodoList 组件,要求:
- 使用 useReducer 管理状态
- 支持添加、删除、切换完成状态
- 支持过滤(全部/已完成/未完成)
- 包含完整的 TypeScript 类型定义
- 包含完整的 CSS 样式(使用 CSS 变量)
- 响应式设计
- 不要使用任何第三方库
2.2 API 调用代码
调用 DeepSeek V4 Pro 的 API 很简单,跟 OpenAI 格式兼容:
python
import requests
API_KEY = "your-api-key" // 替换成你自己的 key
URL = "https://api.deepseek.com/v1/chat/completions"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "deepseek-v4-pro",
"messages": [
{"role": "user", "content": "用 React + TypeScript 写一个完整的 TodoList 组件..."}
],
"max_tokens": 16384,
"stream": False
}
response = requests.post(URL, headers=HEADERS, json=payload)
result = response.json()
content = result["choices"][0]["message"]["content"]
reasoning = result["choices"][0]["message"].get("reasoning_content", "")
print(f"输出内容:\n{content}")
print(f"\n思考过程:\n{reasoning}")
🆕 注意那个 reasoning_content 字段------这是 V4 Pro 思考模式的输出,模型会先"想"一遍再回答。这个字段在调试和理解模型行为时非常有用。
2.3 完整输出
模型耗时 130.7 秒 ,总共消耗 9003 tokens(prompt=160, completion=8843, 其中 reasoning=5976, content=2867)。
近 6000 token 都花在了思考上,实际输出不到 3000 token。换句话说,模型花了 2/3 的算力在"想",1/3 在"写"。
下面是 V4 Pro 的完整输出(截取核心部分):
tsx
// types.ts 类型定义完整
interface Todo {
id: string;
text: string;
completed: boolean;
createdAt: number;
}
type FilterType = 'all' | 'active' | 'completed';
type Action =
| { type: 'ADD_TODO'; payload: string }
| { type: 'TOGGLE_TODO'; payload: string }
| { type: 'DELETE_TODO'; payload: string }
| { type: 'SET_FILTER'; payload: FilterType };
类型定义很规范,Todo 有完整的字段,Action 用了 discriminated union------这是 React reducer 的最佳实践写法。
tsx
// reducer.ts
function todoReducer(state: Todo[], action: Action): Todo[] {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: Date.now().toString(),
text: action.payload,
completed: false,
createdAt: Date.now(),
},
];
case 'TOGGLE_TODO':
return state.map(todo =>
todo.id === action.payload
? { ...todo, completed: !todo.completed }
: todo
);
case 'DELETE_TODO':
return state.filter(todo => todo.id !== action.payload);
case 'SET_FILTER':
return state; // filter 放在另一个 state 里
default:
return state;
}
}
这里有个小瑕疵------SET_FILTER 的 case 直接返回了 state,因为 filter 状态需要单独管理。模型在思考过程中意识到了这个问题,但实现上把 filter 拆成了独立的 useState。合理,但 reducer 的 switch 里留一个 no-op case 稍显不够优雅。
tsx
// TodoList.tsx
function TodoList() {
const [todos, dispatch] = useReducer(todoReducer, []);
const [filter, setFilter] = useState<FilterType>('all');
const inputRef = useRef<HTMLInputElement>(null);
const handleAdd = () => {
const text = inputRef.current?.value.trim();
if (!text) return;
dispatch({ type: 'ADD_TODO', payload: text });
if (inputRef.current) inputRef.current.value = '';
};
const filteredTodos = todos.filter(todo => {
if (filter === 'active') return !todo.completed;
if (filter === 'completed') return todo.completed;
return true;
});
return (
<div className="todo-container">
<header className="todo-header">
<h1>Todo List</h1>
<div className="todo-input-group">
<input ref={inputRef} type="text" placeholder="输入新任务..." />
<button onClick={handleAdd}>添加</button>
</div>
</header>
<div className="todo-filters">
{(['all', 'active', 'completed'] as FilterType[]).map(f => (
<button
key={f}
className={filter === f ? 'active' : ''}
onClick={() => setFilter(f)}
>
{{ all: '全部', active: '未完成', completed: '已完成' }[f]}
</button>
))}
</div>
<ul className="todo-list">
{filteredTodos.length === 0 ? (
<li className="todo-empty">暂无任务</li>
) : (
filteredTodos.map(todo => (
<li key={todo.id} className={todo.completed ? 'completed' : ''}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => dispatch({ type: 'TOGGLE_TODO', payload: todo.id })}
/>
<span className="todo-text">{todo.text}</span>
<button onClick={() => dispatch({ type: 'DELETE_TODO', payload: todo.id })}>
删除
</button>
</li>
))
)}
</ul>
</div>
);
}
组件实现很完整。useReducer + useState + useRef 三个 Hook 配合使用,过滤逻辑清晰,空状态也处理了。
CSS 部分(截取):
css
:root {
--primary-color: #4f46e5;
--bg-color: #f9fafb;
--text-color: #111827;
--border-color: #e5e7eb;
--completed-color: #9ca3af;
}
.todo-container {
max-width: 600px;
margin: 2rem auto;
padding: 1.5rem;
background: var(--bg-color);
border-radius: 12px;
}
@media (max-width: 640px) {
.todo-container {
margin: 0;
border-radius: 0;
min-height: 100vh;
}
}
CSS 变量、响应式、过渡动画都齐全。模型甚至考虑了移动端的适配。
2.4 质量评价
第一次测试,印象不错。一个 prompt 出来基本能用的组件,不需要太多手动修改。130 秒的等待有点长,但思考模式开的是高档,质量换速度的取舍可以理解。
三、实测 2:TypeScript 高级类型推导
3.1 测试设计
第二个场景考察类型系统的深度------让 V4 Pro 实现两个经典的高级类型工具:DeepPartial 和 GetValueType。这两个类型在前端项目里不算常见,但能考察模型对 TS 类型系统的理解深度。
Prompt:
实现以下 TypeScript 高级类型工具:
- DeepPartial --- 递归地将所有属性变为可选,包括嵌套对象和数组
- GetValueType --- 提取对象所有值的联合类型
要求:处理边界情况(函数、数组、null/undefined),每个类型给出使用示例
3.2 输出
耗时 36.9 秒 ,消耗 2423 tokens(prompt=140, completion=2283, 其中 reasoning=1854, content=429)。
这次快多了------36 秒 vs 之前 130 秒。原因是问题更聚焦,思考量小(1854 vs 5976)。
typescript
// 1. DeepPartial<T> --- 递归可选
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object
? T[P] extends Function
? T[P] // 函数保持原样,不递归
: T[P] extends Array<infer U>
? Array<DeepPartial<U>> // 数组递归处理元素
: DeepPartial<T[P]> // 普通对象递归
: T[P];
};
// 使用示例
interface User {
id: number;
profile: {
name: string;
age: number;
address: {
city: string;
zip: string;
};
};
tags: string[];
onClick: () => void;
}
type PartialUser = DeepPartial<User>;
// 等价于:
// {
// id?: number;
// profile?: {
// name?: string;
// age?: number;
// address?: {
// city?: string;
// zip?: string;
// };
// };
// tags?: string[];
// onClick?: () => void;
// }
逐行拆解这个 DeepPartial:
[P in keyof T]?--- 映射类型,遍历所有 key 并加?变可选T[P] extends object--- 判断属性值是否是对象类型T[P] extends Function--- 函数类型保持原样,不做递归(边界处理)T[P] extends Array<infer U>--- 数组类型递归处理元素类型DeepPartial<T[P]>--- 普通对象递归
函数和数组都做了边界处理,这是很多人手写 DeepPartial 时容易遗漏的。V4 Pro 在思考过程中明确考虑了这些边界------那 1854 token 的 reasoning 没白花。
typescript
// 2. GetValueType<T> --- 提取值的联合类型
type GetValueType<T> = T[keyof T];
// 使用示例
interface Config {
port: number;
host: string;
debug: boolean;
}
type ConfigValues = GetValueType<Config>;
// 等价于:number | string | boolean
// 更复杂的例子
interface AppState {
user: { name: string };
settings: { theme: string };
count: number;
}
type AppStateValues = GetValueType<AppState>;
// 等价于:{ name: string } | { theme: string } | number
GetValueType 的核心就是 T[keyof T]------遍历所有 key 取值的联合类型。简单但实用,在 Redux/状态管理场景下经常用到。
3.3 质量评价
这一轮表现很好。类型系统是 TS 的深水区,V4 Pro 对条件类型、infer、映射类型的理解都很扎实。函数边界处理是加分项------很多模型会忘记函数也是 object 的子类型,导致 () => void 也被递归展开。
四、实测 3:Bug 修复能力
4.1 测试设计
第三个场景是bug 修复,也是AI 编程工具日常使用频率最高的场景
给 V4 Pro 一段有 bug 的 React 组件代码,让它找出所有问题并修复。
Prompt:
以下 React 组件代码存在多个 bug,请找出所有 bug 并给出修复后的完整代码:
jsxfunction UserList({ userId }) { const [users, setUsers] = useState([]); useEffect(() => { fetch(`/api/users?page=${userId}`) .then(res => res.json()) .then(data => setUsers(data.users)); }, []); return ( <ul> {users.map((user, index) => ( <li key={index}>{user.name}</li> ))} </ul> ); }
这段代码里有三个经典 bug,你在 code review 的时候大概率见过。
4.2 输出
耗时 182.2 秒 ,消耗 11981 tokens(prompt=286, completion=11695, 其中 reasoning=11023, content=672)。
182 秒!超过 3 分钟。11023 token 的思考量是所有测试中最大的。模型在思考阶段做了非常细致的分析。
V4 Pro 识别出 3 个 bug:
Bug 1:useEffect 依赖数组缺少 userId
jsx
// 原代码
useEffect(() => {
fetch(`/api/users?page=${userId}`)
.then(res => res.json())
.then(data => setUsers(data.users));
}, []); // ← 空依赖数组,userId 变化时不会重新请求
这是 React Hooks 最经典的 bug------userId 在 effect 中使用了,但没有加到依赖数组里。组件挂载后 userId 变化,数据不会重新加载。
Bug 2:缺少异步请求清理/竞态处理
jsx
// 原代码没有处理组件卸载时的清理
// 如果 userId 快速变化,旧请求可能覆盖新请求的结果
V4 Pro 引入了 AbortController 来处理竞态------这个加分项我没想到。很多模型只会加依赖数组,不会考虑竞态问题。
Bug 3:key 使用不可靠的 index
jsx
// 原代码
{users.map((user, index) => (
<li key={index}>{user.name}</li> // ← index 作为 key 不稳定
))}
列表删除/排序时 index 会变化,导致 React diff 算法错误复用 DOM。应该用稳定的唯一标识符,比如 user.id。
修复后的完整代码:
tsx
function UserList({ userId }: { userId: string }) {
const [users, setUsers] = useState<User[]>([]);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController(); // AbortController 处理竞态
const fetchData = async () => {
try {
setError(null);
const response = await fetch(`/api/users?page=${userId}`, {
signal: controller.signal, // 传入 signal
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUsers(data.users);
} catch (err) {
if (err instanceof DOMException && err.name === 'AbortError') {
return; // 请求被取消,静默处理
}
setError(err instanceof Error ? err.message : 'Unknown error');
}
};
fetchData();
return () => controller.abort(); // 清理函数取消未完成请求
}, [userId]); // 依赖数组补全
if (error) {
return <div className="error">加载失败: {error}</div>;
}
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li> // 用 user.id 替代 index
))}
</ul>
);
}
修复质量很高。三个 bug 全部修复,而且:
AbortController处理竞态------很多 senior 前端都忘记写的代码response.ok检查------HTTP 状态码验证- error handling------加了 error state 和错误展示
AbortError静默处理------取消请求不算错误,不该展示给用户
4.3 质量评价
说实话很惊讶,引入AbortController 说明 V4 Pro 修复的不只是表面,而是思考"这段代码在运行时会出现什么问题"。这是高级工程师的思维模式。
182 秒确实很长。但考虑到它思考了 11000 token(相当于在脑子里写了一篇 5000 字的技术分析),这个时间花在了刀刃上。复杂 bug 修复场景,慢一点也无所谓,只要透彻就好。
五、实测 4:Agent 多步骤工程任务
5.1 测试设计
最后一个场景是让 V4 Pro 充当 Agent,完成一个多步骤的工程任务:从零创建一个 React + Vite + TypeScript 项目,包含组件、路由和 API 调用。
Prompt:
作为前端工程 Agent,按步骤完成:
- 用 Vite 创建 React + TypeScript 项目
- 安装 react-router-dom
- 创建 src/types.ts(类型定义)
- 创建 src/api.ts(fetch 封装带错误处理)
- 创建 src/pages/Home.tsx 和 src/pages/Detail.tsx
- 创建 src/App.tsx(HashRouter 路由配置)
- 给出目录结构树
每步给出完整代码。
API 数据: 耗时 154.4s | 总 tokens 13804(思考 11147,输出 2452)
5.2 输出
V4 Pro 按步骤输出了完整的搭建指南:
Step 1:项目初始化
bash
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm install react-router-dom
npm install -D @types/react-router-dom
Step 2:类型定义
typescript
// src/types.ts
export interface Post {
id: number;
userId: number;
title: string;
body: string;
}
Step 3:API 封装
typescript
// src/api.ts
import { Post } from './types';
const BASE_URL = 'https://jsonplaceholder.typicode.com';
export async function fetchPosts(signal?: AbortSignal): Promise<Post[]> {
const res = await fetch(`${BASE_URL}/posts`, { signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`); // 状态码检查
return res.json();
}
export async function fetchPostById(id: number, signal?: AbortSignal): Promise<Post> {
const res = await fetch(`${BASE_URL}/posts/${id}`, { signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
API 封装里有两个值得注意的点:res.ok 检查------跟 bug 修复测试中一样,V4 Pro 对 HTTP 错误处理有 consistently 的好习惯;signal?: AbortSignal 可选参数------让调用方可以传入 AbortController.signal 来取消请求。这个参数设计是后续页面组件中竞态处理的基础。
Step 4:路由配置
tsx
// src/App.tsx
import { HashRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import Detail from './pages/Detail';
function App() {
return (
<HashRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/post/:id" element={<Detail />} />
</Routes>
</HashRouter>
);
}
export default App;
用 HashRouter 而不是 BrowserRouter------模型注意到了 prompt 里的"Hash 模式"要求。这种细节遵从能力很重要。
Step 5:首页
tsx
// src/pages/Home.tsx
import { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { fetchPosts } from '../api';
import { Post } from '../types';
function Home() {
const [posts, setPosts] = useState<Post[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController();
const load = async () => {
try {
setLoading(true);
const data = await fetchPosts(controller.signal);
setPosts(data);
} catch (err) {
if (err instanceof DOMException && err.name !== 'AbortError') {
setError(err.message);
}
} finally {
setLoading(false);
}
};
load();
return () => controller.abort();
}, []);
if (loading) return <div>加载中...</div>;
if (error) return <div>错误: {error}</div>;
return (
<div>
<h1>文章列表</h1>
<ul>
{posts.map(post => (
<li key={post.id}>
<Link to={`/post/${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
</div>
);
}
export default Home;
又出现了 AbortController------V4 Pro 对异步请求清理有很强的意识。或者说底层将这种思维模式作为了默认行为。
Step 6:详情页
tsx
// src/pages/Detail.tsx
import { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom';
import { fetchPostById } from '../api';
import { Post } from '../types';
function Detail() {
const { id } = useParams<{ id: string }>();
const [post, setPost] = useState<Post | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const controller = new AbortController();
const load = async () => {
try {
setLoading(true);
if (id) {
const data = await fetchPostById(Number(id), controller.signal);
setPost(data);
}
} catch (err) {
if (err instanceof DOMException && err.name !== 'AbortError') {
console.error(err);
}
} finally {
setLoading(false);
}
};
load();
return () => controller.abort();
}, [id]); // id 作为依赖
if (loading) return <div>加载中...</div>;
if (!post) return <div>未找到文章</div>;
return (
<div>
<Link to="/">← 返回列表</Link>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
);
}
export default Detail;
useParams 的泛型参数 <{ id: string }> 写了,id 加入了依赖数组,!post 的空状态也处理了。
5.3 质量评价
可以看出整个 Agent 任务完成质量很高。7 个步骤、10+ 个文件,每个文件代码完整可运行。
V4 Pro 在不同文件中保持了一致的代码风格,AbortController 的使用模式在 request.ts 和页面组件中完全一致。这种跨文件的一致性说明模型有内在的代码规范意识,不是随机生成。
六、横向对比
6.1 能力对比
把 V4 Pro 放到当前 AI 编程工具的竞争格局里看一下:
| 工具 | Terminal Bench 2.1 | DeepSWE | 中文评测 SuperCLUE |
|---|---|---|---|
| DeepSeek V4 Pro | 87.9 | 62.7 | 51.52(第二) |
| Claude Fable 5 | 88.0 | --- | --- |
| Meta Muse Code | 82.9 | 59.3 | --- |
| OpenAI Codex (GPT-5.6) | 81.8 | --- | --- |
| Kimi K3 | --- | --- | 60.61(第一) |
| GLM-5.2 | --- | --- | 48.48(第三) |
Terminal Bench 上 DeepSeek 和 Claude 基本打平,DeepSWE 上 DeepSeek 领先。中文场景下 Kimi K3 表现更好,但 Kimi 的 Agent 能力(DeepSWE)没有公开数据。
注:DeepSeek V4 Pro 的 Terminal Bench/DeepSWE 基于官方 Harness 框架跑出的数据,其余模型环境各异,对比仅供趋势参考。
6.2 价格对比
| 工具 | 输入(每百万 token) | 输出(每百万 token) | 相对成本 |
|---|---|---|---|
| DeepSeek V4 Pro | ¥3 | ¥6 | 1x(基准) |
| Meta Muse Code | ~¥9 | ~¥30 | 3-5x |
| Claude Fable 5 | ~¥108 | ~¥540 | 36-90x |
| OpenAI Codex | --- | --- | 按订阅收费 |
DeepSeek 的价格优势是碾压级的。同样的任务量,用 Claude 的成本够你用 DeepSeek 用一个月。
6.3 前端开发者选型建议
根据我这四轮实测的经验,给前端开发者一个实用的选型建议:
日常代码补全 / 快速生成 → Muse Code 或 DeepSeek 思考模式低档
- 补全场景对延迟敏感,V4 Pro 高档思考 130s 太慢
- Muse Code 免费,DeepSeek 低档模式也能接受
复杂组件生成 / Bug 修复 → DeepSeek V4 Pro 思考模式高档
- 质量优先,速度可以等
- AbortController 那种深度分析是其他模型做不到的
大型项目重构 / 全局理解 → Claude Fable 5(预算够的话)
- 1M 上下文两家都有,但 Claude 的代码理解深度略胜
- 价格贵 36-90 倍,团队预算充足才考虑
中文场景 / 国内项目 → DeepSeek V4 Pro 或 Kimi K3
- 中文理解两家都强,DeepSeek 的 Agent 能力更全面
- Kimi K3 在 SuperCLUE 中文评测上更高,但 Agent 数据不透明
如果你是个人开发者或小团队,DeepSeek V4 Pro 是当前性价比最高的选择,没有之一。如果你在大厂有预算,Claude Fable 5 + DeepSeek V4 Pro 组合使用,复杂任务给 Claude,日常任务给 DeepSeek。
七、思考与局限
7.1 思考模式很慢,但不是所有场景都需要
四轮测试下来,表明思考量越大,耗时越长,但结果质量越高。
Bug 修复花了 182 秒,但找出了 3 个 bug 还引入了 AbortController,这个是快速模型给不了的。
V4 Pro 的三档思考模式就是解决这个问题的。日常补全用低档快速响应,复杂分析用高档深度推理。但目前 API 层面思考模式的切换还不够透明,文档也比较简陋,期待后续完善。
7.2 不适合实时补全
130-182 秒的响应时间,意味着 V4 Pro 不适合做 IDE 里的实时代码补全。你在 VS Code 里敲一个字符等 2 分钟才出建议,体验肯定不好。
补全场景建议用一些简单的工具或者插件即可,免费还好用。V4 Pro 用来处理复杂任务 Agent即可。
7.3 价格优势是真实的
¥3/¥6 的价格意味着什么?
四轮测试总共消耗约 33000 tokens。按 Claude Fable 5 的价格算,大约 ¥5.4。按 DeepSeek 算,大约 ¥0.13。
一个月如果跑 1000 次类似任务,Claude 要 ¥5400,DeepSeek 只要 ¥130。省下来的钱够买一台 MacBook 了。
7.4 其他评测者发现了什么
我也看了其他人的评测,交叉验证一下。
程序员鱼皮用 Codex + 自建 Harness 跑了 7 个项目(动画/3D/游戏/全栈),结论是「前端效果拉胯,后端逻辑扎实」------前端 UI 渲染效果明显不如 Kimi K3 和 Claude Opus 5,但后端并发控制和逻辑严谨度没问题。
夕小瑶科技说跑了 4100 万 token,结论是「好模型但不是好同事」------V4 Pro 在 Codex 里闷头干活不说话(思考占比 84.5%),爱抄同门旧 session 的作业,前端和写作能力低于预期。但底子硬:100 并发 0 失败,缓存命中率 96%。
这些发现跟我的测试结果方向一致:V4 Pro 的代码逻辑和 bug 洞察力很强(后端思维),但前端 UI 渲染不是它的强项。我的四轮测试偏代码逻辑层面,所以表现很好。如果你要让它做复杂的 UI 设计或视觉效果,预期要调低一些。
还有一个共识:V4 Pro 的思考模式很慢,不适合实时补全。鱼皮提到 p50 延迟 4.9s、p99 延迟 12.3s,跟我的 130-182s 级别虽然不同(他跑的是 Codex 场景,我是单次 API 调用),但「慢」是一致的结论。
7.5 国产模型的 pride
V4 Pro 在 Terminal Bench 上跟 Anthropic 的旗舰模型打平,在 DeepSWE 上超越所有对手。这不是"国产模型追上了",而是"国产模型在某些维度领先了"。
作为开发工程师来说,只关心好不好用,贵不贵。V4 Pro 好用而且便宜,就这么简单。
面试题收尾
题目 1:useEffect 依赖数组与竞态处理
题目 :以下组件在 userId 快速切换时会出现什么问题?如何修复?
jsx
function UserList({ userId }) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setData);
}, [userId]);
return <div>{data?.name}</div>;
}
答案:
问题:userId 快速切换时,旧请求可能比新请求晚返回,导致 setData 被旧数据覆盖(竞态条件)。
修复方案------使用 AbortController:
jsx
useEffect(() => {
const controller = new AbortController();
fetch(`/api/users/${userId}`, { signal: controller.signal })
.then(res => res.json())
.then(setData)
.catch(err => {
if (err instanceof DOMException && err.name === 'AbortError') return;
console.error(err);
});
return () => controller.abort();
}, [userId]);
解析 :useEffect 的清理函数在依赖变化或组件卸载时执行。controller.abort() 会取消所有传入该 signal 的未完成请求。被取消的 fetch 会抛出 AbortError,需要在 catch 中静默处理。这是 V4 Pro 在 bug 修复测试中的核心思路。
题目 2:useReducer vs useState 选择
题目:什么场景下应该用 useReducer 而不是 useState?举例说明。
答案:
使用 useReducer 的场景:
- 状态转换逻辑复杂,涉及多个子状态联动
- 下一个状态依赖前一个状态的多个字段
- 状态更新逻辑需要复用
- 想要对状态变更做集中管理和追踪
举个------TodoList 组件有 todos、filter、loading 三个状态。如果用 useState 要写三个独立的 setter,逻辑分散。用 useReducer 把所有操作定义为 Action,reducer 集中处理状态转换:
jsx
// ✅ useReducer:状态转换逻辑集中
const [state, dispatch] = useReducer(reducer, initialState);
dispatch({ type: 'ADD_TODO', payload: text });
// ❌ useState:逻辑分散在多个事件处理函数中
const [todos, setTodos] = useState([]);
const [filter, setFilter] = useState('all');
// 每个操作都要手动管理多个 setter
解析:V4 Pro 在组件生成测试中自动选择了 useReducer + useState 的组合------reducer 管理 todos 数组,useState 管理 filter。这是合理的架构选择:核心数据用 reducer 集中管理,独立的 UI 状态用 useState 轻量处理。
题目 3:TypeScript DeepPartial 实现
题目 :手写一个 DeepPartial<T> 类型,递归地将所有属性变可选,并处理函数和数组的边界情况。
答案:
typescript
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object
? T[P] extends Function
? T[P]
: T[P] extends Array<infer U>
? Array<DeepPartial<U>>
: DeepPartial<T[P]>
: T[P];
};
解析:
关键点在于三层条件类型判断:
T[P] extends object--- 先判断是否对象类型T[P] extends Function--- 函数保持原样,不递归(否则() => void会被展开成{ (): void })T[P] extends Array<infer U>--- 数组递归处理元素类型U,而不是递归处理Array本身
V4 Pro 在类型推导测试中对这三个边界的处理完全正确。很多人手写 DeepPartial 会遗漏函数边界,因为 JavaScript 中 typeof fn === 'function' 但 Function extends object 也成立。
题目 4:AbortController 用法
题目:说明 AbortController 的工作原理,并给出在 React 中使用的完整模式。
答案:
AbortController 是 Web API 提供的请求取消机制:
tsx
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
setLoading(true);
const res = await fetch(url, { signal: controller.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json = await res.json();
setData(json);
} catch (err) {
if (err instanceof DOMException && err.name === 'AbortError') {
return; // 被取消的请求,静默处理
}
setError(err as Error);
} finally {
setLoading(false);
}
};
fetchData();
return () => controller.abort(); // ✅ 清理函数
}, [url]);
return { data, error, loading };
}
解析:
工作原理三步走:
- 创建
AbortController实例,拿到controller.signal - 把
signal传给fetch(url, { signal }) - 调用
controller.abort()取消所有使用该 signal 的请求
React 中的使用模式:在 useEffect 内部创建 controller,在清理函数中调用 abort()。这样当依赖变化或组件卸载时,未完成的请求自动取消。
V4 Pro 在 bug 修复和 Agent 任务中都使用了这个模式------说明它的训练数据中有大量现代 React 最佳实践的代码。
题目 5:AI 编程工具的选型考量
题目:作为前端团队负责人,你需要为 10 人团队选择 AI 编程工具。列出 3 个关键考量维度,并说明 DeepSeek V4 Pro 和 Claude Fable 5 在各维度上的优劣。
答案:
维度 1:任务匹配度
- 日常补全:两者高档模式都太慢,建议用低档/专用补全模型
- 复杂组件生成:Claude 略优(代码理解深度),但差距不大
- Bug 修复:DeepSeek 的 AbortController 级分析表现突出
- Agent 工程任务:两者都行,Claude 生态更成熟
维度 2:成本效率
- DeepSeek:¥3/¥6 每百万 token,10 人团队月成本约 ¥1000-3000
- Claude:~¥108/¥540 每百万 token,同任务量约 ¥36000-108000
- DeepSeek 的成本是 Claude 的 1/36 到 1/90
维度 3:数据安全与合规
- DeepSeek:国内公司,数据不出境,合规风险低
- Claude:美国公司,数据走 Anthropic 服务器,需评估合规要求
- 如果项目涉及敏感数据或行业监管,DeepSeek 的合规优势是决定性的
解析:AI 编程工具选型不是单纯比跑分,要综合考虑团队能力、预算约束和合规要求。V4 Pro 在成本和合规上有明显优势,Claude 在生态成熟度上领先。实际操作中,很多团队选择"主力 + 备选"的双模型策略。
写在最后
DeepSeek V4 Pro 经过测试确实超出预期。而且这种价格,可以让想用变成直接做,个人开发也能日常使用。
欢迎关注和评论~