聊《大模型岗位变了,测试工程师该补的还是算法吗?》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。
摘要
上周和一个做测试的朋友聊天,他说最近面试了几家招大模型相关岗位的公司,面了三轮,前两轮还行,到第三轮被问住:"你做过的项目,线上出问题时怎么排查?"他愣是没答上来。
不是因为他技术不行,而是他之前做的事和大模型上线真的差了一截。
我做过类似的转型,也带过从测试转大模型的同学。今天想把这条路上的坑和判断标准拆开说,不聊虚的,只聊你实际该补什么。
---
目录
- 测试岗位正在变味
- 大模型项目里的真实案例
- 排查过程:权限崩溃是怎么发生的
- 代码解释:Agent 测试框架的核心逻辑
- 失败原因:为什么很多人 Demo 过了,上线就崩
- 适用边界:什么时候不该照搬这套方案
- 总结
测试岗位正在变味

以前做测试,核心技能是写用例、跑自动化、提缺陷。现在大模型项目进来,需求变了。
典型场景:业务方不再只说"做个功能",而是说"做个能帮用户查订单的助手"。你写的接口用例还是对的,但问题是,这个助手会不会乱答?会不会把用户隐私泄露出去?响应慢不慢?这些都不在传统测试的范围内。
我见过一个真实的入职项目,甲方要一个智能客服 Agent,能读订单表、查物流、还能根据用户语气调整回答风格。Demo 阶段跑得很顺,业务方很满意,结果一上 staging,第二天就被投诉了:
- 有的用户能查到别人的订单
- 有的接口调用时 token 超限没人报警
- 日志里没有 trace_id,出了问题根本定位不到
这三件事,任何一个单独拿出来,都不难修。但组合在一起,就是典型的"测试转大模型"时缺的那一环。
结论:测试工程师的优势是验证思维,缺的是对 Agent 行为边界和可观测性的理解。
---
大模型项目里的真实案例

我来讲一个自己做过的实战,这个项目后来也成了我简历上的核心条目。
项目背景:给内部运营团队做一个"数据查询助手",基于 LangChain + PostgreSQL,支持自然语言查数据。
输入:
- 用户提问:"上个月华东区销售额前三的商品是什么?"
- 大模型需要生成 SQL,执行查询,返回结果
步骤:
1. 用 LangChain 的 SQLDatabaseChain 构建 Agent
2. 配置权限,限制只能查特定表的特定列
3. 加日志,记录每次查询的 prompt、生成的 SQL、执行结果
4. 设计测试用例覆盖正常场景、越权场景、长尾场景
可观察结果:
| 场景 | 预期 | 实际 | 问题 |
|------|------|------|------|
| 正常查询 | 返回正确结果 | ✅ 通过 | — |
| 查询其他用户数据 | 拒绝 | ❌ 返回了数据 | 权限校验未生效 |
| 超长 prompt | 截断后处理 | ❌ 崩溃 | 没做输入长度限制 |
| 无日志 trace_id | — | ❌ 查不到上下文 | 日志缺失 |
这个案例告诉我:Demo 能跑通只是及格线,真正的门槛在后面上线阶段。
---
排查过程:权限崩溃是怎么发生的
那个查询助手的越权问题,我是这样定位的:
现象:用户 A 输入"查我的订单",返回了用户 B 的订单信息。
第一步:复现。用两个不同的 user_id 分别登录,A 登录后查看是否能看到 B 的数据。确认问题存在。
第二步:看日志。发现生成的 SQL 里没有 WHERE 条件里的 user_id 过滤。但代码里明明有这段逻辑:
query = f"SELECT * FROM orders WHERE user_id = {user_id}"
第三步:验证参数传递。在 SQL 生成前后加打印,发现 user_id 在链式调用中丢了。定位到 LangChain 的 SQLDatabaseChain 在拼接 prompt 时,自定义变量没有被正确注入。
第四步:修复。改成用 ChatPromptTemplate 显式声明变量,并确保 user_id 从 session 中取出后传入:
from langchain.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_messages([
("system", "你是数据查询助手。"),
("human", "用户 {user_id} 请求查询数据,请生成 SQL。"),
])
# 确保 user_id 从 session 获取并传入
prompt = template.invoke({"user_id": request.user.id})
结论:权限问题不是模型不会,是框架使用不当。这个问题在 Demo 阶段很难暴露,只有做多用户场景的测试才会触发。
---

