十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

国产大模型落地汽车研发:RAG问答与测试用例生成工程实践

国产大模型落地汽车研发:RAG问答与测试用例生成工程实践 国产 AI 大模型进入汽车产业之后最常见的讨论不是“能做什么”而是“替换多少人、压缩多少工期”。如果团队只从这个角度引入模型模型很容易变成一种给研发、测试、供应商持续施压的杠杆也就是另一种内卷。真正值得走的路线是把国产 AI 用在知识检索、测试生成、变更分析、文档编写这些高重复、低创造性的环节里并且用可验证的输出、可追溯的来源、可度量的质量指标判断它到底有没有带来效率而不只是带来忙碌。下面用一条完整的工程链路来说明这件事从国产大模型的接口选型开始到搭建一个面向智能座舱知识库的 RAG 问答服务再到用小 Agent 生成软件测试用例最后用一个评估集对模型效果做回归。读完以后可以照着它在智能座舱、车机软件或研发平台里复现一条最小闭环。1. 国产 AI 在汽车项目中的正确位置生产可验证工件而不是单纯内卷1.1 先区分“效率工具”和“内卷工具”“内卷式使用 AI”有一个很容易识别的特征模型被用来批量生成无差别的输出这些输出从一开始就没有人准备执行比如自动生成 100 条没人运行的测试用例、自动回复 500 条没有校验的客服消息、自动重写 20 版文案。看起来速度很快实际上制造了大量需要清理的中间垃圾。在汽车软件项目中更合理的用法是把大模型当作“第一版草稿生产器”。它生成的东西必须进入一个明确的任务闭环测试用例生成后至少能被测试负责人评审并导入用例管理工具。产品问题回答必须引用用户手册或维修资料的原始章节。代码变更解释必须对应当前分支的实际 diff不能泛泛而谈。缺陷报告生成后需要与缺陷管理系统的字段一一对应。也就是说国产 AI 在汽车行业里真正要解决的问题不是“用更少的人干更多的活”而是“把重复劳动自动化之后让专业的人把时间花在异常判断、缺陷分析和质量决策上”。1.2 适合国产 AI 介入的典型场景场景输入输出质量底线智能座舱手册问答用户自然语言问题回答文字与引用章节答案能追溯知识库原文软件测试用例生成需求描述、PR 变更JSON 数组格式测试用例字段完整、步骤可执行研发代码解释与初步审查代码文件、变更 diff结构化说明和风险点不直接修改安全关键逻辑售后故障初筛用户故障描述建议检查顺序只辅助参考最终判断交还技师供应商交付文档比对旧版与新版文档变更摘要与影响点逐条映射到文档位置上面这几个场景有一个共同点它们都需要一套低代码或无代码的工程校验环节而不是“模型说出结果就算完成”。只有把校验环节做出来模型才不会变成内卷放大器。1.3 不适合的场景要靠规则兜底大模型不适合直接承担车辆功能安全判断比如根据诊断码直接决定是否切断动力、是否允许远程固件升级、是否触发制动。这类决策需要满足功能安全标准要求可解释、可回滚、可审计模型目前的概率输出形态无法单独承担。在生产项目里最稳妥的边界是让模型做自然语言理解、信息检索、文档摘要、测试草稿生成最终控制权始终留在规则引擎和有时间、有权限的工程师手里。2. 先把模型接入方式定下来API、本地部署与统一接口2.1 选 API 还是私有化部署不能只看参数大小汽车行业的数据边界比互联网应用敏感得多。很多座舱数据、诊断码、测试报告、供应链文件都不能随意离开企业内部网络。决定采用云端 API 还是本地部署主要看六项因素。决策项倾向云端 API倾向本地私有化部署落地提示数据能否出域可以出域不能出域或需要脱敏先做数据分类再选接入方式试点数据量小样本验证持续大批量索引试点期 API 更方便调用频率低频辅助高频在线服务高并发场景需要评估 GPU 显存延迟要求可接受秒级延迟需要低延迟或离线可用离线车端部署还需考虑量化迭代节奏希望立即用最新能力需要固定版本做回归私有化要自己做版本管理运维能力缺少 GPU 运维人员有模型服务团队本地部署不等于零运维先说明一点没有绝对正确的选择只有当下任务约束下的合适选择。如果是智能座舱用户手册问答数据本身不是高度机密的售后资料API 试点就可以如果要对未发布车型的测试报告做自动分析数据不能出域就要走本地部署。2.2 开发阶段用统一 OpenAI 兼容接口目前多数国产大模型服务都会提供兼容 OpenAI Chat Completions 的接口。开发时不要把请求代码和某一家厂商 SDK 绑死最好通过环境变量管理地址、密钥和模型名。这样后续切换模型只需要改配置不用重写代码。先准备 Python 环境python3 -m venv .venv source .venv/bin/activate pip install -U openai sentence-transformers numpy然后建立统一客户端import os from openai import OpenAI AI_BASE_URL os.environ.get(AI_BASE_URL, http://127.0.0.1:8000/v1) AI_API_KEY os.environ.get(AI_API_KEY, local-key) AI_MODEL os.environ.get(AI_MODEL, local-model) client OpenAI( api_keyAI_API_KEY, base_urlAI_BASE_URL, ) def chat_once(system_prompt: str, user_prompt: str, temperature: float 0.2) - str: resp client.chat.completions.create( modelAI_MODEL, messages[ {role: system, content: system_prompt}, {role: user, content: user_prompt}, ], temperaturetemperature, timeout60, ) return resp.choices[0].message.content配置示例export AI_BASE_URLhttp://127.0.0.1:8000/v1 export AI_API_KEYyour-local-api-key export AI_MODELyour-model-id如果本地用 Ollama 这类工具启动模型Ollama 会在本机提供一个类似的接口。实际项目里使用哪一个模型、什么版本要以企业获得的授权和内部评测结果为准不要在代码里写死一篇别人博客里给出的模型名。2.3 检查接口是否可用在写任何业务代码前先用一个最简单的请求验证当前模型服务是否正常。可以把下面的代码保存为smoke_test.pyif __name__ __main__: result chat_once( system_prompt你是一个汽车项目里的调试助手。, user_prompt请用一句话说明如果车辆启动时仪表盘亮起红色电池灯用户第一步应该做什么, temperature0.1, ) print(result)执行后能看到正常文本就说明地址、密钥、模型名和网络都通了。失败时先检查环境变量是否加载再检查模型服务日志。不要直接去调业务代码。3. 第一个可落地场景用 RAG 搭建智能座舱知识库问答3.1 为什么不直接让大模型背诵车辆手册整车用户手册动辄几百页不同车型配置差异也很大。直接把整本手册塞到提示词里既超出上下文窗口也无法保证回答使用的是最新版本资料。更常见的问题是大模型会根据自己的训练数据“脑补”出并不适用于当前车型的操作步骤这在售后场景里非常危险。RAG 的思路是“先检索再生成”。先用用户的问题检索相关资料再把检索到的高相关片段拼接到提示词中让模型只能依据这些片段回答。它不要求模型记住整车手册内容只要求它具备根据上下文做概括和转述的能力。3.2 最小步骤切分手册、生成向量、检索片段工程上可以把用户手册按 Markdown 的章节目录切块。切块不宜过大推荐以 500 到 800 字为一段同时保留一小段重叠避免一个完整操作步骤被从中间切开。这里给出一个示例代码结构实际项目可以根据自己的文档格式调整from langchain_text_splitters import RecursiveCharacterTextSplitter # 假设 manual_text 是从用户手册 Markdown 文件读取的完整文本 splitter RecursiveCharacterTextSplitter( separators[\n## , \n### , \n\n, 。, , ], chunk_size600, chunk_overlap100, ) chunks splitter.split_text(manual_text) print(f切分后共得到 {len(chunks)} 个片段)切分后使用中文向量模型为每个片段生成向量。下面的代码使用开源向量模型把文本转换成 768 维向量并用归一化后的向量计算余弦相似度from sentence_transformers import SentenceTransformer embedder SentenceTransformer(BAAI/bge-small-zh-v1.5) chunk_vectors embedder.encode(chunks, normalize_embeddingsTrue) def search_manual(question: str, top_k: int 3): question_vector embedder.encode([question], normalize_embeddingsTrue) scores chunk_vectors question_vector.T best_idx scores[:, 0].argsort()[-top_k:][::-1] return [chunks[i] for i in best_idx], [float(scores[i, 0]) for i in best_idx]上一步得到检索片段后再把它交给大模型生成最终回答。在调用大模型之前可以先打印检索结果经验是如果检索回来的片段本身就不相关后面再怎么优化提示词都不会有效果。3.3 引导模型只根据资料回答问题编写下面的问答函数def answer_from_manual(question: str) - str: hit_chunks, hit_scores search_manual(question, top_k3) context \n\n.join( [f资料片段 {i 1}\n{chunk} for i, chunk in enumerate(hit_chunks)] ) system_prompt ( 你是智能座舱使用助理。只根据用户提供的资料片段回答。 如果资料片段不足以回答问题必须回答“我没有找到相关资料”。 回答中不要编造车型或操作步骤。 ) user_prompt f资料片段如下 {context} 用户问题{question} 输出要求 1. 先给出简短回答。 2. 再说明依据来自哪一段资料。 3. 如果资料里没有答案只输出“我没有找到相关资料”不要解释。 return chat_once(system_prompt, user_prompt, temperature0.1)这个函数里的 system prompt 非常重要。在售后知识库场景中宁可让模型说“不知道”也不能让模型自己编造维修方案。3.4 RAG 生产化还要补四件事数据版本化手册更新后不能直接覆盖旧向量要保留版本号、发布时间和生效车型。低分拦截检索相似度低于某个阈值时不把资料片段交给模型。阈值需要根据实际数据调试常见起点是 0.3 到 0.5。日志留痕记录“用户问句、检索到的片段、模型输出、检索分数”后续做质量回看才方便。人工抽检每周抽 20 条问答日志判断回答是否引用了正确章节。这个动作不能省。4. 让大模型变成测试用例生成 Agent结构化输出和校验4.1 测试用例生成的边界设计很多团队把“大模型自动生成测试用例”理解成一句提示词拿到全部结果。实际工程里最容易出错的地方是输出格式不稳定、步骤不可执行、预期结果太模糊。要避免这个问题应该把任务限定成输入一段需求描述或一个 PR 变更说明。输出一个 JSON 数组每条用例包含字段id、title、precondition、steps、expected。校验程序自动检查字段是否齐全、steps是否为数组、是否存在重复id。这里举的场景是智能座舱远程控制功能。很多测试资产都是这一类面向用户体验的功能模型适合生成第一版用例但不适合在没有人工评审的情况下进入自动化执行队列。4.2 一个轻量 Agent 的最小实现下面的函数接收需求文本输出标准化测试用例 JSON。它只依赖上一节已经封装好的chat_onceimport json import re def generate_test_cases(requirement_text: str) - list[dict]: system_prompt ( 你是汽车座舱软件测试助手。 只输出 JSON 数组不要输出 Markdown不要增加任何解释。 数组每个元素必须包含字段id,title,precondition,steps,expected。 ) user_prompt f请根据以下需求生成测试用例数量控制在 5 到 10 条。 需求描述 {requirement_text} 要求 1. 覆盖正常流程、边界情况、异常输入。 2. precondition 写清楚前置条件。 3. steps 必须是字符串数组。 4. expected 写清楚可观察的期望结果。 5. 如果需求涉及车辆安全不要直接给出“允许执行”的结论。 raw_output chat_once(system_prompt, user_prompt, temperature0.1) raw_output raw_output.strip() raw_output re.sub(r^(?:json)?\s*, , raw_output) raw_output re.sub(r\s*$, , raw_output) try: cases json.loads(raw_output) except json.JSONDecodeError: raise ValueError(模型输出不是合法 JSON请查看完整原始输出。) if not isinstance(cases, list): raise ValueError(模型输出必须是 JSON 数组。) required_fields {id, title, precondition, steps, expected} for case in cases: if not required_fields.issubset(case.keys()): raise ValueError(f用例缺少必要字段{required_fields - case.keys()}) return cases运行示例python generate_test_cases.py 当车辆处于驻车挡且电量低于20%时用户在手机App点击远程启动空调应提示电量不足且不启动。一份正常输出可能是下面的结构[ { id: TC-001, title: 驻车挡低电量远程启动限制, precondition: 车辆处于P挡电池电量19%手机App已连接, steps: [ 打开手机App进入远程控制页, 点击远程启动空调, 观察结果 ], expected: 系统提示电量不足空调不启动 } ]4.3 为什么说它不是“套壳提示词”这套结构看起来只是“提示词 JSON”但工程上有三个关键点输出校验程序强制要求字段完整格式不对就报错而不是让脏数据进入测试管理系统。任务边界它只做“草稿生成”不做真实执行也不做安全结论。这样模型出错的后果可控。可追溯每条用例由哪段需求生成可以通过日志回看后续需求变更时能知道需要重新生成哪些用例。把这三个点做好模型就是一个可用的测试 Agent。一旦漏掉这三个点模型就直接退化成生成大量没人用的测试用例的工具也就是前面说的内卷工具。5. 用评估集做回归模型不可只靠手感判断5.1 先建立一个小而固定的评估集汽车项目里切换大模型、修改提示词、更新知识库都非常频繁。没有评估集的话团队只能靠个别人工抽查下结论很容易出现“看起来效果好但关键场景退步”的情况。评估集不需要一开始很大建议准备 20 到 50 条针对自身业务的问题。每一条都要包含问题正文。期望覆盖的要点列表。不该出现的内容。是否要求引用知识库来源。示例EVAL_SET [ { question: 车辆空调制冷效果差用户手册建议如何排查, must_have: [花粉滤芯, 风量设置, 制冷剂], must_not: [直接更换压缩机], need_source: True, }, { question: 手机App远程解锁失败第一步应该看什么, must_have: [网络状态, 车辆位置, 整车电源], must_not: [重新刷写控制器], need_source: True, }, ]5.2 用自动脚本计算关键指标下面是一个最小评估脚本逻辑def run_eval(question: str, must_have: list[str], need_source: bool) - dict: answer answer_from_manual(question) missing_points [] for point in must_have: if point.lower() not in answer.lower(): missing_points.append(point) return { question: question, answer: answer, missing_points: missing_points, need_source: need_source, }这个逻辑只能做初筛因为模型可能换一种说法表达同一个关键词。更准确的做法是用“裁判模型”做二次判断但裁判模型不能只看结论必须给它提供参考答案和打分维度。5.3 建议指标的速查表指标数据来源说明目标参考必答要点覆盖率评估集每条回答是否覆盖期望要点从 60% 起步逐步提高到 90%无依据回答率日志抽检模型是否回答了知识库不存在的结论越低越好目标是 0检索命中率知识库检索日志top 3 是否出现有效片段建议高于 85%API 失败率服务监控超时、限流、5xx 比例生产环境低于 1%测试用例格式通过率生成脚本JSON 可解析且字段完整比例应达到 100% 才放行指标项未被人工大改比例测试管理平台评审后保留原有用例的比例反映草稿可复用程度每周跑一次评估记录不同模型版本和提示词版本的结果。长期积累后团队在切换模型时就不会只凭某几个演示用例做决策。5.4 发布前要过的检查清单知识库版本是否已更新旧版本是否还能查询。提示词是否固定并纳入 Git 管理。是否有线上日志和检索分数。是否用同一套评估集跑过当前模型。是否存在安全结论场景被模型直接输出的情况。是否有回滚到上一版模型或知识库的方案。6. 常见问题排查从接口到输出效果的分层处理方法6.1 现象调用模型接口超时或限流可能原因检查方式处理建议环境变量没有加载envgrep AI_地址拼错或路径多一层打开文档核对 base_url 结尾统一使用.../v1作为 base_url模型服务未启动查看模型服务日志本地启动后重新验证smoke_test.py单次请求超时时间太短查看超时日志首轮请求设置 60 秒稳定后再调低6.2 现象回答内容与用户手册不一致可能原因检查方式处理建议检索回来的片段不相关打印search_manual返回的 top_k调整切块大小、top_k 或向量模型提示词没有做“只根据资料回答”的限制查看 system prompt增加强约束资料不足时直接拒绝回答车型版本信息丢失检查切块是否把“车型版本”切掉在切分时把源文件名和版本写进片段元数据模型被自身知识影响观察答案是否包含资料外专有名词降低 temperature增加参考片段来源标识6.3 现象测试用例输出不是合法 JSON可能原因检查方式处理建议输出被 Markdown 代码块包裹查看原始输出先剥掉代码块再json.loadstemperature过高导致格式漂移检查调用参数生成结构化内容时温度设为 0 到 0.2上下文里示例不足查看提示词是否只有文字说明在提示词中加入一个短示例生成内容被截断查看输出长度是否达到上限开启更长的 max_tokens 或拆分生成6.4 建议保留一套诊断函数在实际项目里建议不要只把最终结果打印出来还要输出原始模型返回、提示词模板版本、检索片段分数和调用耗时。这样遇到问题可以从日志里直接定位不用靠测试人员回忆“当时是什么现象”。7. 落地建议把国产 AI 从单点 demo 变成研发基础设施7.1 选择试点时坚持“小场景、强校验、可回滚”不要一开始就做“全车型知识库”或“所有测试用例自动生成”。建议先选择一个只有几百页文档的知识库或者一个需求描述非常规整的功能模块。范围越小校验成本越低越容易快速建立标注数据。7.2 把提示词和评估集纳入版本管理提示词就是软件资产。很多团队只管理代码不管理提示词导致模型效果变了却没法确定是模型升级还是提示词被改动。推荐在项目仓库里建立如下结构ai_platform/ ├── prompts/ │ ├── rag_answer.yaml │ └── test_case_generation.yaml ├── eval/ │ ├── eval_manual.json │ └── eval_test_cases.json ├── scripts/ │ ├── smoke_test.py │ ├── build_index.py │ └── run_eval.py └── logs/7.3 关键参数需要持续调参不能照搬默认值以 RAG 参数为例同样一段文本切得太碎会让一个完整步骤丢失上下文切得太大又会造成检索命中不精确。下面这张表可以当作调参起点。参数默认建议过低时的表现过高时的表现chunk_size500 到 800 字步骤被拦腰截断检索冗余内容多chunk_overlap80 到 150 字上下文连续性差重复片段多top_k3 到 5关键资料漏检无关片段干扰回答temperature0.1 到 0.2回答过于机械格式不稳定易编造检索最低分阈值0.3 到 0.5有效资料被拦截无关资料进入提示词7.4 行动清单在团队内部先定义“成功”不要只写“引入大模型提升了效率”要写清楚提升的是哪些可度量指标。找一个知识库问答场景用 RAG 做一个可以查版本、查引用的小服务。找一个测试用例生成场景用 JSON 输出做自动化校验。跑通之后再考虑接入更完整的 Agent 框架。每次更换模型或修改提示词都跑一次评估集。国产 AI 真正能给汽车产业带来的价值是让高重复工作不再消耗工程师的判断力让知识能够被快速检索、验证和沉淀。它不应该被包装成一条无限压低成本的流水线而应该是一套能自动生产草稿、持续校验质量、随时接受回归的基础设施。建立这样的工程习惯远比找一个新模型更重要。
返回列表