木鸡SteadyGame——大模型评测作业
大模型评测作业
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 202601 福大-软件工程实践-W 班 |
| 这个作业要求在哪里 | 软件工程实践——大模型评测作业 |
| 这个作业的目标 | 用固定车型数据搭一个多轮购车决策环境,让两个模型各跑 18 次独立任务,量化比较推荐结果、上下文保持、工具调用、结构化输出、Token 与响应时间,并在此基础上分析软件工程问题与产品机会。 |
| 其他参考文献 | 《构建之法》相关章节;CNNIC、IDC、中汽协、中国汽车流通协会、国家统计局公开资料,详见文末。 |
目录
- 大模型评测作业
- 第一部分:调研与评测
- 模型一:DeepSeek V4.1 Flash
- 使用体验
- 自动化测试
- 结论
- 模型二:Qwen 3.7 Plus
- 使用体验
- 自动化测试
- 结论
- 实验设计、量化结果与案例
- 1. 实验设置
- 2. 三个场景和事前预期
- 3. 程序结构和 Function Calling
- 4. 评分规则和计算方法
- 5. 主要结果
- 6. 失败与边界案例
- 用户访谈记录
- 第二部分:分析
- 开发时间估计
- 平台与测试系统的三层分析
- 同类产品对比与选型
- 大模型对现实生活的影响
- 软件工程方面的建议
- BUG 存在的原因分析
- 改进方案与方案优选
- 市场概况
- 产品规划:NABCD
- 代码、数据与参考资料
第一部分:调研与评测
本次比较的是两个可通过 API 调用的模型产品。为了避免把网页体验、模型版本和 API 结果混在一起,本文的正式成绩全部来自固定脚本运行的 DeepSeek 与 Qwen API;两边均使用多轮任务、同一份教学模拟车型数据和相同的本地函数工具。
模型一:DeepSeek V4.1 Flash
使用体验
介绍。 DeepSeek 开放平台是深度求索面向开发者的模型服务:注册账号、创建 API Key,就能按官方文档把模型接进自己的程序;同一家还提供面向普通用户的网页/客户端对话。平台把模型分成通用对话与推理增强两类,本次使用的 deepseek-flash 属于 DeepSeek V4.1 Flash 系列,官方标注支持 Tool Calls。
使用体验(按两个入口各走一遍)。
- 入口一:网页/客户端对话(普通用户视角)。 打开就是一句“探索未至之境”加一个输入框,不需要注册开发者账号,也没有参数要调。输入框下只留了两个开关:深度思考和智能搜索;再往下一排是“和 DeepSeek 对话 / API 开放平台 / Harness 桌面端”三个入口。也就是说,普通用户和开发者被清楚地区分成两条路径,不会互相干扰。本组两个都走了:网页端看“聊起来顺不顺”,桌面端 Harness 看“能不能自己干活”(见下面的功能广度)。
- 入口二:开放平台控制台(开发者视角,本次量化评测走这条)。 注册后在控制台创建 API Key,能看到可用模型、价格与用量;把 Key 写进本机
local.env(不进代码、不进博客),先发一次最小请求确认额度与连通性,再跑 18 个正式任务。真正用到的能力只有两个:多轮对话和 Function Calling——模型收到购车需求后,请求程序查询车型库、比较参数,再根据工具返回的真实结果组织答案。 - 一次任务跑完,我们看到什么。 每次任务会留下 5 轮原文、解析出的字段、Token 数、累计请求耗时和工具调用记录;这些都能落进 CSV,所以结论可以逐条回查。这一点是纯网页对话给不了的。

截图顶部还有一条更新公告:“DeepSeek V4.1 Flash 现已更新至 V4.1-Flash-1017 版本,项目开发能力提升显著,更低成本、更快速完成任务;新增 API 支持网页搜索与抓取”。这条公告本身是产品体验的一部分——它说明这个模型线在持续迭代;也提醒一件事:同一系列名下的版本会变,所以我们的运行记录里同时保存了请求用的模型 ID 和接口返回的模型标识。
试跑时程序会打印什么。 每个任务跑完会输出一行 task_id / 是否解析成功 / final_choice_id / token 数 / 工具次数,例如 A-A-R1: ok; final=null; tokens=42972; tools=8——final=null 是因为场景 A 的正确答案就是“无匹配”。确认接口、数据与日志都正常之后,才按同样的命令去掉 --pilot 跑正式任务。截图见附件 体验截图/。
功能广度:桌面端把它当“工作台”,不是聊天框。 下面这张是 Harness 桌面端的插件设置页,能看出产品的定位:
- 内置插件:子智能体(设置递归层级、数量与模型)、网页搜索(设置搜索提供方)、Agent 循环(控制 Agent 派发工具调用的方式)、终端(限制每条命令最多跑多久、最多输出多少)。
- 实验性插件:智能体团队(团队协作、共享任务看板)、语音输入(本地 SenseVoice 转写)、自动授权审查(由模型在每次工具调用前判断是否授权)、开发者工具(查看原始数据与调试后端)。
真正“能干活”的四项都在内置里:工具派发、终端、联网、子任务拆分。而“自动授权审查”被放在实验性并默认关闭,说明连厂商自己也把“模型能不能自己决定执行命令”当成需要谨慎对待的部分。对我们评测的含义很直接:本次只用了 API 的单次工具调用,没有涉及终端和子智能体,所以它在这条更强的 Agent 线上是否稳定,本文没有证据、也不下结论。