代码解释:Agent 测试框架的核心逻辑
下面这段代码是我为 Agent 项目写的测试辅助类,核心思路是把"权限、日志、输出"三件事串起来验证。
class AgentTestRunner:
def __init__(self, agent, db_connection):
self.agent = agent
self.db = db_connection
self.trace_log = []
def run_and_verify(self, user_id, question, expected_pattern):
# 1. 捕获本次调用的 trace_id
trace_id = str(uuid.uuid4())
# 2. 执行 Agent,传入 user_id 限制权限
result = self.agent.invoke({
"user_id": user_id,
"question": question
})
# 3. 检查输出是否符合预期模式
if not re.search(expected_pattern, result):
raise AssertionError(f"输出不符合预期: {result}")
# 4. 记录日志,包含 trace_id 便于排查
self.trace_log.append({
"trace_id": trace_id,
"user_id": user_id,
"question": question,
"result": result,
"timestamp": datetime.now().isoformat()
})
return result
逐段解释:
__init__:初始化 Agent 实例和数据库连接,准备一个空的日志列表。run_and_verify:核心测试方法,接受三个参数——user_id用于权限隔离,question是测试输入,expected_pattern是用正则写的预期输出格式。trace_id:每次调用生成唯一 ID,后续排查问题可以直接在日志里搜这个 ID。self.agent.invoke:调用 Agent,注意user_id必须显式传入,不能依赖框架默认行为。- 正则校验输出:防止 Agent 返回格式完全错误的内容。
- 日志记录:用字典结构存每次调用的关键信息,方便事后分析。
异常处理:如果输出不符合预期,直接抛 AssertionError,测试框架(pytest)会自动标记为失败。
---
失败原因:为什么很多人 Demo 过了,上线就崩
我见过的失败案例,基本可以分成三类:
1. 业务错误:理解错了需求。比如以为"智能客服"只需要回答问题,忘了还要考虑用户的敏感信息不能泄露。这类问题通常出现在需求评审阶段,测试工程师应该介入提反问。
2. 配置错误:框架用对了,但参数配错了。比如上面的案例,user_id 没有正确传入,导致权限校验失效。这类问题靠走查和单测可以避免。
3. 环境问题:本地跑得好好的,上线因为数据库连接池不够、token 限制、网络超时挂了。这类问题需要在 staging 环境做压力测试,不能只在本地验证。
如何区分:最简单的办法——看报错信息。业务错误通常表现在结果不对但没报错;配置错误会有明确的异常栈;环境问题多半是超时或连接失败。
---
适用边界:什么时候不该照搬这套方案
这套方法的核心是权限控制 + 日志追踪 + 自动化验证,适用于以下场景:
- 需要处理用户数据的 Agent(客服、数据分析、内部工具)
- 多人协作的项目(日志 trace_id 是协查的基础)
- 对输出质量有要求的场景(医疗、金融、电商)
不适用的场景:
- 纯展示型的 Demo,没有真实用户数据
- 离线批处理任务,不需要实时响应和权限隔离
- 个人学习项目,只是为了熟悉框架 API
取舍建议:如果时间紧,优先保证权限和日志,输出验证可以后补。如果三者都要,建议从单测开始,逐步扩展到集成测试。
---
总结
测试转大模型,不是要你去学算法,而是要你补上两样东西:
第一样是对 Agent 行为边界的理解。知道权限、日志、可观测性这些概念在实际项目中怎么落地。
第二样是工程化的测试能力。光会写用例不够,还要能把权限校验、日志追踪、异常场景验证串成自动化流程。
Demo 能跑通不难,难的是让它在真实环境里稳定运行。这也是面试官真正想看到的——你能不能把测试思维用到新领域,而不是只会套旧方法。
资料展示
下面是我整理的AI大模型学习资料和工具包预览,适合收藏后按主题逐步学习。



如果你想看完整资料目录,可以在评论区留言「资料」;也欢迎告诉我你更关注AI大模型里的哪类内容。

5104



被折叠的 条评论
为什么被折叠?



