测试转大模型后,Demo 跑通却上线失败,我踩过的权限和日志坑
发布时间:2026/8/25 23:19:45 作者:尧图编辑部 阅读量:1,286

聊《我用测试经验做了次 AI 项目最先失效的是旧方法》之前先说一句实在的别急着背概念先看它在真实项目里到底解决什么问题。摘要摘要从功能测试转向 AI 测试最容易高估模型效果、低估工程化成本。本文复盘一次 Agent 项目上线的真实踩坑经历重点讲权限控制、日志追踪和交付文档这三个比调参更折磨人的工程问题给出可复现的排查路径和代码示例。目录测试岗位的新变化从用例执行到链路可控AI 辅助测试工具很香但团队接手成本被低估自动化用例生成别只盯着模型输出质量Agent 测试框架权限、日志、可观测才是硬骨头质量评估业务方问的从来不是准不准失败原因业务错误、配置错误和环境错误的区分适用边界什么时候该用这套方法什么时候不该总结测试工程师的大模型跃迁路径---测试岗位的新变化去年我带团队接了一个内部知识库问答的 Agent 项目用的是 LangGraph 搭的 RAG 流程。Demo 阶段跑得很顺准确率 92%业务方很满意。结果上线第一周运维同学打了三个电话给我1. 某个接口超时但模型侧日志显示调用正常2. 权限校验绕过了普通用户能看到管理员才能查的文档3. 排查问题时根本不知道是哪个节点出了问题这三个问题没有一个和模型效果相关。这让我意识到测试工程师转大模型方向最大的能力跃迁不是学会用 Claude 写代码而是从验证功能对不对转向验证链路能不能控。Demo 阶段的测试思维是输入→输出对不对生产环境的测试思维是中间每个节点的状态、权限、日志、异常路径是否可观测。很多测试同学简历上写着熟悉 LangChain、熟悉 Prompt 工程但面试时问你的 Agent 项目怎么追踪一次错误调用经过了哪些节点基本答不上来。这不是能力问题是学习路径的盲区——学校教测试教的是功能测试和自动化测试企业招大模型测试需要的是工程化可观测能力。AI 辅助测试工具很香但团队接手成本被低估我接触过不少测试转大模型的案例大家普遍有一个误区先把 Demo 跑通再考虑工程化。实际结果是 Demo 很顺团队协作先崩了。一个典型的场景是某人用 Claude Code 或 Cursor 快速搭了一个带 Agent 的测试平台本地跑通后交给团队维护。接手的人发现三件事没有日志追踪不知道请求走到了哪一步权限配置散落在代码里改一个权限要翻三个文件交付文档只有 README没有接口说明和异常处理逻辑这些问题在单人 Demo 阶段不存在因为所有上下文都在作者脑子里。但团队协作时这些就是显性的接手成本。我在接手上一个同事的 Agent 项目时第一件事不是看模型效果而是查三样东西日志链路是否完整、权限是否集中管理、异常路径是否有兜底。这三样缺一样项目就无法稳定维护。测试工程师的优势在于对异常路径敏感。功能测试时我们习惯想如果输入为空怎么办这个思维在大模型项目中依然有效只是异常的定义从输入不合法变成了模型输出不可控。自动化用例生成别只盯着模型输出质量很多测试同学转向 AI 测试后花大量时间研究如何用模型生成测试用例、如何评估用例质量。这当然有价值但我认为优先级应该调整先把工程化基础打牢再谈用例生成的智能程度。一个可复现的真实案例项目背景给一个内部审批流 Agent 写自动化测试审批逻辑涉及三个模型节点意图识别、权限校验、结果生成。输入100 条测试用例覆盖正常流程和异常流程。步骤1. 用 Playwright 驱动前端模拟用户提交审批请求2. 用 Pytest 组织测试用例每个用例断言最终状态3. 在 LangGraph 的每个节点打点记录输入输出和耗时可观察结果正常流程95 条通过5 条失败分析失败用例后发现4 条是权限节点返回了意外的 token1 条是意图识别节点把请假识别成了调班关键发现模型输出质量问题只占 10%剩下 90% 是权限和日志追踪的问题。比如某条用例失败时日志显示权限节点返回了空 token但代码里没有记录为什么返回空排查花了两个小时。这个案例说明自动化用例生成的价值不在于生成更多用例而在于用工程化的方式暴露模型和链路的真实问题。Agent 测试框架权限、日志、可观测才是硬骨头这里给一个具体的代码示例展示如何在 Agent 项目中做基础的权限校验和日志追踪。import logging from functools import wraps from typing import Any, Dict # 配置结构化日志方便后续接入 ELK 或 Loki logging.basicConfig( levellogging.INFO, format%(asctime)s | %(levelname)s | %(node)s | %(request_id)s | %(message)s, ) logger logging.getLogger(agent_tracer) def trace_node(node_name: str): 节点装饰器记录每个节点的输入、输出和耗时 def decorator(func): wraps(func) def wrapper(*args, **kwargs) - Dict[str, Any]: request_id kwargs.get(request_id, unknown) logger.info( fnode{node_name} | req{request_id} | finput{kwargs}, extra{node: node_name, request_id: request_id}, ) start __import__(time).time() try: result func(*args, **kwargs) logger.info( fnode{node_name} | req{request_id} | foutput{result} | statusok, extra{node: node_name, request_id: request_id}, ) return result except Exception as e: elapsed __import__(time).time() - start logger.error( fnode{node_name} | req{request_id} | ferror{str(e)} | elapsed{elapsed:.2f}s, extra{node: node_name, request_id: request_id}, ) raise return wrapper return decorator def require_permission(role: str): 权限装饰器检查当前用户角色是否满足要求 def decorator(func): wraps(func) def wrapper(*args, **kwargs) - Dict[str, Any]: user_role kwargs.get(user_role) request_id kwargs.get(request_id, unknown) if user_role ! role: logger.warning( fPERMISSION_DENIED | req{request_id} | frole{user_role} | required{role}, extra{node: auth, request_id: request_id}, ) return {error: permission_denied, code: 403} return func(*args, **kwargs) return wrapper return decorator # 使用示例 trace_node(intent_recognizer) require_permission(admin) def process_approval(request_id: str, user_role: str, content: str) - Dict[str, Any]: # 模拟节点处理逻辑 return {status: approved, request_id: request_id}代码解释trace_node装饰器包裹每个 Agent 节点记录输入参数、输出结果和异常信息。extra参数用于结构化日志方便后续按request_id追踪完整链路。输入是节点名称和函数输出是增强后的函数异常时记录错误信息和耗时。require_permission装饰器集中管理权限校验避免权限逻辑散落在业务代码中。输入是期望的角色名校验不通过时返回统一的 403 错误格式便于前端和日志系统解析。两个装饰器可以叠加使用require_permission先执行权限不通过直接返回不进入节点逻辑。排查过程某次上线后业务方反馈某个普通用户提交了管理员才能审批的请求系统却返回了通过。排查链路如下1. 现象用户角色是employee但process_approval返回了approved2. 验证动作查日志搜索PERMISSION_DENIED发现该请求没有命中权限拦截3. 排除结果代码中require_permission装饰器确实存在但process_approval函数定义时漏加了该装饰器——这是一个典型的Demo 阶段没加上线前忘记补的错误4. 根因权限校验没有统一入口分散在各个节点的装饰器上容易遗漏这个案例说明权限问题不是模型问题是工程规范问题。测试工程师在 Code Review 时应该把权限是否集中管理作为必查项。质量评估业务方问的从来不是准不准Demo 阶段业务方关心的是准确率、响应速度、用户体验。上线后他们问的是三件事1.出问题了能不能快速定位——日志链路是否完整2.权限有没有漏洞——能不能越权操作3.新人能不能接手——文档是否清晰我在面试候选人时会问一个问题你的 Agent 项目如果线上出现一次调用错误你怎么在 5 分钟内定位到是哪个节点、哪条输入、哪个参数导致的能答上来的人基本具备大模型测试的工程化能力。质量评估的优先级应该是可观测性 权限安全 模型效果。模型效果可以用 prompt 调优、用 RAG 增强、用 fine-tune 改善但可观测性和权限安全是架构问题后期补成本很高。失败原因业务错误、配置错误和环境错误的区分Agent 项目上线后的失败大致可以归为三类区分它们能节省大量排查时间。业务错误模型输出不符合预期但链路本身是通的。比如意图识别把请假识别成调班RAG 召回了错误的文档。这类问题通常表现为准确率下降但日志完整、权限正常。修复方向是调 prompt、加 few-shot 示例、优化检索策略。配置错误代码逻辑没问题但参数配错了。比如上面提到的漏加权限装饰器、环境变量里 API Key 填错、数据库连接指向了测试环境。这类问题的特征是同一段代码在本地跑通上线就挂或者换个环境就出问题。排查时先看配置变更记录再对比不同环境的差异。环境错误基础设施层面的问题。比如模型服务超时、向量数据库连接池耗尽、网络抖动导致请求中断。这类问题通常伴随明显的错误日志timeout、connection refused且影响范围是全局的不是某个特定输入才触发。区分这三类的快速方法先看日志链路是否完整排除环境错误再看配置是否与预期一致排除配置错误最后看模型输出本身定位业务错误。很多团队一上来就调模型结果发现是环境变量配错了白白浪费时间。适用边界什么时候该用这套方法什么时候不该这套权限日志的工程化方案有明确的适用边界不是所有场景都值得照搬。适用场景多节点 Agent 系统3 个以上节点人工追踪链路成本过高团队协作项目需要多人维护和排查涉及权限敏感数据的系统内部知识库、审批流、用户数据查询需要满足审计或合规要求的场景限制条件单个节点的简单脚本或 Demo加这套框架反而增加复杂度个人学习项目目标是理解模型行为而非生产稳定节点数量少1-2 个且逻辑简单的场景日志追踪的收益有限团队没有日志平台ELK、Loki 等支撑结构化日志的查询和分析取舍结构化日志 vs 开发效率加trace_node装饰器需要每个节点手动标注初期会拖慢开发速度但换来的是排查效率。如果项目周期只有几周且不会上线可以只加关键节点的日志。权限集中管理 vs 灵活性把权限校验统一收口后新增特殊权限场景需要改框架代码不如散落在各处灵活。但如果团队超过 3 人集中管理的长期收益更大。完整链路追踪 vs 性能每个节点打点会引入少量延迟通常 10ms对实时性要求极高的场景需要权衡。什么时候不应照搬你只是在本地跑一个 RAG Demo 验证想法不需要上生产你的 Agent 只有 1-2 个节点且逻辑简单到一眼能看懂团队只有你一个人且你记得住所有代码的上下文项目生命周期不足一个月工程化投入收不回来识别这套方案的 applicability 很简单问自己如果明天我生病请假同事能不能在 30 分钟内定位线上问题。如果答案是否定的就需要补工程化如果答案是肯定的说明当前复杂度不需要过度设计。总结测试工程师的大模型跃迁路径从测试转大模型不是换工具是换思维。功能测试的思维是输入→输出AI 测试的思维是链路→可控。我的建议是1. 先补工程化基础日志追踪、权限管理、异常处理这三样比学会用 LangChain 更重要2. 用排查思维做测试不要只验证对不对要验证错了能不能快速定位3. 关注交付文档Demo 可以只有代码生产项目必须有接口说明、异常处理逻辑和排查手册4. 简历上突出工程能力写熟悉 LangChain不如写设计并实现了 Agent 节点的日志追踪和权限校验框架测试工程师的优势是对异常敏感、对边界条件敏感。把这些优势迁移到 AI 项目中关注权限、日志和可观测性你就能在 Demo 和上线之间找到真正的价值点。大模型应用的竞争早就不是谁的模型更聪明而是谁的系统更可控。资料展示下面是我整理的AI大模型学习资料和工具包预览适合收藏后按主题逐步学习。需要这份AI大模型资料清单的话在评论区回复「清单」即可我会根据大家的问题继续补充对应的实战内容。