ARTICLE DETAIL

资讯详情

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

AI 工作流失败复盘:先定位输入、模型还是工具调用

AI 工作流失败复盘:先定位输入、模型还是工具调用 AI 工作流失败复盘先定位输入、模型还是工具调用AI 工作流失败时先判断输入、模型输出还是工具执行最早偏离预期。为每个节点保存脱敏摘要、状态码与版本信息便于构造相同条件并重放状态机路径。1. 问题现象与排查入口排查时可抽取脱敏样本用抓包与日志重放还原调用顺序# 过滤排查业务网关日志中的异常请求序列 grep -E ERROR|ExtractFailed /var/log/workflow/app.log | tail -n 50 # 查找匹配 TraceID 的原始日志发现日志中缺失了发给大模型的完整 Prompt jq . | select(.trace_idtr-9023812) /var/log/workflow/trace.json可以从三个容易缺记录的节点开始检查Prompt 模版未版本化代码里用的 Prompt 字符串是动态拼接的线上跑的到底是哪个模版版本无法回溯。入参与出参快照缺失出于隐私限制上游过滤掉了原始文本导致只留下了最终报错中间 LLM 返回的原始字符串Raw Output直接丢弃了。降级保护缺失当 LLM 没有按 JSON Schema 返回时系统没有自动修复Auto-Repair和硬编码兜底机制直接抛出未捕获异常。2. 具备完整证据链捕获的工程实现为了让每一次失败实验和线上故障都能“留有痕迹”可以在 Node.js/TypeScript 服务端重构工单处理流程。核心要求有两个一是在请求全生命周期埋入不可变 Trace Snapshot二是引入确定性的 Schema 校验与兜底降级。import { createHash } from crypto; interface AuditSnapshot { traceId: string; templateVersion: string; rawInput: string; renderedPrompt: string; rawOutput?: string; parsedResult?: Recordstring, any; status: SUCCESS | FORMAT_ERROR | TIMEOUT | FALLBACK; errorDetail?: string; durationMs: number; } export class TicketProcessor { private templateVersion v2.1.4; constructor( private llmClient: { complete: (prompt: string) Promisestring }, private auditStore: { save: (snapshot: AuditSnapshot) Promisevoid } ) {} private renderPrompt(ticketContent: string): string { return You are a professional customer support classifier. Analyze the following ticket and return STRICT JSON with format: {category: string, priority: LOW|HIGH}. Do NOT add markdown block quotes or explanations. Ticket Content: ${ticketContent}; } private tryParseJson(text: string): Recordstring, any | null { try { // 清楚可能存在的 markdown 标记 (如 json ... ) const cleaned text.replace(/json\s*|\s*/g, ).trim(); return JSON.parse(cleaned); } catch { return null; } } public async processTicket(traceId: string, ticketContent: string): Promise{ category: string; priority: string; isFallback: boolean } { const startTime Date.now(); const renderedPrompt this.renderPrompt(ticketContent); const snapshot: AuditSnapshot { traceId, templateVersion: this.templateVersion, rawInput: ticketContent, renderedPrompt, status: SUCCESS, durationMs: 0 }; try { // 调用模型服务 const rawOutput await this.llmClient.complete(renderedPrompt); snapshot.rawOutput rawOutput; // 强校验 JSON 解析 const parsed this.tryParseJson(rawOutput); if (!parsed || !parsed.category || !parsed.priority) { snapshot.status FORMAT_ERROR; snapshot.errorDetail Model output failed schema validation; // 触发降级逻辑写入人工审核队列 await this.auditStore.save({ ...snapshot, durationMs: Date.now() - startTime }); return { category: UNCATEGORIZED, priority: HIGH, isFallback: true }; } snapshot.parsedResult parsed; snapshot.durationMs Date.now() - startTime; await this.auditStore.save(snapshot); return { category: parsed.category, priority: parsed.priority, isFallback: false }; } catch (err: any) { snapshot.status err.name TimeoutError ? TIMEOUT : FALLBACK; snapshot.errorDetail err.message || String(err); snapshot.durationMs Date.now() - startTime; await this.auditStore.save(snapshot); // 线上保底出错绝不能卡死业务流程 return { category: SYSTEM_FALLBACK, priority: HIGH, isFallback: true }; } } }3. 故障快照复盘与对比分析这套证据链埋点上线后当再次遇到类似故障时可以直接根据trace_id抽取完整快照。通过数据库查询或日志检索直接对比正常与异常请求的入参特征# 从证据链快照中按状态检索异常记录 sqlite3 /data/audit/snapshots.db \ SELECT trace_id, template_version, error_detail, duration_ms FROM snapshots WHERE statusFORMAT_ERROR LIMIT 10;应加入一类边界用例工单正文包含大括号、引号和日志片段。若输入没有分隔与转义模型可能把用户内容误当成指令测试应验证模板边界和结构化字段不会被覆盖。修复后应按同一任务集复测并记录稳定性与自动流转率指标维度证据链建立前证据链建立后故障定位平均时长 (MTTR)记录证据链建立前记录证据链建立后未捕获异常比例记录证据链建立前记录证据链建立后Prompt 模版追踪粒度无记录精确到 Git Commit 版本号工单流转兜底成功率记录证据链建立前记录证据链建立后4. 经验总结在传统业务中落地 AI 功能最要紧的不是追求模型有多聪明而是保证系统足够健壮。Trace ID 应贯穿 Prompt 渲染、模型响应摘要、Schema 校验和降级分流。日志先脱敏并设置留存期限复盘时从第一次状态偏移开始检查。
返回列表