它解决了我们的问题吗。 解决了“把模型接进自己的程序”这一层:输出可以被日志和 CSV 保存,可以复现,可以按任务统计 Token。但它没有替我们解决工程侧的问题——密钥管理、请求超时、工具参数解析、JSON 校验、费用控制,全都要自己写。单独看网页对话是否流畅,并不能说明 API 返回一定满足机器解析要求;这次正式运行中两者是各自独立的事情。
优缺点分析。
| 维度 | 本次观察 |
|---|---|
| 数据量 | 单任务平均 41,977 Token,是本组的较高值;每次请求都携带完整上下文,5 轮对话的输入 Token 会线性叠加。 |
| 界面 | 以控制台 + 接口文档为主,没有专门面向“任务级评测”的视图:看不到单次任务的调用链,也没有现成的失败标记(桌面端 Harness 有「轨迹」页签可以回看步骤,但那是另一个产品界面,且不入我们的评测流程)。 |
| 功能 | Tool Calls 可用,且在 9/9 个比较轮都正确调用;严格 JSON 输出 45/45 全部合格。 |
| 准确度 | 9/9 最终选择落在事前登记的可接受集合内,硬约束、数据真实性、多轮一致性均无扣分。 |
| 用户体验 | 平均累计 API 响应时间 30.6 秒/任务,是本次两个模型中较短的一个;缺点是 Token 花得多,较高推理强度下回答偏长。 |
用户(也就是我们这些开发者)的改进意见。 一是希望在控制台直接看到“某一次任务”的费用与 Token 拆分,而不只是账户总量,便于做成本回归;二是在文档里更清楚地说明推理强度参数对输出长度和延迟的影响,避免只凭直觉调参;三是错误码能进一步区分限流、余额不足、参数非法,现在都需要读响应正文才能判断。
产品体验评分(只评价产品本身,与前面的任务得分无关)。 参照同类评测的常见做法,把“好不好用”拆成五项、各 20 分,便于和另一个产品对照:
| 维度 | 分数 | 打分依据 |
|---|---|---|
| 核心功能 | 18 | 18 个任务里没有出现接口级失败,多轮对话与 Tool Calls 全程可用。 |
| 细节 | 16 | 控制台能看到模型、价格与用量;缺少单次任务的费用与调用链。 |
| 用户体验 | 15 | 接入流程短、文档可查;错误提示不够细分,调参影响要靠试。 |
| 辅助功能 | 16 | 有官方文档、定价页和模型列表;没有任务级调试面板。 |
| 效能 | 17 | 平均累计响应 30.6 秒/任务,交互式场景可以接受。 |
| 合计 | 82/100 |
自动化测试
测什么、怎么跑。 DeepSeek 的正式 API 标识是 deepseek-flash,官方文档将其标注为 DeepSeek V4.1 Flash 系列并支持 Tool Calls;脚本启用 reasoning_effort=high 与 thinking。运行分三步,都不需要改代码:
python .\购车自动化评测.py --preview # 只打印执行计划,不发请求、不花钱
python .\购车自动化评测.py --pilot --model A # 单模型小样本试跑,确认接口与数据
python .\购车自动化评测.py --run # 正式跑 2 模型 × 3 场景 × 3 次 = 18 个任务
密钥只从环境变量或本机 local.env 读取(脚本里没有硬编码),所以同一份代码换台机器只要填两行变量就能复现。
一个任务内部到底发生了什么。 每个"模型 × 场景 × 重复"从一条全新的 system 消息开始(system 里带固定车型表和输出约定),随后依次发送 5 个用户轮次;同一任务内保留全部历史,任务之间不共享任何上下文。每一轮的处理是:发请求 → 如果模型要求调用工具,本地执行 query_vehicle_catalog 或 compare_vehicles 并把结果作为 role=tool 消息回传 → 模型据此继续,直到给出最终答复;单轮最多允许 5 次工具往返,超过就抛错并记录,避免模型反复调用把任务挂死。整轮结束后,这一轮的原文、解析结果、Token、耗时、工具次数全部写入 raw_turns.jsonl,再汇总进 turns.csv。
记录了哪些字段。 逐轮记录在 turns.csv:task_id / model / model_id / api_model_ids / scenario_id / repeat / turn / stage / candidate_ids / final_choice_id / json_parse_ok / latency_s / prompt_tokens / completion_tokens / api_requests / tool_calls / tool_errors / response / error。任务级汇总在 tasks.csv,多出 final_choice_match、all_candidate_ids_known、total_tokens、api_requests_including_tool_followups、estimated_list_rate_cost 等列。第 4 轮的对比表被单独抽到 comparison_table.csv(61 行)。
失败怎么处理。 三类异常都落库、不吞:HTTP 错误或超时抛 RuntimeError 写进 error 列;工具参数不是合法 JSON 时记 tool_errors 并把错误回传给模型(让它自己修);运行中断可用 --resume <运行目录> 续跑,已完成的 task_id 跳过、只补缺失任务,避免重复计费。
本次运行的实际数字。
| 项目 | DeepSeek V4.1 Flash |
|---|---|
| 完整任务 / 用户轮次 | 9 / 45 |
| API 请求总数(含工具续写) | 99(平均 11.0 次/任务) |
| 工具调用总数 | 56(平均 6.2 次/任务) |
| 工具错误 | 0 |
| Token 合计 / 每任务均值 | 377,793 / 41,977 |
| 累计 API 响应时间合计 / 每任务均值 | 275.8 秒 / 30.6 秒 |
| 最终选择命中(程序判定) | 9/9 |
| 候选 ID 全部来自车型库(程序判定) | 9/9 |
| 原文严格 JSON(程序判定) | 45/45 |
一次运行实录:任务 A-B-R1(场景 B,第 1 次)。 把一次真实运行按“问什么、答什么”摊开,比任何汇总数字直观。下面每轮都是原文节选,括号里是程序同时记下的开销;完整原文见 raw_turns.jsonl 的 task_id=A-B-R1。
第 1 轮|我们问:「家里通常有4到5人乘车,每月几次高速长途,没有固定充电桩,模拟裸车预算不超过17.5万元。请先给初步候选。stage填initial。」
DeepSeek 答(节选):
candidate_ids为 E1、P1、H1,final_choice_id为null。理由原文:「按预算≤17.5万与座位数≥5两项硬约束筛选,符合条件的是E1、P1、H1共3款;E2(18.8万)超出预算,不纳入候选……初步候选排序建议为P1优先,H1次之,E1作为备选;这是初步候选,尚未确定最终车型。」同时列了 5 条unknowns,包括「未提供明确的动力形式硬性要求」「模拟裸车价不含税费、保险、上牌费及优惠,实际落地价未知」。
(4,346 token|7.2 秒|工具 2 次)
第 2 轮|我们问:「增加动力硬约束:不考虑纯电车型,插电混动或燃油都可以。更新候选,其他条件不变。stage填update。」
DeepSeek 答(节选): 候选收缩为 P1、H1。理由原文:「按要求新增‘不考虑纯电’硬约束后重新筛选:原候选E1已被排除,E2则因18.8万元超出预算、且属于纯电而不再考虑;剩余P1与H1均满足全部硬约束。」
(6,708 token|5.4 秒|工具 1 次)
第 3 轮|我们问:「增加硬约束:至少5座、后备厢至少450升。在满足硬约束后,优先考虑车型表中能耗数值较低者。说明有效条件并更新候选。stage填update。」
DeepSeek 答(节选): 候选不变。这一轮最值得看的是它的
unknowns:「能耗字段口径不完全可比:P1为‘亏电油耗’,H1为综合油耗;如果P1经常充电,其等效能耗会更低,而本次无家充条件,因此未计入充电场景」。
(9,277 token|9.3 秒|工具 1 次)
第 4 轮|我们问:「比较当前候选的价格、动力、CLTC续航、座位数、后备厢、能耗,并逐项标记硬约束满足情况;未知或不适用如实标记。stage填comparison。」
DeepSeek 答(节选): 比较表逐项写了「价格:16.8万≤17.5万,满足;动力:插电混动,满足(非纯电)……」,H1 的续航如实标「不适用(燃油车,车型库中该字段为null,标为不适用,不作为违规)」。
(11,284 token|7.0 秒|工具 1 次)
第 5 轮|我们问:「结合家庭人数、高速使用、无固定充电桩、预算和能耗偏好给最终推荐及取舍理由。不要补车型库外数据。stage填final。」
DeepSeek 答(节选):
final_choice_id为 P1。理由按条件逐条对应:「1) 家庭通常4-5人乘车——P1为5座,硬约束满足;2) 无固定充电桩——插电混动不充电也能当油车使用……选择P1的代价(取舍):比H1贵1.3万元,后备厢少50升(450L vs 500L)。」
(13,927 token|7.3 秒|工具 1 次)
这五轮里有四个可讲的地方。 一是上下文的线性膨胀:第 1 轮 4,346 token,第 5 轮 13,927 token,因为每轮都要重发完整历史,任务越长单轮越贵。二是每轮先查再答:5 轮共 6 次工具调用,没有一次绕过车型库直接编数据。三是第 3 轮那句"口径不可比"——它没有把 P1 的亏电油耗和 H1 的综合油耗直接摆在一起比大小,而是先声明不可比,这是它拿到"数据真实性 20 分"的具体来源。四是第 4 轮的比较表把 P1 列了两次(3 行里 P1 出现两次),这是复核原文时才发现的细节:JSON 结构完全合法、字段齐全,内容却有一次重复——结构合规不等于内容无误,这一条正好说明为什么机器只能筛格式,人得读内容。
结果怎么读。 三个场景的最终结果分别是:A 连续 3 次回答“无匹配”,B 连续 3 次推荐 P1,C 连续 3 次推荐 H1,九次都落在事前登记的可接受集合内。工具调用方面,9 个任务的比较轮全部调用了 compare_vehicles,参数均为固定车型库中的 ID。值得注意的是它的工具密度:平均每任务 6.2 次调用、11.0 次请求,说明它更倾向“先查再答”而不是凭上下文直接作答——这与后面 Qwen 的 3.1 次/任务形成对照。
复现方式。 附件里带了 manifest.json(模型 ID、参数、日期)和 protocol.json(车型、系统提示、五轮输入、预期结果、评分权重),拿到仓库按上面的三条命令即可重跑;中断过的运行用 --resume 指向原目录。
重复性与波动。 三个场景各跑 3 次,人工总分的极差全部为 0(A:100/100/100,B:100/100/100,C:100/100/100),说明在本次设置下它的输出质量没有随重复次数波动。需要提醒的是,极差为 0 不等于"永远稳定"——它更可能说明这 9 次恰好都落在评分细则的满分档,而不是模型没有方差。真正能验证方差的样本量远大于 3。
跑一遍要多久。 9 个任务的累计 API 请求时间为 275.8 秒,加上本地工具执行与落盘,全流程大约 5 分钟;这个成本意味着回归测试是负担得起的——改一版脚本重跑一次,代价比人工复核一小时小得多。这也是我们后来能把 18 个任务反复核对的原因。
详细的统一实验条件、场景表和评分口径见实验设计与结果;关键代码见程序结构和 Function Calling。
结论
在本次固定数据、提示词和参数下,DeepSeek 的人工评分平均为 100/100,最终结果命中率为 9/9,三类场景各自均为 3/3。它在工具调用覆盖和严格 JSON 输出方面表现稳定;其代价是单任务平均 Token 数较高(41,977)。样本只有每场景 3 次,评分也含人工判断,这个结论只适用于本次实验设置,不构成行业排名。
总体评价:推荐。 如果要做一个需要每轮稳定调用工具、返回可解析结果的购车助手原型,我会先用它;但上线前仍需把校验层补上——本次它的 45/45 只能说明“这批数据上没出错”,不说明“以后不会错”。
模型二:Qwen 3.7 Plus
使用体验
介绍。 阿里云百炼是模型服务平台,把模型服务、API Key、额度和用量放在同一个控制台里管理,同时提供与 OpenAI 兼容的 Chat Completions 接口。它面向普通用户的入口是通义千问(网页/App),面向开发者的是百炼控制台加 API——本节记录的是后者:本次没有用通义千问的网页对话做任务,只用百炼控制台与 API,这条边界先讲清楚,免得把网页端的观感混进 API 数据。
使用体验。
- 入口一:百炼体验中心(浏览器内直接对话,普通用户视角)。 左侧把模型能力分成文本 / 语音 / 视觉 / 全模态 / 向量五类,本次进的是“文本模型”,默认选中
Qwen3.8-Max。输入框下方有“深度思考”开关和一个联网检索按钮,再往下是“深度研究 / 头脑风暴 / 内容解析 / 网页开发”四个模板;右上角是“API 接入”,左下角是“API-KEY”——从试用到接进程序只隔着一个按钮,这对“先试再决定接不接”的开发者很友好。页脚还写着“所有内容均由人工智能模型生成,仅供参考,非官方立场”,属于必要的合规提示。需要说明的是,这个界面里默认的Qwen3.8-Max并不是我们正式评测的qwen3.7-plus,所以它只用于产品体验,不参与量化对比。 - 入口二:百炼控制台 + 兼容 API(开发者视角,本次量化评测走这条)。 在华北 2(北京)地域开通服务后,创建 API Key → 确认账户可用额度 → 填写本地环境变量 → 先小规模试跑 → 再开始正式任务。模型标识为
qwen3.7-plus(百炼文档说明它等同快照qwen3.7-plus-2026-05-26)。对开发者最直接的好处是:接口形态与 OpenAI 兼容,原先写好的调用代码几乎不用改就能换模型——这也是“同一脚本比两个模型”能成立的前提。 - 一次任务跑完,我们看到什么。 与 DeepSeek 侧同样的五轮记录、Token、耗时与工具调用;差异出现在中间轮次:工具该调没调、JSON 该合法却带了围栏。


这张截图值得多说一句:模型广场当时已经排到 Qwen3.8 系列,而我们这次调用的是 qwen3.7-plus 的快照。这不是错配,而是现实——平台的版本迭代比一次评测周期更快。工程上的含义很直接:报告里必须同时写清“请求用的模型 ID”和“接口返回的模型标识”,否则过几周连自己都说不清当时测的是哪个版本。
功能广度:一个控制台里装了五类模型能力。 体验中心左侧分文本 / 语音 / 视觉 / 全模态 / 向量五类,我们点进去看了三类,下图是这三个入口的实际界面:
- 向量模型:
Qwen3.7-Text-Embedding的文本检索演示,输入一句问题(如“肠道菌群代谢物与情绪调节机制”),页面把语料按语义分布成一团点云;上方还可以切到图片检索、视频检索,右下角能选“通用知识问答检索”等模式。 - 全模态模型:
Qwen3.8-Omni-Flash-Realtime的实时视频通话,预置了“严苛面试官 / 表达教练 / 智能助理 / 选购顾问 / 游戏 NPC”五个人设,也可以自建人设,点“开始通话”就进入实时对话。 - 视觉模型:
万相3.0-视频生成的视频创作,可选 1080P、时长 5 秒、是否带声音,下方有“灵感 / 资产”素材区。
这里有个细节值得点出来:全模态那五个预置人设里,“选购顾问”和我们这次的购车场景直接撞上了——说明平台自己也把“帮人挑东西”当作常见用法。但它是通用人设:不了解具体车型库、不知道价格口径、也没有来源标注。这正是我们为什么要自己搭固定数据加工具,而不是直接用平台现成的对话模板。



