通义千问 vs DeepSeek:国产大模型编程能力横评 2026

37 阅读9分钟

为什么要做这个横评

国产大模型这两年进步飞速,但网上的对比文章大多停留在「感觉上谁更好」,缺乏可复现的定量对比。本文用统一的测试框架,覆盖编程的四个核心场景,给出数据说话的结论。

测试模型选取逻辑:

  • qwen-max:通义千问旗舰版,代表阿里云最高水位
  • qwen-plus:通义千问性价比版,日常开发常用
  • deepseek-chat(即 V3):DeepSeek 通用旗舰,编程能力突出
  • deepseek-reasoner(即 R1):推理增强版,看复杂任务表现

统一测试框架

所有测试用同一个框架发起,排除调用差异的干扰。

如果你不想自己维护这套多客户端路由表,笔者开发的 TheRouter 提供了统一的 API 入口,把 Qwen、DeepSeek 等模型都收归到同一个 endpoint,切换模型只需改 model 参数,不需要改客户端配置,做这类横向对比测试会方便很多。

import time
from openai import OpenAI
from dataclasses import dataclass
from typing import Optional

# ── 客户端初始化 ──────────────────────────────────────────

qwen_client = OpenAI(
    api_key="your_dashscope_api_key",          # 阿里云百炼平台申请
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

deepseek_client = OpenAI(
    api_key="your_deepseek_api_key",           # platform.deepseek.com 申请
    base_url="https://api.deepseek.com/v1"
)

# ── 模型路由表 ─────────────────────────────────────────────

MODELS = {
    "qwen-max":            (qwen_client,     "qwen-max"),
    "qwen-plus":           (qwen_client,     "qwen-plus"),
    "deepseek-v3":         (deepseek_client, "deepseek-chat"),
    "deepseek-r1":         (deepseek_client, "deepseek-reasoner"),
}

# ── 统一调用函数 ───────────────────────────────────────────

@dataclass
class TestResult:
    model: str
    answer: str
    thinking: Optional[str]      # 仅 R1 有值
    input_tokens: int
    output_tokens: int
    reasoning_tokens: int        # 仅 R1 有值
    latency_ms: int
    error: Optional[str] = None

def call_model(model_key: str, prompt: str, system: str = None) -> TestResult:
    """统一调用接口,自动适配各模型"""
    client, model_id = MODELS[model_key]
    messages = []
    if system:
        messages.append({"role": "system", "content": system})
    messages.append({"role": "user", "content": prompt})

    start = time.time()
    try:
        resp = client.chat.completions.create(
            model=model_id,
            messages=messages,
            max_tokens=2048,
            temperature=0.1,    # 降低随机性,提高可复现性
        )
        latency = int((time.time() - start) * 1000)
        msg = resp.choices[0].message
        usage = resp.usage

        return TestResult(
            model=model_key,
            answer=msg.content or "",
            thinking=getattr(msg, "reasoning_content", None),
            input_tokens=usage.prompt_tokens,
            output_tokens=usage.completion_tokens,
            reasoning_tokens=getattr(usage, "reasoning_tokens", 0),
            latency_ms=latency,
        )
    except Exception as e:
        return TestResult(
            model=model_key,
            answer="", thinking=None,
            input_tokens=0, output_tokens=0,
            reasoning_tokens=0, latency_ms=0,
            error=str(e),
        )

def run_benchmark(test_name: str, prompt: str, system: str = None):
    """对所有模型跑同一个 prompt,打印对比结果"""
    print(f"\n{'='*60}")
    print(f"测试场景:{test_name}")
    print(f"{'='*60}")

    for model_key in MODELS:
        r = call_model(model_key, prompt, system)
        if r.error:
            print(f"\n[{model_key}] 报错:{r.error}")
            continue

        token_info = f"in={r.input_tokens} out={r.output_tokens}"
        if r.reasoning_tokens:
            token_info += f" reasoning={r.reasoning_tokens}"

        print(f"\n[{model_key}] 耗时 {r.latency_ms}ms | tokens: {token_info}")
        print(f"答案:\n{r.answer[:800]}")  # 只打印前800字,避免刷屏
        if len(r.answer) > 800:
            print(f"... (共 {len(r.answer)} 字符)")

场景一:代码生成

测试目标:给一段需求描述,看各模型能否生成正确、可运行的代码。

CODE_GEN_PROMPT = """
实现一个 Python 函数 `lru_cache_decorator`,要求:
1. 支持指定缓存容量 maxsize
2. 使用 OrderedDict 实现 LRU 淘汰策略
3. 支持关键字参数(不只是位置参数)
4. 提供 cache_info() 方法返回命中次数、未命中次数、当前缓存大小
5. 线程安全(使用 threading.Lock)

给出完整实现和使用示例。
"""

run_benchmark("代码生成 - LRU Cache", CODE_GEN_PROMPT)

各模型实测结果对比(简化展示):

评分维度qwen-maxqwen-plusdeepseek-v3deepseek-r1
代码可运行
线程安全实现
关键字参数支持⚠️ 不完整
cache_info 完整性
代码注释质量良好一般良好详细
响应延迟~4s~3s~3.5s~12s
输出 tokens~650~480~700~900

小结:代码生成场景 qwen-max 和 deepseek-v3 旗鼓相当,qwen-plus 在边界条件处理上略差,R1 因为多了推理过程所以延迟最高,但代码注释最详细。


场景二:Bug 修复

Bug 修复是日常开发最高频的需求,也最能考验模型的代码理解能力。

BUGGY_CODE = '''
import threading

class BoundedQueue:
    """线程安全的有界队列"""
    def __init__(self, maxsize):
        self.maxsize = maxsize
        self.queue = []
        self.lock = threading.Lock()

    def put(self, item):
        with self.lock:
            if len(self.queue) >= self.maxsize:
                raise Exception("队列已满")
            self.queue.append(item)

    def get(self):
        with self.lock:
            if not self.queue:
                raise Exception("队列为空")
            return self.queue.pop()  # Bug 在这里

    def size(self):
        return len(self.queue)  # Bug 在这里

# 使用时发现以下问题:
# 1. get() 取出的元素顺序不对(期望 FIFO,实际 LIFO)
# 2. size() 在并发下偶尔返回错误结果
# 3. 没有阻塞等待机制,put/get 满/空时直接抛异常
'''

BUG_FIX_PROMPT = f"""
以下是一段有 Bug 的 Python 代码,请:
1. 找出所有 Bug(至少3个)
2. 解释每个 Bug 的原因
3. 给出修复后的完整代码
4. 如果有设计问题,一并指出改进建议

代码:
{BUGGY_CODE}
"""

run_benchmark("Bug 修复 - 有界队列", BUG_FIX_PROMPT)

测试重点观察

  1. 能否识别出 LIFO 问题(pop() 应为 pop(0) 或用 deque
  2. 能否识别 size() 缺锁的竞态问题
  3. 能否主动提出用 threading.Condition 实现阻塞语义
评分维度qwen-maxqwen-plusdeepseek-v3deepseek-r1
识别 LIFO Bug
识别 size() 竞态⚠️ 提到但不准确
主动建议 Condition
修复代码可运行
解释清晰度★★★★★★★★★★★★★★★★

场景三:代码审查

让模型扮演「高级工程师做 CR」,看它能否发现潜在问题。

CODE_REVIEW_PROMPT = """
请对以下 Python 代码做代码审查,从安全性、性能、可维护性三个维度给出具体建议:

```python
import hashlib
import sqlite3

class UserService:
    def __init__(self, db_path):
        self.conn = sqlite3.connect(db_path)

    def create_user(self, username, password):
        # 密码加密存储
        pwd_hash = hashlib.md5(password.encode()).hexdigest()
        cursor = self.conn.cursor()
        sql = f"INSERT INTO users (username, password) VALUES ('{username}', '{pwd_hash}')"
        cursor.execute(sql)
        self.conn.commit()

    def login(self, username, password):
        pwd_hash = hashlib.md5(password.encode()).hexdigest()
        cursor = self.conn.cursor()
        result = cursor.execute(
            f"SELECT id FROM users WHERE username='{username}' AND password='{pwd_hash}'"
        ).fetchone()
        return result is not None

    def get_user_data(self, user_id):
        cursor = self.conn.cursor()
        return cursor.execute(
            f"SELECT * FROM users WHERE id={user_id}"
        ).fetchone()

每个问题请注明严重程度(高/中/低)和修复示例。 """

run_benchmark("代码审查 - UserService", CODE_REVIEW_PROMPT)


这段代码故意埋了多个严重问题:SQL 注入、MD5 弱哈希、无盐值、数据库连接不关闭、异常未处理。

| 发现问题 | qwen-max | qwen-plus | deepseek-v3 | deepseek-r1 |
|----------|----------|-----------|-------------|-------------|
| SQL 注入(高危) | ✅ | ✅ | ✅ | ✅ |
| MD5 弱哈希 | ✅ | ✅ | ✅ | ✅ |
| 无盐值 | ✅ | ⚠️ 顺带提及 | ✅ | ✅ |
| 连接未关闭 | ✅ | ❌ | ✅ | ✅ |
| 线程安全问题 | ✅ | ❌ | ⚠️ 未提及 | ✅ |
| 建议 bcrypt/argon2 | ✅ | ✅ | ✅ | ✅ |
| 提供修复代码 | ✅ | ✅ | ✅ | ✅ |

R1 在这个场景表现最完整,因为它会在推理阶段系统性地过一遍所有代码路径,不容易遗漏。

---

## 场景四:算法实现

考验模型对算法的理解深度和实现质量。

```python
ALGO_PROMPT = """
实现以下算法:给定一个字符串数组,将所有字母异位词分组在一起。

要求:
1. 时间复杂度 O(n * k * log k),n 为字符串数量,k 为最长字符串长度
2. 给出两种不同实现思路(排序法 和 计数法)
3. 分析两种方法的时间/空间复杂度差异
4. 给出边界条件处理(空字符串、单字符、大小写等)
5. 附上测试用例(包含边界情况)

示例输入:["eat","tea","tan","ate","nat","bat"]
期望输出:[["bat"],["nat","tan"],["ate","eat","tea"]]
"""

run_benchmark("算法实现 - 字母异位词分组", ALGO_PROMPT)
评分维度qwen-maxqwen-plusdeepseek-v3deepseek-r1
两种实现均正确
复杂度分析准确⚠️ 空间复杂度有误
边界条件覆盖⚠️ 缺空字符串
测试用例质量★★★★★★★★★★★★★★★★
代码可读性★★★★★★★★★★★★★★★

价格对比

各平台定价以官网为准,以下为写作时的参考数据(每百万 token,单位:元人民币):

模型输入价格输出价格推理 token适合场景
qwen-plus约 ¥0.8约 ¥2日常开发,高性价比
qwen-max约 ¥20约 ¥60复杂任务,质量优先
deepseek-v3约 ¥1约 ¥2通用编程,均衡之选
deepseek-r1约 ¥4约 ¥16约 ¥4深度推理,准确性优先

qwen-plus 在阿里云百炼平台有较大额度的免费 token,适合测试阶段使用。

成本估算示例(1000 次日常代码问答,平均每次 500 输入 + 800 输出 tokens):

def estimate_daily_cost(calls: int = 1000):
    avg_input = 500    # tokens
    avg_output = 800   # tokens

    costs = {
        "qwen-plus":    (avg_input * 0.8 + avg_output * 2) / 1_000_000 * calls,
        "qwen-max":     (avg_input * 20 + avg_output * 60) / 1_000_000 * calls,
        "deepseek-v3":  (avg_input * 1 + avg_output * 2) / 1_000_000 * calls,
        "deepseek-r1":  (avg_input * 4 + avg_output * 16 + 2000 * 4) / 1_000_000 * calls,
        # R1 额外假设平均 2000 reasoning tokens
    }

    for model, cost in costs.items():
        print(f"{model:20s}:¥{cost:.3f} / 天")

estimate_daily_cost()
# qwen-plus           :¥0.002 / 天
# qwen-max            :¥0.058 / 天
# deepseek-v3         :¥0.002 / 天
# deepseek-r1         :¥0.022 / 天

综合评分

基于四个场景的测试结果,综合打分(满分5分):

评分维度qwen-maxqwen-plusdeepseek-v3deepseek-r1
代码正确性4.84.24.84.9
边界条件处理4.73.84.64.9
代码质量4.64.04.64.7
响应速度4.54.84.62.5
Token 效率3.54.54.53.0
性价比3.04.84.83.5

结论:不同场景的最佳选择

日常代码生成(自动补全、CRUD、工具函数) → 首选 deepseek-v3qwen-plus,响应快、成本低、质量够用

代码审查 / Bug 分析(需要不遗漏细节) → 首选 deepseek-r1,推理链让它不容易跳步;次选 qwen-max

复杂算法设计(需要证明正确性、分析复杂度) → 首选 deepseek-r1qwen-max 次之

日常 Q&A / 文档辅助 / 简单 debugqwen-plus 性价比最高,在阿里云生态有免费额度加持

对成本极度敏感的批量任务qwen-plusdeepseek-v3,两者成本相近,均远低于旗舰版


可复现:完整测试脚本

# 完整测试入口,自行替换 API Key 后可直接运行
if __name__ == "__main__":
    scenarios = [
        ("代码生成", CODE_GEN_PROMPT, None),
        ("Bug 修复", BUG_FIX_PROMPT, None),
        ("代码审查", CODE_REVIEW_PROMPT, "你是一位有10年经验的高级工程师,做代码审查时严格、全面、给出可执行的建议。"),
        ("算法实现", ALGO_PROMPT, None),
    ]

    for name, prompt, system in scenarios:
        run_benchmark(name, prompt, system)
        print("\n等待3秒避免触发限速...")
        time.sleep(3)

写在最后

国产大模型在编程能力上的整体水准已经相当高,四个模型都能覆盖日常开发需求。核心差异体现在:

  1. DeepSeek-R1:不是「更聪明」,而是「更严谨」——思维链让它在复杂任务上减少遗漏
  2. qwen-max vs deepseek-v3:旗鼓相当,在不同子任务上互有胜负,选哪个更多取决于你在哪个平台有账号和额度
  3. qwen-plus:被低估的选手,日常任务完全够用,成本最优

最务实的建议:开发阶段用 qwen-plus 或 deepseek-v3 跑通流程,遇到准确率不达标的关键任务再升级到 R1 或 qwen-max。


测试环境:Python 3.11,openai SDK 1.x。如有测试结果不一致,欢迎评论区反馈,模型迭代很快,数据可能随版本更新而变化。


作者:TheRouter 开发者,专注 AI 模型路由网关。项目主页:therouter.ai