试跑与正式运行的日志都在附件 体验截图/ 与 实验数据/ 里,正式 18 次结果以 CSV 为准。
它解决了我们的问题吗。 同样解决了接入问题,而且迁移成本比预期低。但“能调用”不等于“能当接口用”:正式运行中它出现了漏调比较工具和 JSON 格式不合法两类问题,需要客户端自己校验。这一点恰好是本次评测最值得记录的地方(见失败与边界案例)。
优缺点分析。
| 维度 | 本次观察 |
|---|---|
| 数据量 | 单任务平均 28,147 Token,明显低于 DeepSeek,是本组在成本侧的加分项。 |
| 界面 | 控制台把模型、Key、额度、用量集中管理;但同样缺少“任务级调用链”视图,看不到某一轮到底有没有触发工具。 |
| 功能 | Function Calling 可用,但 9 个比较轮中有 2 次没有调用;另有 1 轮整体 JSON 非法、7 轮被 Markdown 围栏包裹。 |
| 准确度 | 9/9 最终选择命中,硬约束与数据真实性满分;但 unknowns 字段在 9 个任务中全部为空,5 分全部丢失。 |
| 用户体验 | 平均累计 API 响应时间 119.9 秒/任务,约为 DeepSeek 的 3.9 倍;较长的等待对交互式产品不友好。 |
用户(也就是我们这些开发者)的改进意见。 一是希望控制台能看到每轮是否触发工具、参数是什么、有没有失败,这比只看总 Token 有用得多;二是希望能开启“严格结构化输出”开关,从服务端保证 JSON 合法,减少客户端兜底;三是响应时间和并发限制可以在文档里给出更明确的参考区间,方便换算成产品的超时与重试策略。
产品体验评分(只评价产品本身,与前面的任务得分无关)。 与 DeepSeek 用同一套五项标准,便于对照:
| 维度 | 分数 | 打分依据 |
|---|---|---|
| 核心功能 | 17 | 18 个任务全部跑通,最终选择 9/9 命中;但比较轮漏调工具 2 次。 |
| 细节 | 16 | 控制台把 Key、额度、用量放在一起,比“分散在多个页面”省事。 |
| 用户体验 | 15 | 兼容接口让换模型几乎零改动;错误也偏隐晦,格式问题不主动暴露。 |
| 辅助功能 | 17 | 文档、模型广场、快照版本、免费额度说明比较完整。 |
| 效能 | 12 | 平均累计响应 119.9 秒/任务,交互式场景偏慢。 |
| 合计 | 77/100 |
自动化测试
测什么、怎么跑。 Qwen 的正式 API 标识是 qwen3.7-plus,本次启用 enable_thinking=true,走百炼北京地域的 OpenAI 兼容接口。运行命令与 DeepSeek 完全相同,只把 --model 换成 B:
python .\购车自动化评测.py --pilot --model B # 确认额度与接口后小样本试跑
python .\购车自动化评测.py --run # 与模型 A 一起跑满 18 个任务
与 DeepSeek 的“同”与“不同”。 相同的是 system prompt、三组场景、固定车型表、JSON 输出字段、两个本地工具、超时设置与记录方式;不同的是推理参数——百炼用 enable_thinking=true,DeepSeek 用 reasoning_effort=high 加 thinking。两家接口的参数名和语义不一致,不能声称参数完全一致,这一点在实验设置里也单独注明过。
本次运行的实际数字。
| 项目 | Qwen 3.7 Plus |
|---|---|
| 完整任务 / 用户轮次 | 9 / 45 |
| API 请求总数(含工具续写) | 73(平均 8.1 次/任务) |
| 工具调用总数 | 28(平均 3.1 次/任务) |
| 工具错误 | 0 |
| Token 合计 / 每任务均值 | 253,327 / 28,147 |
| 累计 API 响应时间合计 / 每任务均值 | 1,079.3 秒 / 119.9 秒 |
| 最终选择命中(程序判定) | 9/9 |
| 候选 ID 全部来自车型库(程序判定) | 9/9 |
| 原文严格 JSON(程序判定) | 37/45(去围栏后 44/45) |
一次运行实录:任务 B-B-R1(同样是场景 B、第 1 次)。 选它是因为和上面 DeepSeek 的 A-B-R1 输入完全相同,可以逐轮对照。同样按“问什么、答什么”摊开:
第 1 轮|我们问(与 DeepSeek 那句一字不差):「家里通常有4到5人乘车,每月几次高速长途,没有固定充电桩,模拟裸车预算不超过17.5万元。请先给初步候选。stage填initial。」
Qwen 答(节选):
candidate_ids为 E1、P1、H1,final_choice_id为null,unknowns是空数组。理由原文:「初步筛选出符合预算和座位数要求的车型。结合无固定充电桩及高速长途场景,插电混动(P1)与燃油(H1)可加油无焦虑,纯电(E1)存在补能不便的风险,暂留作候选对比。」
(5,000 token|63.1 秒|工具 0 次)
⚠️ 它写的是“初步筛选出”,但这一轮没有调用query_vehicle_catalog。
第 2 轮|我们问:「增加动力硬约束:不考虑纯电车型,插电混动或燃油都可以。更新候选,其他条件不变。stage填update。」
Qwen 答(节选): 候选收缩为 P1、H1。理由全文只有一句:「已根据新增硬约束排除纯电车型E1,剩余P1(插电混动)与H1(燃油)均满足所有当前条件,进入下一步对比。」
(4,442 token|16.0 秒|工具 1 次)——这是它全程唯一一次调用工具。
第 3 轮|我们问:「增加硬约束:至少5座、后备厢至少450升。在满足硬约束后,优先考虑车型表中能耗数值较低者。说明有效条件并更新候选。stage填update。」
Qwen 答(节选): 这一轮的
final_choice_id就已经填成"P1",理由是:「……P1的能耗数值(5.2)低于H1(7.8),因此推荐P1作为最终选择。」按输出协议,第 3 轮仍是update、final_choice_id应为null——它提前下了结论。unknowns依旧是空数组。
(4,569 token|36.7 秒|工具 0 次)
第 4 轮|我们问:「比较当前候选的价格、动力、CLTC续航、座位数、后备厢、能耗,并逐项标记硬约束满足情况;未知或不适用如实标记。stage填comparison。」
Qwen 答(节选): 比较表 2 行,
constraint_check写成紧凑的括号式:P1 是「价格16.8万(满足<=17.5万); 动力插电混动(满足非纯电); 座位5(满足>=5); 后备厢450L(满足>=450L); 能耗数值5.2(满足较低偏好)」。内容与固定表一致,但这一轮没有调用compare_vehicles,参数是从上下文复述的。
(5,265 token|40.0 秒|工具 0 次)
第 5 轮|我们问:「结合家庭人数、高速使用、无固定充电桩、预算和能耗偏好给最终推荐及取舍理由。不要补车型库外数据。stage填final。」
Qwen 答(节选): 理由按点罗列:「1) 家庭4-5人乘车:两款均为5座,均满足。2) 高速长途+无固定充电桩:两款均可加油,无续航焦虑,P1亏电油耗5.2升/100公里低于H1的7.8升/100公里……3) 预算:P1为16.8万、H1为14.5万,均在17.5万以内」。
final_choice_id为 P1。
(4,180 token|13.7 秒|工具 0 次)
和 DeepSeek 的同场景对照,差距一目了然。
| 指标 | DeepSeek A-B-R1 | Qwen B-B-R1 |
|---|---|---|
| API 请求 | 10 | 6 |
| 工具调用 | 6 | 1 |
| Token | 45,542 | 23,456 |
| 累计耗时 | 36.2 秒 | 169.5 秒 |
unknowns 条数 | 4–6 条/轮 | 全程 0 条 |
| 最终选择 | P1(命中) | P1(命中) |
两个任务最后都推荐了 P1,但过程完全不同:DeepSeek 查了 6 次、花了 36 秒;Qwen 只查了 1 次、花了 170 秒。这解释了一个容易被误读的现象——Qwen 的 Token 更省,省下来的正是“少查几次”的那部分,而漏掉的恰恰是可核验性。省钱和可核验在这一次运行里是同一枚硬币的两面。
顺带修正我们自己的一处口径。 上面的实录让我们发现:正文前面用的“比较轮工具调用 9/9 对 7/9”只统计了第 4 轮,可实际上第 1–3 轮同样要求“筛选车型前先调用工具”。按完整口径重新数(第 1–4 轮共 36 个必要调用点):DeepSeek 36/36,Qwen 27/36(75%)。第 5 轮不调工具是合理的,最终建议不必再查一次。我们保留“比较轮”作为主指标,是因为它最稳定、最容易复核;但真正的差距比 7/9 看起来更大,这一点应当说清楚,而不是让读者以为只有比较轮出了问题。
三个数字能说明问题。 一是工具密度:6.2 次/任务对 3.1 次/任务,DeepSeek 更愿意先查再答,Qwen 更倾向凭上下文直接作答——这正是漏调工具的根源。二是请求数:8.1 次/任务的请求量却有 119.9 秒累计耗时,说明慢在单次请求本身,不是被工具往返拖的。三是格式:37/45 的原文严格 JSON,等于每 6 轮就有 1 轮需要客户端兜底,这个比例在真实产品里不可接受。
一个必须说清的数据缺口。 附件里的 tool_calls.csv 只有 5 条明细(来自恢复运行后新跑的 B-C-R3),不是全部 84 次调用。原因是中断前那次运行用的是旧版脚本,只记录了每轮的工具调用次数,没有逐次保存参数和返回值;--resume 恢复后,旧任务的明细无法追补。所以本文判断“哪一轮漏调工具”依据的是 turns.csv 的 tool_calls 列(逐轮计数,90 行完整),而不是明细文件——两者不冲突,但读者应当知道明细不全。
结果怎么读。 场景 A 三次最终结果均为无匹配;场景 B 三次均推荐 P1;场景 C 三次均推荐 H1,最终选择 9/9 命中。但最终答案正确不代表过程无缺陷:场景 B 有两次比较轮没有调用工具(B-B-R1、B-B-R2 第 4 轮,tool_calls=0),B-B-R2 第 3 轮原文整体不是合法 JSON,评测程序的宽松解析还错误地从嵌套内容里截取了一个车型对象当成本轮结果。这三处都在失败与边界案例里逐条分析。
重复性与波动。 它的分数波动比 DeepSeek 明显:A 场景 95/95/95(极差 0)、C 场景 95/94/94(极差 1),而 B 场景 90/87.5/95(极差 7.5,标准差 3.12)——三次里两次扣分都发生在 B 场景,正是漏调工具和 JSON 非法这两类问题。也就是说,它的不稳定性不是"随机抖动",而是集中在特定场景的特定环节,这种波动比均匀抖动更容易定位、也更容易修。
跑一遍要多久。 9 个任务的累计 API 请求时间为 1,079.3 秒,约 18 分钟,是 DeepSeek 的近 4 倍。这意味着同一个 3×3 回归,Qwen 侧要等更久;如果以后扩到 5 个场景 × 5 次,光等待就要一个多小时。对做评测的人来说,延迟不只是"用户体验"指标,它直接决定了你能跑多少样本。
结论
Qwen 在本次配置下的人工评分平均为 93.39/100,最终结果命中率为 9/9。它的每任务平均 Token 数较少(28,147),但响应时间较长(119.9 秒),结构化输出和比较工具调用需要进一步加强。对于可以接受客户端校验、且更关注 Token 数的原型,可继续使用并增加验证层;如果任务要求每轮都必须可靠调用工具、返回可解析结构,则本次结果显示应优先修复这些问题后再进入生产使用。
总体评价:有条件推荐。 省钱是实打实的,但前提是你愿意在自己的代码里补一层严格校验;如果接的是面向用户的实时对话,119.9 秒的等待会让体验先崩。
实验设计、量化结果与案例
1. 实验设置
测试日期为 2026-11-10。DeepSeek 使用官方 API 模型 ID deepseek-flash,Qwen 使用百炼 API 模型 ID qwen3.7-plus。平台当前文档中,DeepSeek deepseek-flash 对应 V4.1 Flash 系列;百炼文档说明 Qwen qwen3.7-plus 等同快照 qwen3.7-plus-2026-05-26。运行记录也保存了 API 返回的模型标识。
为什么选这两个,以及类型上的取舍。 作业建议覆盖不同类型(例如一个通用对话模型 + 一个推理模型)。本组实际选的是两个通用对话模型的不同厂商版本:DeepSeek V4.1 Flash(开启 thinking、reasoning_effort=high)与 Qwen 3.7 Plus(enable_thinking=true)。这样选的理由是:我们要比较的是“同为通用模型、不同厂商”在同一个工具调用任务上的工程差异。如果一边放推理模型、一边放通用模型,最终结果的差异会同时混入“模型类型”和“厂商实现”两个变量,反而说不清到底是哪一个导致的。代价要写明:本次没有覆盖“纯推理模型”这一档,作业建议的那组对照我们没有做;若补做,需另跑 18 个任务并单独成表,不与本次结果混算。
两边的温度参数均使用 API 默认值,没有显式设置。DeepSeek 使用 reasoning_effort=high 并启用 thinking;Qwen 使用 enable_thinking=true。可配置推理参数因服务商接口不同而无法完全统一,是本实验的比较限制。两边使用同样的车型信息、对话轮次、输出 JSON 约定、评分规则和工具 schema。
完整参数记录。 作业要求记录“平台、精确模型标识、测试日期和主要参数”,逐项如下(同一份内容也写进了 manifest.json):
| 项目 | DeepSeek | Qwen | 是否统一 |
|---|---|---|---|
| 服务平台 | DeepSeek 开放平台 | 阿里云百炼(华北 2 北京) | 不同平台,按官方接口调用 |
| 请求模型 ID | deepseek-flash | qwen3.7-plus(=快照 qwen3.7-plus-2026-05-26) | — |
| 接口返回的模型标识 | 由 api_model_ids 字段记录 | 同左 | 双方都记录 |
| 接口与端点 | /chat/completions | OpenAI 兼容 /compatible-mode/v1/chat/completions | 同为 Chat Completions |
| 测试日期 | 2026-11-10 | 2026-11-10 | 是 |
| 温度 | 默认值(未显式设置) | 默认值(未显式设置) | 是 |
| 推理相关参数 | reasoning_effort=high + thinking | enable_thinking=true | 否,接口语义不同,已说明 |
| 工具 | 2 个本地函数,schema 相同 | 同左 | 是 |
| 单轮工具往返上限 | 5 次 | 5 次 | 是 |
| 单次请求超时 | 180 秒 | 180 秒 | 是 |
| 上下文策略 | 任务内保留、任务间重建 | 同左 | 是 |
| 联网检索 | 未使用 | 未使用 | 是 |
| 输出约定 | 单个顶层 JSON、7 个必填字段 | 同左 | 是 |
车型数据性质: 下表为本组自拟的虚构教学模拟数据,不是现实车型,也不是真实报价。数据整理日期为 2026-11-09;价格口径为模拟裸车价(万元,不含税费、保险、上牌费及优惠);续航单位 km、座位单位“座”、后备厢单位 L,能耗单位见表。由于所有参数均由本组固定,不进行联网检索。
| ID | 年份与配置 | 模拟裸车价 | 动力类型 | CLTC 纯电续航 | 座位 | 后备厢 | 能耗 |
|---|---|---|---|---|---|---|---|
| E1 | 2026 款云驰 E1 510 智享版 | 15.8 万元 | 纯电 | 510 km | 5 | 480 L | 14.5 千瓦时/100 km |
| E2 | 2026 款云驰 E2 620 旗舰版 | 18.8 万元 | 纯电 | 620 km | 5 | 520 L | 15.5 千瓦时/100 km |
| P1 | 2026 款山河 P1 160 家用版 | 16.8 万元 | 插电混动 | 160 km | 5 | 450 L | 亏电油耗 5.2 L/100 km |
| H1 | 2026 款山河 H1 燃油舒适版 | 14.5 万元 | 燃油 | 不适用 | 5 | 500 L | 7.8 L/100 km |
2. 三个场景和事前预期
| 场景 | 预算与使用需求 | 预算外硬约束 | 运行前预期 |
|---|---|---|---|
| A 城市通勤/无匹配 | ≤17 万元;每天通勤约 50 km;家中可安装充电桩 | 必须纯电,CLTC ≥600 km | 无匹配:E1 续航不足,E2 超预算,P1/H1 动力类型不符。 |
| B 家庭长途/补能 | ≤17.5 万元;4–5 人乘坐;每月数次高速;没有固定充电桩 | 非纯电、至少 5 座、后备厢 ≥450 L | P1、H1 均满足硬约束;能耗是偏好,不是硬约束。按表内油耗数值,预期优先 P1。 |
| C 中途修改需求 | 初始 ≤19 万元;周末带家人出行 | 至少 5 座、后备厢 ≥450 L;后续预算改为 ≤15 万元、不能装桩、不考虑纯电,并明确撤销纯电偏好及续航要求 | 按最新条件推荐 H1;保留座位和后备厢条件,不再沿用已撤销条件。 |
三种场景和预期结果在正式运行前写入 protocol.json。每个模型×场景×重复从全新的 system 消息开始;同一次任务保留前序消息。每次完整任务有 5 个用户轮次:初步需求、补充偏好/约束、继续更新、车型参数对比、最终建议。因此正式规模为 2 个模型 × 3 个场景 × 3 次重复 = 18 个任务、90 轮。
3. 程序结构和 Function Calling
自动化程序负责固定输入、创建独立上下文、调用两个模型、执行本地工具并保存结果。工具只有两个只读函数:query_vehicle_catalog 按预算/动力/续航/座位/后备厢条件筛选模拟车型;compare_vehicles 按车型 ID 返回车型表参数。筛选与比较使用程序中的固定数据,不使用联网搜索。模型需要在答案中说明工具结果,并按指定 JSON 字段返回候选、约束、比较表、最终选择和未知项。
每个模型 × 场景 × 重复:创建新上下文
逐轮发送同一套用户输入并保留本任务历史
如模型请求工具:本地程序执行查询/比较并把结果回传
保存每轮原文、解析字段、token、累计 API 响应时间和工具调用数
保存最终选择并与预先登记的可接受结果对比
关键代码(节选,完整版本见附件 代码/购车自动化评测.py)。工具用 JSON Schema 声明参数,让模型只能在枚举值里选车型 ID 和动力类型;单轮最多 5 次工具往返,避免模型反复调用陷入死循环:
TOOLS = [
{"type": "function", "function": {
"name": "query_vehicle_catalog",
"description": "按预算、动力、续航、座位数及后备厢条件筛选固定教学模拟车型库。",
"parameters": {"type": "object", "properties": {
"price_max_wan": {"type": "number"},
"powertrains": {"type": "array", "items": {"type": "string", "enum": ["纯电", "插电混动", "燃油"]}},
"range_min_km": {"type": "integer"}, "seats_min": {"type": "integer"},
"trunk_min_l": {"type": "integer"}}, "required": []}}},
{"type": "function", "function": {
"name": "compare_vehicles",
"description": "按车型ID查询固定车型库完整参数,返回可核验的比较数据。",
"parameters": {"type": "object", "properties": {
"model_ids": {"type": "array", "items": {"type": "string", "enum": ["E1", "E2", "P1", "H1"]}}},
"required": ["model_ids"]}}},
]
def run_tool(name, args):
"""本地只读工具:确定性筛选,不联网、不补数据。"""
if name == "query_vehicle_catalog":
rows = VEHICLES[:]
if args.get("price_max_wan") is not None:
rows = [v for v in rows if v["price_wan"] <= float(args["price_max_wan"])]
if args.get("powertrains"):
rows = [v for v in rows if v["powertrain"] in set(args["powertrains"])]
if args.get("range_min_km") is not None:
rows = [v for v in rows if v["range_cltc_km"] is not None
and v["range_cltc_km"] >= int(args["range_min_km"])]
return {"matched_count": len(rows), "vehicles": rows, "data_type": "虚构教学模拟数据"}
if name == "compare_vehicles":
ids = args.get("model_ids", [])
return {"vehicles": [v for v in VEHICLES if v["model_id"] in ids],
"unknown_ids": [x for x in ids if x not in {v["model_id"] for v in VEHICLES}]}
raise ValueError("未注册工具:" + str(name))
def call_turn(config, messages, task_id, turn_no, tool_log):
"""一个用户轮次内:发请求 → 执行工具 → 把结果回传 → 直到模型给出最终答复。"""
for _ in range(5):
response, dt = post(config, messages)
msg = response["choices"][0]["message"]
calls = msg.get("tool_calls") or []
if not calls: # 没有工具请求,本轮结束
return msg.get("content") or "", parse_object(msg.get("content") or "")
messages.append({"role": "assistant", "content": msg.get("content"), "tool_calls": calls})
for call in calls:
name = call["function"]["name"]
raw = call["function"]["arguments"] or "{}"
try:
args = json.loads(raw)
result = run_tool(name, args) # 工具返回固定数据,模型不得改写
except Exception as exc:
result = {"error": str(exc)} # 工具错误单独记录,不当作成功
tool_log.append({"task_id": task_id, "turn": turn_no, "name": name,
"arguments": args, "result": result})
messages.append({"role": "tool", "tool_call_id": call["id"],
"content": json.dumps(result, ensure_ascii=False)})
raise RuntimeError("单轮工具调用超过5次,停止以防止无限循环")
4. 评分规则和计算方法
每个任务人工复核后按 100 分计分,权重在运行前固定。评分参考原始回答、固定数据与任务预期;一个任务只有一条总分记录,场景均值按该场景 3 次独立任务计算。
| 指标 | 权重 | 判定标准 | 判据来源 | 样本量 |
|---|---|---|---|---|
| 硬约束满足 | 25 | 最终回答符合全部当前硬约束得满分;场景 A 必须无匹配,不能为了给答案而放宽约束。 | 人工对照车型表,程序 final_choice_match 交叉核对 | 18 任务 |
| 数据真实性 | 20 | 对照车型 ID、价格、动力、续航、座位、后备厢、能耗核验;不存在的车型/参数按处扣分。 | 人工;程序 all_candidate_ids_known 先筛一遍未知 ID | 18 任务 |
| 多轮一致性 | 20 | 约束保留、明确撤销、偏好与硬约束区分、结论与最新状态一致,每项 5 分。 | 人工 | 18 任务 |
| 指令与格式 | 10 | 顶层 JSON 可解析、stage 正确、候选与比较表齐全、必填字段齐全,每项 2.5 分。 | 程序初筛(json_parse_ok、stage)+ 人工复核原文 | 90 轮 |
| 工具调用正确性 | 10 | 需要查询或比较时调用正确工具、参数合法、结果来自固定库;漏调用按规则记 5 分。 | 程序计数(tool_calls、tool_errors)+ 人工看参数 | 18 任务(比较轮 18 次) |
| 推荐理由 | 10 | 结合已知参数解释选择与取舍,不把车型表外数据当作事实。 | 人工 | 18 任务 |
| 未知信息处理 | 5 | 对车型表没有的数据明确标“未知/不适用”,不自行补造。 | 人工(逐条看 unknowns 字段) | 18 任务 |
程序判定与人工判定的分工。 上表能做到"可复算"的只有前四类里的客观项:final_choice_match、all_candidate_ids_known、json_parse_ok、stage 是否为空、tool_calls 是否为 0、tool_errors 是否非空——这些都是从 CSV 里数出来的,换一个人重算应当得到同样结果。剩下五项(硬约束、真实性、一致性、理由、未知项)必须人工读原文,因为"这条理由算不算解释清楚了"没法写成布尔表达式。我们把这部分写进 manual_scores.csv 的 scorer_notes,每条都注明扣分依据(哪一轮、哪个字段、违反了哪一条规则),事后可以逐条复查。
为什么不全自动打分。 试过把"未知项"也做成程序判定(unknowns 数组非空即得分),但立刻遇到反例:模型可以塞一个无关的"未知:真实道路续航"来凑分。所以这一项仍然人工判,程序只负责把 unknowns 为空的任务标出来。这也是本文反复强调的那句话:能自动的只是"格式与计数","说没说清楚"仍要人来看。
最终结果命中率由程序比较 final_choice_id 与事前登记的可接受 ID;稳定性按各模型、各场景 3 次最终结果是否都落在可接受集合内计算。Token 为 API 返回的 prompt 与 completion token 之和。延迟为任务各次 API 请求耗时之和,单位秒;它不是用户端完整墙钟时间。人工评分有判断成分,因此同时报告客观命中、结构格式、工具计数和 Token/时延,不把总分解释成普适能力。
5. 主要结果
| 模型 | 任务数 | 最终结果命中 | 每场景稳定性 | 平均人工分 | 去围栏后完整 JSON 可解析 | 原文严格 JSON 格式 | 比较轮工具调用 | 平均 Token/任务 | 平均累计 API 响应时间/任务 | 工具错误 |
|---|---|---|---|---|---|---|---|---|---|---|
| DeepSeek V4.1 Flash | 9 | 9/9(100%) | A/B/C 均 3/3 | 100.00 | 45/45 | 45/45 | 9/9 | 41,977 | 30.6 秒 | 0 |
| Qwen 3.7 Plus | 9 | 9/9(100%) | A/B/C 均 3/3 | 93.39 | 44/45 | 37/45 | 7/9 | 28,147 | 119.9 秒 | 0 |
| 场景 | DeepSeek 平均分 | Qwen 平均分 | DeepSeek 平均 Token | Qwen 平均 Token | DeepSeek 平均累计 API 响应时间 | Qwen 平均累计 API 响应时间 |
|---|---|---|---|---|---|---|
| A 城市通勤/无匹配 | 100.00 | 95.00 | 34,714 | 29,727 | 24.7 秒 | 98.2 秒 |
| B 家庭长途/补能 | 100.00 | 90.83 | 45,046 | 27,655 | 39.1 秒 | 166.0 秒 |
| C 中途修改需求 | 100.00 | 94.33 | 46,172 | 27,060 | 28.1 秒 | 95.6 秒 |
人工评分的维度均值如下。DeepSeek 在本次记录中达到各项满分;Qwen 的扣分集中在 unknowns 未列出任务中未提供的现实使用信息、场景 B 两次比较轮未调用工具、一轮整体 JSON 格式错误,以及场景 C 两个重复任务把 JSON 包在 Markdown 围栏中。人工分只表示本组依据公开规则复核这 9 个任务的结果。
| 指标均值 | DeepSeek | Qwen |
|---|---|---|
| 硬约束满足(25) | 25.00 | 25.00 |
| 数据真实性(20) | 20.00 | 20.00 |
| 多轮一致性(20) | 20.00 | 20.00 |
| 指令与格式(10) | 10.00 | 9.50 |
| 工具调用(10) | 10.00 | 8.89 |
| 推荐理由(10) | 10.00 | 10.00 |
| 未知信息处理(5) | 5.00 | 0.00 |
| 合计(100) | 100.00 | 93.39 |

雷达图把各维度得分折算为“占该维度满分的比例”,便于在满分不同的维度之间直接比较形状差异;它不改变上表分数,只是同一批数据的另一种投影。
图表中的误差线表示三次任务的最小值至最大值,场景样本量均为 n=3。平均 Token 和响应时间的波动不代表模型长期表现;尤其 Qwen 的推理参数与 DeepSeek 不完全相同。




五张图各看什么。 为了避免“有图但不知道看什么”,把每张图的指标、单位与读法列清楚(样本量均为每模型每场景 n=3,柱为均值、误差线为三次的最小值至最大值):
| 图 | 指标 | 单位 | 怎么读 |
|---|---|---|---|
radar_dimensions.png | 七个评分维度的得分率(维度均值 ÷ 维度满分) | % | 形状越接近正七边形越均衡;Qwen 在“未知信息处理”方向的凹陷最明显 |
score_by_scenario.png | 各场景平均人工评分 | 分(0–100) | 比较场景间差异:Qwen 的低点在 B 场景,与漏调工具、JSON 非法两处扣分对应 |
final_match_rate.png | 最终决策命中率 | % | 两模型三场景全部 100%,说明“选对车”这件事本次没有区分度 |
latency_by_scenario.png | 每任务平均累计 API 响应时间 | 秒 | Qwen 三个场景分别是 DeepSeek 的 4.0 / 4.2 / 3.4 倍 |
tokens_by_scenario.png | 每任务平均 Token | token | 与延迟相反:Qwen 更低,B 场景差 1.6 万 token |
稳定性怎么算。 作业建议把稳定性单独列为维度,我们按“同一模型同一场景 3 次独立运行是否都落在可接受集合内 + 三次总分的极差”来量化:两模型 6 个(模型×场景)组合的成功率都是 3/3;总分极差 DeepSeek 全为 0,Qwen 为 0 / 7.5 / 1.0。结论是:本次设置下两个模型都稳定命中,稳定性不足以区分优劣——真正有区分度的是工具调用率与格式合法率。样本量只有每场景 3 次,这个判断只适用于本次数据。
费用没有从两个平台的账户账单中拆出这 18 个任务的独立金额,所以本文不估算人民币或美元费用。Token 数可复核,实际费用应以相同账单时间范围内的平台记录为准;两家缓存规则、免费额度和价格口径也可能不同。
6. 失败与边界案例
案例一:Qwen 的 JSON 输出与解析器共同失效(B-B-R2 第 3 轮)。 该轮要求更新候选并按指定 JSON 格式输出。原始回答文本中 reason 字段包含未转义的引号,导致整段顶层 JSON 无法通过严格解析。当前程序的 parse_object() 在顶层解析失败后继续扫描后续 {,因此误把 comparison_table 内的车型对象当成整个回答,结果 turns.csv 的 stage 为空,但 json_parse_ok 仍被记成 True。复核后将 Qwen 的 B-B-R2 格式分由 9 调整为 7.5、总分由 89 调整为 87.5;另外,B-C-R2 第 1–2 轮和 B-C-R3 五轮使用 Markdown 代码围栏,违反“只输出 JSON”的指令;两个受影响任务的格式分各扣 1 分、总分由 95 调整为 94。权重未改。去掉围栏后,Qwen 44/45 轮可解析为完整 JSON;另 7/45 轮虽是完整 JSON,但包在围栏中;1/45 轮整体 JSON 无效。DeepSeek 原文 45/45 轮均为不带围栏的有效 JSON。
这件事有两层现象:模型回答没有保持合法 JSON;评测程序又以过宽松的“从任意花括号处截取”规则掩盖了错误。仅看 status=ok 或解析布尔值,会高估结构化输出质量。
案例二:Qwen 比较轮漏调用工具(B-B-R1、B-B-R2 第 4 轮)。 提示词要求比较当前候选并逐项标记约束,system prompt 也要求比较车型时先调用车型工具。两次模型都直接依据上下文生成了参数表,没有调用 compare_vehicles。输出参数与固定表一致,所以最终候选仍然正确;但在工具调用这一工程要求上不合格。其余 Qwen 场景 B 重复调用了比较工具。
边界场景 A:无匹配约束。 两个模型的 6 次运行均返回无匹配,符合预算、动力和续航条件的冲突设计;没有为了给出车型而放宽硬约束。这是边界成功,不是车型推荐失败。
边界场景 C:中途撤销和修改条件。 两模型 6 次运行最终均选择 H1,并保留座位、后备厢要求,清除了明确撤销的纯电偏好和续航要求。该场景用于检查上下文更新能力;本次没有观察到最终结果错误。
用户访谈记录
本节内容来自真实访谈,问答与截图均为原始记录(头像与昵称已做处理)。
背景介绍。 受访者:林同学(数学与统计专业,大三在读,不是本组成员),据其自述几乎每天使用 AI 助手。选择原因:他长期把 AI 助手当日常开发工具,属于“已经在用、并且会用脚投票”的真实用户,不是第一次尝鲜的旁观者;他自己的需求很明确——少解释、少返工。访谈时间:2026 年 11 月 9 日,线上问答。
TA 现场做的任务(体验过程)。 访谈不是只问话。我们给 TA 的任务是“从空目录生成一个能跑的网页”,用的是 DeepSeek 的对话界面(Harness 桌面端,工作区挂 DeepSeek-v4.1-Flash),提示词原文如下:
从空目录新建一个“校园复习任务看板”网页。功能:添加复习任务(任务名称、课程、截止日期、预计分钟数);显示任务列表,可标记完成或删除;可筛选全部、未完成、已完成;显示完成进度并用 localStorage 保存,刷新页面后数据保留;输入不完整或分钟数无效时提示;首次打开显示 3 条标明为示例的复习任务,并提供清空示例任务的方式。页面简洁、适配手机屏幕。请给出完整代码,并简要说明如何运行和手动验证上述功能。



观察到的过程(事实)。 TA 一次性发出提示词,没有分步引导、没有补充说明;DeepSeek 用时 9 分 27 秒、1 轮 40 步完成,交付 index.html、styles.css、app.js、README.md 四个文件,并附桌面端与手机端两种预览。TA 全程只做了一次“发出提示词 → 等结果 → 打开预览”的动作,没有遇到需要回头重问的卡点——也就是说,这个任务在 10 分钟量级里是能独立完成的。加上后面逐项读 README、核对页面功能,整段体验约 20 分钟。
成品质量(可逐条核对)。 拿提示词里的要求对一遍截图:任务名称/课程/截止日期/预计分钟数四个字段齐全,分钟数标了 1–1440 的范围;进度条显示 33%(已完成 1/3,剩余 2 项);筛选页签“全部 3 / 未完成 2 / 已完成 1”与列表一致;三条示例任务都带“示例”标签,并给了“清空示例任务”入口;页脚注明“任务只保存在当前浏览器的 localStorage 中,不会上传到服务器”。这些都能在图里直接看到,不是我们替它说的。
TA 的评价(原话)。
Q1:你之前用过 DeepSeek 或通义千问吗?
用过。DeepSeek 我用了挺久,通义千问也试过一段时间,现在主要用 DeepSeek。
Q2:这次用下来,它满足你的需求了吗?
基本够用。写代码、看报错特别顺,一堆报错信息丢给它,它就能直接告诉我哪里没传参数。就是改大文件不行,几千行的文件让它改一段逻辑,它老改到旁边去,或者顺手把我没让动的也重写了,每次还得自己再翻一遍 diff。
Q3:有没有卡住的地方,或者让你觉得意外、不错的地方?
有卡住的地方。最烦的是聊久了它就忘事,前面说好的写法后面又不认了;还有就是偶尔特别自信地编一个不存在的参数名,我得去查文档才知道它瞎说。好的地方是我说话不用太讲究,一句话里塞几个要求它也能拆明白,不用非得列成一条一条。
Q4:如果只能改一个地方,你改哪里?
如果只改一个,让它记住我的项目。现在每开一个新会话都跟换了个人似的,项目结构、命名习惯、哪个库不能用,全得从头讲一遍,天天讲,真的累。
TA 用什么栏目、能不能上手。 按作业要求的第(2)条,单独记一下他实际用的是哪个栏目:
| 记录项 | 内容 |
|---|---|
| 实际使用的产品栏目/功能 | DeepSeek 的对话界面(本次现场用的是桌面端 Harness,同样的任务在网页端也能做):贴一句提示词,等它生成整套页面。日常则用于贴报错、定位参数、改大文件里的一段逻辑、看 diff。据其自述,他没有用过开放平台的 API 控制台,也不关心计费与参数。 |
| TA 能不能上手 | 能,而且是熟练用户——现场任务一次成功、中途没有求助,他不需要学习怎么提问,反而总结出了自己的用法(“说话不用太讲究,一句话里塞几个要求”)。这说明这个产品的上手门槛对程序员已经很低;访谈里暴露的不是“不会用”,而是“用久了之后的失望”。 |
| 与产品设计的关联(推测) | 他抱怨的三件事都指向同一个设计取向:产品把“生成”做得很好,把“确认与追踪”留给用户(自己翻 diff、自己查文档、自己重讲项目背景)。 |
四句话里的四个具体现象。 这段回答有用,是因为每个抱怨都能落到具体行为上,而不是"好用/不好用":
| 受访者的说法 | 具体表现 | 可能原因(推测) | 与本次实验的呼应 |
|---|---|---|---|
| "改大文件老改到旁边去" | 几千行的文件里做局部改动,重写了无关段落 | 长上下文里定位精度下降;缺少行级锚点,模型倾向整段重写 | 与"漏调比较工具"同源:模型宁可自己生成,也不先去精确定位 |
| "聊久了就忘事" | 多轮后不认前面约定的写法 | 上下文内信息衰减;有效约束没有存成显式状态 | 场景 C 就是专测这个:撤销与保留必须写进状态,不能靠模型记 |
| "自信地编不存在的参数名" | 输出看着专业,查文档即证伪 | 训练语料里的模式补全;缺少表达"不确定"的习惯 | 与 Qwen 的 unknowns 9 次全空完全一致:模型不愿说"不知道" |
| "一句话塞几个要求也能拆明白" | 口语化、多要求的输入仍能被正确拆解 | 指令解析能力较强 | 我们的三轮需求增补与撤销也没出现解析错误 |
我们能从这段访谈拿到的改进方向。 林同学把"记住项目"排在第一位,这件事不是"换个更聪明的模型"能解决的,而是产品层的事:把项目结构、命名习惯、禁用依赖写成一个可查看、可修改的项目级规则文件,每次会话自动注入,而不是让用户每天重讲一遍。代价是用户要维护这个文件;好处是它可见、可版本化、可复核——正好落回本文反复强调的那句"证据要能看见"。
为什么这条访谈值得记。 他的三个抱怨(改偏、忘事、编参数)和我们在 18 个任务里量到的三类缺陷(工具漏调、约束遗忘、未知不标)指向同一件事:模型不会主动报告自己不确定。所以产品侧的解法不是等一个更强的模型,而是加结构化的约束、状态与校验——这也是第二部分改进方案选择"客户端严格校验"而不是"只改提示词"的直接理由。
过程图片。 QQ 问答记录如下,头像与昵称已裁除,仅保留对话内容。

第二部分:分析
开发时间估计
以下是从零实现同类课程原型的估计工时,不是本组计时记录。本组共 8 人,实际分工与贡献度如下(合计 100%)。
贡献度的分配口径:8 人平均为 12.5%,组长因贯穿全程(协议定稿、统筹、统稿、发布)略高 2.5 个百分点,脚本主体因不可替代略高 0.5 个百分点,其余成员投入相仿、统一取 12%。差异只体现“谁多担了一点”,不拉开档次——这个项目本身就是并行推进的。
| 姓名 | 学号 | 角色 | 主要产出 | 贡献度 |
|---|---|---|---|---|
| 林晨 | 102400420 | 组长 / 统稿 | 场景与评分协议定稿、进度统筹、报告结构设计、全文统稿、发布与提交 | 15% |
| 李想 | 102400419 | 测试框架 | 自动化脚本主体:多轮上下文管理、工具调用循环、日志与 CSV 落盘规范 | 13% |
| 林宇扬 | 102400422 | 接口接入 A | DeepSeek API 接入、密钥与配置管理、试跑与正式运行复核 | 12% |
| 林凯 | 102400421 | 接口接入 B | 百炼 Qwen API 接入、额度与地域配置、试跑与正式运行复核 | 12% |
| 刘婷婷 | 102400405 | 评分引擎 | 7 维人工评分、逐轮原文与车型表核对、manual_scores.csv 与扣分依据 | 12% |
| 孙田田 | 102400407 | 可视化与材料 | 5 张图(雷达 + 4 柱状)、数据汇总、附件包与 README | 12% |
| 王婉怡 | 102400408 | 体验与采访 | 两个产品的体验记录、界面截图整理、用户访谈与访谈记录 | 12% |
| 郑雯心 | 102400409 | 市场与发布检查 | 市场资料与引用核对、竞品调研、发布检查与提交 | 12% |
| 合计 | — | — | — | 100% |
开发背景假设。 团队 8 人,均为计算机相关专业在读,每人每天可投入 2–3 小时课外时间;其中 3 人处在核心链路上(场景与协议、脚本、运行复核),其余 5 人各承担 2–3 小时的分块工作(逐轮评分、图表、截图、访谈、市场资料);没有专职 UI 与测试;API 使用免费额度或自费小额调用。
关键是:8 人并行不等于 8 倍速度。真正串行的只有“协议定稿 → 脚本 → 正式运行 → 复核”这条链,其余工作可以并行,所以日历时间约 4 天,而有效工时只有 16–24 人时。这个量级也自洽:核心 3 人每天 2–3 小时、干满 3 天,约 18–27 人时,与下面的分项合计吻合。
| 阶段 | 日历天数 | 参与人数 | 说明 |
|---|---|---|---|
| 场景、车型数据与评分协议定稿 | 1 | 3 | 4 款车型、3 个场景、事前预期结果;定稿后不再改 |
| 脚本与工具接入 | 1 | 2 | 多轮框架、两个只读工具、日志与 CSV |
| 试跑、调试与正式运行 | 1 | 2 | 前半天排错,后半天跑满 18 个任务 |
| 人工复核与评分 | 1 | 4 | 逐轮原文对照车型表与预期结果 |
| 图表、写作与提交检查 | 1(与上一步重叠) | 5 | 五张图、博客、附件、引用核对 |
| 合计(后两步可并行) | 3–4 天 | 不含等待审核与额度问题 |
各环节的有效人时估计。
| 工作 | 估计人时 | 产出 |
|---|---|---|
| 场景、模拟车型数据、预期结果与评分规则 | 2–3 小时 | 固定协议、测试边界 |
| 两家 API 接入、Function Calling 和多轮上下文 | 4–5 小时 | 自动化运行程序 |
| 批量运行、异常记录和结果复核 | 2–3 小时 | 18 个任务与逐轮日志 |
| 人工评分、图表、失败案例分析 | 2–4 小时 | 评分表和可视化 |
| 两个产品体验、用户访谈和证据整理 | 2–3 小时 | 体验记录、采访素材 |
| 博客、附件、引用与提交检查 | 4–5 小时 | 可提交作业 |
| 合计 | 16–24 小时 | 不含学习 API、等待服务和返工时间 |
按这个估计,8 人平均每人投入 2–3 小时,明显少于“三个人各做二十小时”那种估法——因为评分、截图、资料这些确实是分块的,一个人一小时能推进一块。真正压不动的只有协议定稿和正式运行那两天。
按《构建之法》第 9 章项目经理的视角,本组最有效的做法不是继续加人,而是先把「场景协议」和「评分规则」固定下来、由一人统一维护:这两样一旦中途改动,之前跑完的 18 个任务就要重跑,协调成本会迅速吃掉并行省下的时间。
按《构建之法》第 8 章“功能的定位和优先级”的思路,这 16–24 小时里真正决定作业质量的是前 4 行(约 10–15 小时):场景与评分规则一旦含糊,后面的运行和作图都会变成返工。第 5、6 行更接近可压缩的“展示成本”,压缩它会掉分,但不至于让结论失效。因此如果时间只够做一半,优先保证协议固定和逐轮日志完整。
平台与测试系统的三层分析
书里有一个说法:程序 = 算法 + 数据结构,软件 = 程序 + 软件工程,软件企业 = 软件 + 商业模式。按这三个层次拆开看本次用到的三个对象——DeepSeek 开放平台、阿里云百炼、本组自建的评测程序——能更清楚地说明“模型好不好”和“服务能不能用”是两件事。
| 层次 | DeepSeek 开放平台 | 阿里云百炼 | 本组评测程序 |
|---|---|---|---|
| 程序层 | 对话以消息数组传递;支持 Tool Calls,工具参数以 JSON Schema 声明;提供推理强度等参数;上下文窗口由调用方自行维护。 | 对话接口与 OpenAI 兼容,同一套 messages 结构;tools 字段同样按 JSON Schema 传;enable_thinking 控制思考模式。 | 用列表保存 4 条车型记录,二十余行确定性筛选函数完成预算/动力/续航/座位/后备厢过滤;逐轮记录原文、Token、耗时;一个简单解析函数从回答中提取 JSON。 |
| 软件工程层 | API 网关 + 鉴权 + 限流;接口文档、错误码、定价页;模型按版本迭代,调用方需自行做版本记录与回归。 | 模型广场、Key 管理、用量与额度、地域化部署、快照版本(qwen3.7-plus-2026-05-26);OpenAI 兼容层降低迁移成本。 | 配置与代码分离(local.env);协议文件固定场景与预期;JSONL 逐轮日志 + 4 份 CSV;同一脚本可重跑做回归;失败被单独记录而不是吞掉。 |
| 商业层 | 按 Token 计费、区分峰谷时段;用开源模型 + 低价 API 获取开发者流量,推理模型作为溢价能力。 | 免费额度获客 + 按地域/模型分档计费;把模型、数据、工具、部署打包成云上服务,赚的是平台与生态的钱。 | 无商业收入,属于课程实验工具;它的“价值”是可复现的评测方法,而不是产品收入。 |
程序层:模型架构是黑箱,能观察的是接口行为。 我们没有、也不应该声称知道两家的具体网络结构或训练方法。可以确定的是接口层面的“算法 + 数据结构”:消息数组的线性累积、工具调用的请求—执行—回传循环、JSON 的参数解析。本实验把最需要准确性的部分(预算、续航、座位、后备厢的过滤)从模型里拿出来,交给确定性代码,模型只负责理解自然语言、维护有效约束、解释取舍。这是本次最关键的工程决定:它把“模型会不会算错”变成“模型会不会用错工具”。
软件工程层:服务化把模型变成了可替换的组件。 两个平台都提供鉴权、限流、文档、版本和计量,这些是“软件工程”而不是“算法”:它们决定了一个团队能不能把模型接进生产。百炼的 OpenAI 兼容接口让同一份调用代码可以换模型,这是评测能用同一脚本跑两家的前提;DeepSeek 的接口更简单,参数更少,但也意味着更多配置需要调用方自己管。本组程序则补上了平台没有提供的部分:固定协议、逐轮日志、可重跑的回归脚本、失败可见的记录方式。
商业层:两家卖的不是同一个东西。 DeepSeek 的策略更像“开源模型 + 低价 API + 推理能力溢价”,计费区分峰谷,适合对成本敏感、愿意自己搭工程能力的开发者;百炼的策略是云平台化——用免费额度把开发者拉进来,再把模型、数据、部署、工具链一起卖,赚的是生态和规模。对本次评测的直接含义是:选型不能只看分数,还要看计费口径、缓存规则、额度政策和版本快照。本次没有从账单拆出 18 个任务的费用,所以两种商业模式的成本差异只能定性描述。
一个不该被混淆的边界: 评测程序不是软件产品。它没有用户、没有收入、没有服务等级承诺;它只是一个用来产生证据的工具。把“自建脚本跑出的分数”当成“平台的产品能力评价”,或者反过来把“平台的功能列表”当成“模型的任务表现”,都是本次分析要避免的错位。
同类产品对比与选型
按当前评分规则,DeepSeek 得分高于 Qwen;两个模型的最终推荐命中率都是 100%。因每种场景只有 3 次重复,较合适的结论是“本次任务中 DeepSeek 的格式与工具执行更稳定”,而不是给模型做行业排名。
| 使用需求 | 本次证据 | 选型建议 |
|---|---|---|
| 需要严格按工具流程查数据,并稳定返回可解析 JSON | DeepSeek 比较轮调用 9/9、严格 JSON 45/45;Qwen 比较轮 7/9、去围栏后完整 JSON 44/45、严格原文 JSON 格式 37/45 | 这组实验中优先 DeepSeek;仍需在部署前做更大规模回归测试。 |
| 更关注 Token 数,客户端有能力校验输出 | Qwen 平均 28,147 token/任务,低于 DeepSeek 的 41,977;但本次平均累计 API 响应时间更长 | 可将 Qwen 作为备选,先修复强制工具调用和严格 JSON 校验,再比较成本与延迟。 |
| 需要无匹配判断或多轮撤销需求 | 两模型场景 A 与 C 均 3/3 命中 | 本次数据无法区分胜负;需要扩大数据和条件组合后再作选择。 |
| 需要较低等待时间 | DeepSeek 30.6 秒/任务,Qwen 119.9 秒/任务 | 交互式场景优先 DeepSeek;批量离线任务可以接受 Qwen 的长耗时。 |
本表仅适用于本文的模拟车型、提示词、日期和接口配置,不代表对模型行业能力的整体排序。
为了看清“哪一项真的拉开了差距”,再把两个模型逐维度并排放一次。最后一列是证据强度,只有程序能自动判定、且同类样本内无人工判断的才算“强”:
| 维度 | 谁更优 | 依据 | 证据强度 |
|---|---|---|---|
| 最终推荐正确性 | 持平 | 9/9 对 9/9 | 强(程序比对预期) |
| 工具调用可靠性 | DeepSeek | 9/9 对 7/9 | 强(日志计数) |
| 结构化输出合规 | DeepSeek | 严格 JSON 45/45 对 37/45 | 强(严格解析) |
| Token 成本 | Qwen | 28,147 对 41,977 | 强(接口返回) |
| 响应速度 | DeepSeek | 30.6 秒对 119.9 秒 | 强(同机同网络) |
| 未知信息处理 | DeepSeek | 5.00 对 0.00 分 | 中(人工评分) |
| 综合 | DeepSeek | 100.00 对 93.39 | 中(n=3,含人工判断) |
这张表也说明一件容易被忽略的事:“准确率一样”根本不能作为选型结论。两个模型在最重要的指标上打平,真正决定用哪个的是工具可靠性和响应速度,而这两项恰好是工程侧能改的——这也是下一节把改进方案放在客户端而不是提示词上的原因。
大模型对现实生活的影响
对个人:门槛降低,但判断力更重要。 大模型把“查资料、比参数、写代码”这几步的门槛压得很低。本次实验里,一个三百行左右的脚本就让两个模型各自完成 9 次完整的五轮结构化任务——过去要验证这类能力,得先搭一套对话系统、再写评测流程。但门槛降低不等于结论可靠:模型的语言流畅程度和它的正确程度是两件事。B-B-R2 那轮回答读起来完全通顺,实际上整段 JSON 是不合法的;一个不懂技术的用户根本无从发现。
对消费者:能整理信息,但不能替代核验。 购车金额高、价格和配置变动快,错误信息的现实代价是钱。本次实验暴露的“未知信息处理”问题很典型:Qwen 在 9 个任务里没有一次把车型表之外的现实使用信息标为“未知”,而是选择不写。看起来没出错,实际上是让用户以为信息已经完整。真实产品必须展示数据来源、日期、价格口径和未知项,并且让用户保留最终决定权。
对开发者与行业:工程能力重新变成瓶颈。 模型能力越强,接口、校验、重试、上下文管理、评测回归这些“传统软件工程”的活占比越高。本次两个模型的最终准确率也一样(9/9),真正拉开差距的是工具调用率和格式合法率——这些都是工程问题,不是模型聪不聪明的问题。这也意味着评测本身正在成为一项基础设施能力:谁能稳定地量化模型表现,谁就能更快做选型决策。
风险与边界。 一是幻觉与“沉默的错误”,即模型不写错、但也不说不知道;二是隐私,用户为得到准确推荐会说出家庭人数、通勤距离、预算等个人信息,这些数据如何保存和使用必须说清楚;三是责任边界,模型给出建议、用户承担后果,这种不对称需要在产品设计上用“证据 + 可核验 + 可撤回”来缓解;四是供应链依赖,模型版本、计费政策和额度随时可能变化,工程上要留好替换和回滚的余地。
软件工程方面的建议
- 业务数据与语言模型分离。 车型、价格、单位和来源由数据库/API 提供,模型负责理解需求和解释;硬约束过滤可由确定性代码完成。
- 硬约束状态化。 将预算、动力、座位、空间分别保存为结构化状态;用户修改时只更新明确改动字段,并保留变更历史。
- 用严格 schema 验证回答。 对顶层 JSON 进行一次完整解析,检查必填字段、类型、枚举值和车型 ID;失败就重试一次或标记失败,不能从任意嵌套花括号中猜测结构。
- 工具调用有明确验收。 对需要实时或固定数据的步骤,程序检查是否调用了指定工具,校验参数和返回 ID,并将“漏调工具”与“工具执行错误”分开统计。
- 测试可复现、可回归。 固定车型快照、提示词、模型 ID、参数和日期;每个场景独立建上下文;保留逐轮输入、输出、token、延迟和版本。
- 密钥与个人信息保护。 密钥仅通过环境变量或本机私有配置读取;上传博客、截图和仓库前检查密钥、个人资料与账单标识。
- 失败要可见。 这是本次最贵的一课:一个把错误标成成功的监控,比没有监控更危险。任何“解析成功/任务完成”的标记都应由严格校验产生,而不是由宽松的兜底逻辑产生。
BUG 存在的原因分析
测试环境。 操作系统 Windows 11 家庭中文版(10.0.26200);运行时 Python 3.14.3(评测脚本只用标准库,不依赖第三方包);运行日期 2026-11-10;网络为家用宽带直接访问两家官方 API,无代理;被测对象 deepseek-flash 与 qwen3.7-plus。
严重程度分级。 先定义标准,避免“看起来有问题”和“确实影响结论”混为一谈:
| 星级 | 等级 | 判断标准 |
|---|---|---|
| ★★★★★ | Blocker | 服务不可用、任务无法开始、数据丢失,可能造成整体瘫痪。 |
| ★★★★ | Critical | 主要功能失效或结论被系统性带偏,可能影响数据或账号安全。 |
| ★★★ | Major | 功能没完全实现,影响可信度或工程验收,但整体仍能跑通。 |
| ★★ | Minor | 界面、提示、性能类问题,可以优化,不影响结论。 |
| ★ | 可忽略 | 不仔细观察发现不了,基本不影响使用。 |
本次发现的明确缺陷不是“最终选错车型”,而是程序可能把格式错误误判成成功,以及模型有时跳过要求的工具调用。
| 现象 | 归因层面 | 直接证据 | 等级与复现率 | 可能原因(推测) | 工程定位 |
|---|---|---|---|---|---|
| 一轮输出不是合法顶层 JSON,程序却标记解析成功 | 模型(结构化输出)+ 解析程序 | B-B-R2 第 3 轮;严格 JSON 解析失败,但宽松解析器找到了内层车型对象 | Major ★★★;输出侧约 1/45 轮,解析器侧 100% 复现 | 模型生成的字符串中引号转义不完整;程序的解析算法对任意 { 递归尝试,造成误报 | 模型结构化输出 + 评测程序解析器 |
| 两次比较轮没有调用工具 | 模型(工具选择策略)+ 接口配置(tool_choice=auto) | B-B-R1 和 B-B-R2 第 4 轮 tool_calls=0 | Major ★★★;2/9 次(约 22%) | 模型认为上下文已有数据即可直接作答;tool_choice=auto 允许它选择不调用 | Function Calling 策略和调用验收 |
unknowns 字段 9 次全空 | 模型(不说“不知道”)+ 提示词(缺字段级规则) | 全部 9 条 manual_scores 记录 | Minor ★★;9/9 稳定出现 | 模型倾向于“给一个答案”而不是声明信息缺口;提示词只写了“缺失信息写未知”,没有字段级可检查规则 | 提示词设计 + 评分规则的可见性 |
| 计分过度依赖人工阅读会漏掉机器无法消费的格式问题 | 评测方法(评分规程) | 原人工评分曾只记了 stage 缺失,严格复核原文后才发现顶层 JSON 语法错误 | Major ★★★;方法层,一旦发生影响该任务全部得分 | 评分表与自动解析标记没有对原始全文做一致校验 | 评分规程与程序监控 |
四类原因的归属可以这样区分:第一、二、三行主要是模型侧行为(生成质量与工具选择策略),第二行同时有接口侧配置因素(tool_choice=auto 是调用方选择),第一行还有明确的程序侧缺陷(宽松解析器)。第四行是评测方法本身的问题。把它们混在一起说“模型有 bug”会掩盖真正的改法。
三个现象没有一个是 Blocker 或 Critical:18 个任务全部跑完,最终结论没有被推翻。真正值得警惕的是第一行和第四行——它们让“失败”看起来像“成功”,这比失败本身更难发现。
改进方案与方案优选
针对上面四类原因,本组比较了三种改法。目标是:在不改评分权重、不重跑正式数据的前提下,让同类问题在沙盒里一次性暴露并阻断。
| 方案 | 做法 | 实施成本 | 能解决什么 | 弱点 |
|---|---|---|---|---|
| A 只改提示词 | 在 system prompt 里反复强调“严格 JSON、必须调工具” | 最低,改几行文本 | 对听话的模型有一定效果 | 本次已经这么做了仍有 1/45 非法、2/9 漏调;无法验证是否生效 |
| B 客户端严格校验 + 强制工具 + 重试 | 顶层只解析一次、失败即判失败;对必须查询的轮次用 tool_choice 指定函数;不合格重试一次后落库 | 中,约 60–100 行 | 把“坏数据”挡在评分与后续轮次之外;失败可见 | 依赖调用方对每轮语义的正确判断 |
| C 用平台原生结构化输出 | 改用供应商的 JSON Schema / 结构化输出能力,再由本地做一次严格校验 | 中,取决于两家支持程度与接口差异 | 从生成侧降低非法 JSON 概率 | 两家能力不对等,可能破坏“同条件比较” |
选择:B + C 组合,先用 C 降低发生率,再用 B 兜底。 理由是:A 属于“希望模型自觉”,在本次数据里已被证明不够;C 能提升成功率,但两家支持的接口和参数不同,若把 C 作为唯一手段,评测就会变成“比谁的功能更全”,偏离任务本身的比较;B 是唯一能在客户端确定性发现问题的方案,而且它不改变评分规则,历史结果仍然可比。这个选择也符合第 8 章“功能的定位和优先级”的思路:先做能确定性验收的那一层。
具体设计(“约束状态机 + 证据链”):
- 把每轮的
active_constraints作为显式状态对象保存,字段包括预算、动力集合、续航下限、座位、后备厢、以及一个revoked列表;每轮只允许增量更新,撤销必须写入revoked。 - 每轮返回后做一次“状态回放”:用当前状态重跑一遍确定性筛选,若模型给出的候选与程序筛选结果不一致,直接标记为失败,而不是等最终轮才看总分。
- 每条参数附
source与as_of;没有来源的字段强制填“未知”,并在渲染时高亮,让“沉默的错误”变成可见的空缺。 - 失败分级:
format_invalid、tool_missing、constraint_violation、state_regression四类分开统计,避免一个总分掩盖不同性质的问题。
验证方法(不改动原始 18 次结果): 在新版本脚本上对原有三种场景重新执行 3×3 回归,并额外增加含引号、空值、null 续航、非法 ID 的格式边界输入。验收指标为:顶层 JSON 严格解析率(目标 45/45)、必填字段通过率、比较轮工具调用率(目标 9/9)、状态回放一致率、以及“失败被正确标记为失败”的比例。预期收益:在同样的模型下,本次观察到的 1 例非法 JSON 与 2 例漏调工具都会在当轮被拦下,评分不再依赖事后人工读原文才发现;代价是每个任务多 1 次潜在重试,Token 上升约 5%–10%,需要用同一批场景回归确认。
创新点在哪(方法侧)。 不是“又多接了一个模型”,而是把评测程序本身当成被测系统的一部分来设计:模型输出是输入,确定性规则是判据,失败必须可见。这个思路可以直接迁移到任何“模型 + 工具”的产品里——例如车机语音助手、售后工单分类、保险报价解释,共同点是“模型负责理解,代码负责算术和合规”。
市场概况
AI 基础市场在扩张。 CNNIC 发布的《生成式人工智能应用发展报告(2026)》显示,截至 2026 年上半年,我国生成式人工智能用户规模突破 7 亿、普及率超过 50%;AI 综合助手和 AI 效率办公等应用使用次数同比增长超过 100%。IDC 统计 2025 年中国 AI 云市场规模达到 684 亿元,企业级 MaaS Token 调用量同比约增长 16 倍;其中 AI 应用公有云服务市场约 137.3 亿元,高于大模型训推公有云市场的 79.4 亿元。这组数字说明价值正在从“卖算力”向“卖应用能力”迁移,但不等于购车决策产品的市场收入。CNNIC 报告;IDC:中国 AI 云市场;IDC:AI 应用公有云服务市场
购车决策的年度规模。 中汽协数据显示,2025 年我国新车销量 3440 万辆、同比增长 9.4%,其中乘用车 3010.3 万辆、同比增长 9.2%;中国汽车流通协会统计,2025 年二手车交易 2010.8 万辆、同比增长 2.52%,其中二手乘用车 1573.97 万辆。两者合计约 4584 万笔交易/年,可以近似表示“每年发生多少次购车决策”,但它不是独立买家人数,更不是本产品可直接获得的用户数。2025 年汽车工业运行数据(吉林省工信厅转引);中国汽车流通协会年度二手车数据
直接与潜在用户。 国家统计局《2025 年国民经济和社会发展统计公报》记载,2025 年末私人汽车保有量 3.2336 亿辆,这是潜在服务人群的宽口径上限。直接用户应定义为“近期准备购车、需要比较预算与配置”的消费者,以及帮助客户比对车型的销售/咨询人员;潜在合作方包括汽车垂直媒体、经销商集团、二手车平台和金融/保险服务。现有公开数据不足以直接算出“购车决策 Agent”的 TAM,因此本文不把 AI 用户数或整车销售额简单乘一个比例当作市场规模。国家统计局统计公报
机会与挑战。 机会在于信息确实分散:预算、配置、能源形式、空间、补能条件和长期用车成本分散在官网、垂直平台、经销商报价和评测内容里,用户要自己拼表。挑战在于四件事:价格与优惠变化快,数据口径不一致,广告和导流会侵蚀信任,模型错误建议可能造成现实损失。因此这类产品的门槛不在“会不会聊天”,而在数据维护、来源追溯、利益披露和纠错机制——这正好是第二部分前面几节讨论的工程问题。
市场现状:谁在抢这件事。 购车决策这个场景已经有四类玩家,各占一段:
| 产品/渠道 | 定位 | 优势 | 劣势 |
|---|---|---|---|
| 汽车垂直平台(如懂车帝、汽车之家) | 车型库 + 报价 + 内容 + 社区 | 数据全、更新快、有真实成交线索;用户已经在这里比车 | 以广告和线索为收入,推荐排序与商业利益纠缠;自然语言理解弱,条件一多就要用户自己筛 |
| 通用 AI 助手(如豆包、文心、通义) | 什么都能聊的通用入口 | 理解自然语言、能追问、零学习成本 | 车型数据靠记忆,价格与配置容易过时;不标来源,也不承认“不知道” |
| 经销商与 4S 门店销售 | 线下成交与报价 | 有真实库存与优惠,能试驾 | 立场是卖车,不是帮用户比较;信息不对称 |
| 本组设想的产品 | 自然语言需求 → 结构化约束 → 可核验候选 | 把“理解”和“算术”分开,参数带来源与日期,无匹配就直说 | 数据要自己维护;没有用户基础;需要解决商业模式的信任问题 |
竞争关系。 前两类是正面竞品:垂直平台握数据、通用助手握交互,我们的位置在两者中间——用平台的数据加上助手的交互,但把“证据”放在最前面。第三类是潜在合作方,也是最容易破坏信任的一方:一旦付费能影响排序,产品就退化成广告位。这也是为什么本文在 NABCD 的 D(推广)里先把“披露商业关系”写成硬要求。
一个口径上的坦白: 作业问到“智能体 / Agent 应用市场的规模与增速”,我们没有找到口径统一、可核验的独立统计,因此不在这里编一个数字。能查到的是上面两类(生成式 AI 用户规模、AI 云与 AI 应用公有云市场);把“AI 用户数”或“汽车销量”乘一个系数当作 Agent 市场规模,正是本文一直避免的做法。
两类典型用户(画像)。 市场规模说不清,就先说清楚“给谁做”:
| 项目 | 用户 A:家庭换购 | 用户 B:第一次买车 |
|---|---|---|
| 身份 | 30–40 岁,已婚有小孩,五口之家 | 22–26 岁,刚工作,家里出首付 |
| 现有车辆 | 有一台油车,考虑换购或增购 | 无车,正在考驾照 |
| 表面需求 | 空间够、长途不焦虑、总花费可控 | 预算卡得死、怕被销售忽悠、要好看 |
| 潜在需求 | 想要一个能解释“为什么这台更合适”的依据 | 想要知道“这个价格是不是正常” |
| 使用场景 | 晚上在家比较 3–5 款车,反复改条件 | 在 4S 店里当场查参数、比报价 |
| 对我们的要求 | 数据可核验、能记住条件、能导出对比表 | 快速给结论、明确标出未知项、不夸大 |
产品规划:NABCD
作业问的是“在当前模型的基础上设计什么新功能”。我们的答案是:不换更强的模型,而是在本次选出的 deepseek-flash 之上加一层“可核验”的产品结构——因为数据显示两个模型的最终推荐都准确(9/9),短板在工具执行率与结构化输出,而这两项都能在应用层补齐。
- N — Need(需求): 用户要同时考虑预算、动力、空间、补能条件、真实成交价和长期用车成本,信息分散且条件容易相互冲突。
- A — Approach(做法): 先把自然语言要求转成可查看的硬约束与偏好;用车型数据库和确定性筛选得到候选;模型负责追问缺失条件、解释取舍并生成对比表。每个参数附来源、口径和日期,没有数据时显示未知;无匹配时直接说明冲突。
- B — Benefit(收益): 减少搜集和整理信息的时间,让用户能逐项检查约束与证据。收益需通过真实访谈和任务完成时间测量,本次实验没有测得可宣称的节省比例。
- C — Competitors(竞争): 汽车垂直平台有车型库、报价和内容;通用模型擅长理解自然语言,但数据时效和可核验性需加强。本产品定位于两者之间,用有来源的数据与工具连接自然语言决策流程。
- D — Delivery(推广): 先做小范围免费原型,邀请目标用户完成“需求录入—候选比较—约束修改—导出清单”任务;通过反馈确认数据完整性后,再考虑接入更多车型来源。若与经销商或平台合作,必须披露商业关系,不允许付费影响未标注的推荐排序。
为什么是这个功能,而不是别的? 三个候选里我们放弃了“多模态识图认车”(用户真正缺的不是识别,是判断依据)、“社区晒车”(与决策主流程无关,还要冷启动内容)、“自动下单”(要承担责任,但信任还没建立)。选“约束卡片 + 可核验参数表”的理由只有一条:它直接对应本次实验里唯一被证实的短板——模型能给出结论,但给不出让人敢用的证据。
创新点在哪(产品侧)。 不是“让模型更会聊天”,而是把评测里被证明有效的三件事搬进产品:约束状态化(撤销与保留写进状态,不靠模型记)、工具强制 + 严格校验(漏调即失败,不猜结构)、未知显式化(没有数据的字段变成可见空缺,而不是被悄悄省略)。这三条在 18 个任务里都被验证过有效或必要,属于有证据的取舍,不是拍脑袋的功能堆叠。
如果我是新上任的项目经理,先做哪一件? 按《构建之法》第 8 章的功能定位思路,我会先做“约束卡片 + 可核验参数表”,而不是先做“更会聊天的对话”。理由来自本次数据:两个模型的最终推荐都准确(9/9),真正拉低体验的是格式与工具环节;同理,用户真正卡住的不是“模型不懂我”,而是“我不知道它说的对不对”。第一版把每条参数变成可点开来源的卡片,把“未知”显示成显式空缺,再让模型在这个结构上解释权衡——这比继续堆对话轮次更容易建立信任,也更容易被验证。
第一版路线图(8 周,按第 9 章的项目排期思路)。
| 周次 | 目标 | 验收标准 |
|---|---|---|
| 1 | 冻结车型数据结构与来源字段 | 每条参数都有 source 与 as_of,缺数据的字段显式标“未知” |
| 2 | 约束状态机与确定性筛选 | 给定条件能稳定筛出候选,无匹配时直接说明冲突 |
| 3–4 | 对话层接入两个模型 + 严格 schema 校验 | 同 18 个任务回归,解析失败率 0、必要工具调用率 100% |
| 5 | 证据卡片与对比表导出 | 用户能点开任一参数看到来源;可导出 CSV/图片 |
| 6 | 小范围用户测试(10–15 人) | 记录完成时间、卡点、信任度评分 |
| 7 | 修一轮:优先改“未知项披露”和“条件修改” | 修改后同类卡点消失 |
| 8 | 复盘与取舍 | 明确哪些功能不做、为什么不做 |
这一版不做的事也写清楚:不做社区、不做经销商入驻、不做自动下单。原因很简单——它们都不解决“用户凭什么相信这个结论”这个当前最大问题。
代码、数据与参考资料
材料入口: 全部代码、实验数据与图表都放在公开仓库里,点这里即可浏览或按目录下载:
**https://codehub.devcloud.cn-north-4.huaweicloud.com/ded7ada9dd5f43a3ae7004c4d34970f0/llm-car-decision-eval.git**(华为云 CodeArts,已确认无需登录即可读取)
仓库结构:code/(3 个脚本)、data/(协议、逐轮日志、任务汇总、人工评分、问答对照表,共 9 份)、charts/(5 张 PNG + 5 张 SVG)、docs/(复现说明)、README.md(目录、复现命令、结论摘要)。local.env 已被 .gitignore 排除,提交历史与远端内容都检查过,没有 API Key。
- 代码:
购车自动化评测.py(多轮任务 + Function Calling + 日志与 CSV)、生成评测图表.py(柱状图)、生成雷达图.py(七维度雷达图)、local.env.example(仅变量名)。 - 实验数据:
protocol.json(车型、场景、预期、提示词)、tasks.csv、turns.csv、tool_calls.csv、comparison_table.csv、manual_scores.csv、raw_turns.jsonl、manifest.json。**全部 90 轮问答在data/问答对照表.csv**:18 个任务 × 5 轮,每行一条,包含“我们问的原句 / 模型答的原文 / 解析结果 / 工具次数 / token / 耗时”,按场景、模型、重复、轮次排序,Excel 打开即可逐轮核对。 - 问答记录的取证说明: 正文只在两个模型的「自动化测试」里各摘录了一个任务(
A-B-R1、B-B-R1,共 10 轮)作为案例,其余 80 轮没有贴进正文,全部在data/问答对照表.csv;raw_turns.jsonl是最原始的一份(每行一轮,含完整raw_response),CSV 由它导出,两者内容一致。 - 图表:
radar_dimensions(七维度得分率)、score_by_scenario、final_match_rate、latency_by_scenario、tokens_by_scenario,每张都有 PNG 与 SVG 两种格式,正文已插入 PNG。 - 课程/班级: 202601 福大-软件工程实践-W 班;小组成员与分工见「开发时间估计」。
参考资料:
相关推荐
政府科技管理者如何提升区域科技成果转化项目的评价与筛选效率?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
高校技术转移办公室人员在成果转化过程中如何快速提升技术推介效率?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
两相交错并联Boost电路仿真模型(Simulink仿真实现)
内容概要:本文档系统性地介绍了基于Simulink平台的两相交错并联Boost电路仿真模型,属于电力电子变换器建模与仿真研究的重要组成部分。该模型采用交错并联结构,有效提升了系统效率、降低了输出电流纹波,并具备优良的动态响应与系统稳定性。文档不仅聚焦于该特定拓扑的开环与闭环控制实现,还整合了丰富的配套资源,涵盖多种主流DC-DC变换器(如Buck、Boost、LLC、CLLC)、功率因数校正(PFC)电路、PWM整流器、双向充放电系统以及新能源应用场景(如V2G、微电网)等领域的仿真模型。资源体系强调软开关技术、多相交错控制、系统级建模与参数优化设计,所有内容均提供可运行的Simulink仿真文件,部分包含详细的设计报告、计算书及参考文献,具有较强的工程实践与科研复现价值。; 适合人群:电气工程、自动化、电力电子与电力传动等相关专业的硕士博士研究生、高校科研人员,以及从事新能源发电、电动汽车、电源系统设计等领域的工程技术人员。; 使用场景及目标:①支撑高校电力电子与电力系统方向的科研项目,用于新型拓扑结构的建模与先进控制算法的验证;②服务于本科生与研究生的毕业设计、课程设计及高水平学术论文的仿真复现;③为企业在电源产品研发、新能源系统集成等环节提供成熟的仿真方案参考,缩短研发周期,降低试错成本。; 阅读建议:建议使用者首先访问文档末尾提供的完整资源目录链接,按需下载对应仿真模型;在实践过程中,应重点关注模型的参数配置、控制策略实现细节与仿真工况设置,结合配套的说明文档深入理解其工作原理与设计思路,推荐在MATLAB/Simulink环境中动手调试与二次开发,以充分掌握电力电子系统的核心技术。
Picture of ssh key
Picture of ssh key
政府科技管理者在推动区域科技成果转化过程中,如何系统性地识别和分析创新资源的配置瓶颈?.docx
政府科技管理者在推动区域科技成果转化过程中,如何系统性地识别和分析创新资源的配置瓶颈?



