AI 工作流出错别急着甩锅:用一张日志表,查清模型到底在哪一步出了问题

AI 生成的活动文案把折扣写错了。

运营说:“模型就是这么生成的。”技术说:“接口返回正常。”审核人员又说:“我只调整了语气。”

可当大家准备核对原始记录时,才发现系统里只保存了最终稿。用户最初提交了什么、调用了哪个模型、使用哪版提示词、AI 原文是什么,全部无从查起。

这才是许多 AI 工作流真正危险的地方:不是模型会出错,而是出错以后没有证据,无法复现,更不知道该改哪里。

解决办法并不复杂。你不需要先购买专业监控系统,也不必会数据库。对大多数刚开始搭建 AI 工作流的个人和小团队来说,只要增加一张日志表,统一保存输入、模型原始输出、人工修改和错误信息,就能让黑箱第一次变得透明。

真正可靠的 AI 工作流,不是永远不出错,而是每次出错都有证据、能复现、能修正。

一、为什么 AI 工作流一出错,就像在黑箱里找针

一个常见的 AI 文案流程通常只有三步:

1. 用户填写产品资料;

2. AI 生成文案;

3. 运营修改后发布。

看起来很顺,但只要最终内容出现问题,排查就会立刻陷入混乱。

事实错误可能来自用户提交的信息;答非所问可能是提示词遗漏了上下文;文风漂移可能与模型或参数变化有关;最终稿中突然多出的错误,也可能是人工编辑时引入的。

如果系统只保存最终结果,这些可能性就无法逐一验证。

很多人听到“日志”,会想到服务器、数据库和复杂的监控平台。其实日志的本质只是一组连续的问题:

  • 谁发起了任务?
  • 什么时间发起?
  • 原始输入是什么?
  • 使用了哪版提示词?
  • 调用了哪个模型?
  • 模型原始回复是什么?
  • 人工后来改了什么?
  • 如果失败,错误信息是什么?
只要一张表能回答这些问题,它就是一套够用的 AI 调用日志。

二、先搭一张够用的表,不要一上来造复杂系统

下面这套字段可以直接复制到飞书多维表格、Excel、腾讯文档或 Airtable。示例内容仅用于演示字段结构。

| 字段 | 示例 | 用途 | | request_id | content_20250308_001 | 串联同一次任务 | | created_at | 2025-03-08 10:30:21 | 确认任务执行时间 | | workflow | 小红书文案生成 | 区分不同工作流 | | user_input | 产品名称、卖点、受众 | 保存用户原始需求 | | prompt_version | xhs_v3 | 判断提示词是否变化 | | model | 实际调用的模型名 | 排查模型差异 | | model_params | temperature 等实际参数 | 复现当时调用配置 | | model_output | 模型原始回复 | 保存未经编辑的结果 | | human_output | 人工审核后的版本 | 与模型原文进行对比 | | edit_reason | 数字核实、语气调整 | 统计高频修改原因 | | status | success / failed / edited | 快速筛选任务状态 | | latency_ms | 接口实际返回的耗时 | 排查响应速度问题 | | error_message | timeout | 定位失败原因 | | operator | 运营A | 确认操作人 |

如果想用 CSV 快速建表,可以复制下面的表头:

request_id,created_at,workflow,user_input,prompt_version,model,model_params,model_output,human_output,edit_reason,status,latency_ms,error_message,operator

哪些字段必须先记录

第一次搭建时,建议至少保留以下字段:

  • request_id
  • created_at
  • user_input
  • prompt_version
  • model
  • model_output
  • human_output
  • status
  • error_message
  • operator

其中最容易被忽略的,是 model_outputhuman_output

这两个字段绝对不能互相覆盖。如果运营修改后直接把 AI 原文替换掉,那么模型有没有写错、人工改了哪些内容,就再也无法确认。

正确做法是并列保存:

model_output:模型首次返回的原文

human_output:人工审核并修改后的最终稿

如果同一任务需要多次重新生成,还应保留原 request_id,再增加重试序号,或者为每次调用生成独立请求 ID,并通过父任务 ID 把它们关联起来。

配图 1:日志表字段创建页面。
画面应完整展示字段名称和字段类型,重点标出 request_idmodel_outputhuman_outputstatuserror_message

三、零代码实操:把工作流每一步自动写进表格

以“输入产品资料,让 AI 生成小红书文案,再由运营人工修改”为例,整个流程可以拆成八步:

flowchart LR

A[用户输入] --> B[创建任务 ID]

B --> C[记录输入]

C --> D[调用 AI 模型]

D -->|成功| E[记录模型原始输出]

D -->|API 调用失败| X[写入错误码和错误信息]

E --> F[人工修改]

F -->|审核通过| G[记录最终稿与修改说明]

F -->|审核退回| Y[记录退回原因并重新调用]

Y --> D

G --> H[查询与复盘]

X --> H

配图 2:自动化工作流全景图。
截图中应同时保留成功、接口失败和人工退回三条路径,避免只展示“理想流程”。

第一步:触发后立即生成任务 ID

不要等模型返回成功后再创建记录。用户提交表单或发送消息后,第一件事就应该生成 request_id

可以使用 UUID,也可以采用“业务名称+时间+序号”的结构:

xhs_20250308_001

任务 ID 的作用类似快递单号。后面的 API 请求、模型结果、人工审核和错误信息,都通过它串联起来。

配图 3:生成任务 ID 的节点配置。
展示任务 ID 的生成规则,以及它如何传递到后续节点。

第二步:先写入输入,再调用模型

生成任务 ID 后,先在日志表创建记录,写入:

  • 创建时间;
  • 工作流名称;
  • 用户原始输入;
  • 提示词版本;
  • 操作人;
  • 初始状态 processing

这样,即使后面的模型接口超时,日志表中仍然存在任务记录。

很多初级流程恰好做反了:先调用模型,成功后才写表。一旦接口失败,整个任务就像从未发生过,排错自然无从下手。

第三步:调用模型并保存真实配置

AI 请求节点至少需要记录:

  • 实际接口地址;
  • 实际模型名称;
  • 发送给模型的完整内容;
  • 关键模型参数;
  • 请求开始时间;
  • 返回状态。

如果你还没有可用于测试的模型接口,可以前往 api.884819.xyz 查看当前 API 接入方式,并按照平台最新文档填写接口地址、模型名称和鉴权信息。

首次测试建议只提交一条不含隐私的短文本,同时确认日志表是否记录了请求时间、模型名称、原始输出和错误信息。

8848AI 使用用户名和密码即可注册,不需要邮箱验证;平台内置 AI 对话功能,注册后可以直接使用。国产模型如 Deepseek、千问等完全免费,其他服务没有月租、没有订阅,按量付费。新用户注册即送体验token。

配图 4:AI API 请求节点的字段配置。
重点展示模型名称、消息内容、鉴权信息与超时配置;API Key 应以密钥变量方式引用,不要明文出现在截图中。

第四步:无论成功还是失败,都要回写日志

模型调用后,至少需要处理四种状态:

| 情况 | 状态建议 | 应记录内容 | | 正常返回 | success | 原始输出、模型、耗时 | | 请求超时 | failed | timeout、耗时、重试次数 | | 返回为空 | empty | 原始响应、空结果说明 | | 接口报错 | failed | HTTP 状态、错误码、错误信息 |

这里的关键原则是:失败不是流程的空白,也应该是一条完整记录。

配图 5:模型输出回写表格的映射关系。
展示 API 返回内容如何映射到 model_output,异常信息如何映射到 error_message

下面是一段最小化 Python 示例。具体接口地址、模型名称和返回结构,应以实际接口文档为准:

import time

import uuid

import requests

request_id = str(uuid.uuid4())

started_at = time.time()

payload = {

"model": "YOUR_MODEL_NAME",

"messages": [

{

"role": "user",

"content": "请根据以下产品信息生成一篇小红书文案……"

}

]

}

try:

response = requests.post(

"YOUR_API_ENDPOINT",

headers={

"Authorization": "Bearer YOUR_API_KEY",

"Content-Type": "application/json"

},

json=payload,

timeout=60

)

response.raise_for_status()

result = response.json()

model_output = result["choices"][0]["message"]["content"]

log_record = {

"request_id": request_id,

"status": "success",

"model": payload["model"],

"user_input": payload["messages"][0]["content"],

"model_output": model_output,

"latency_ms": int((time.time() - started_at) * 1000)

}

except Exception as error:

log_record = {

"request_id": request_id,

"status": "failed",

"error_message": str(error),

"latency_ms": int((time.time() - started_at) * 1000)

}

print(log_record)

这段代码的重点不是 Python,而是它体现了一条底线:成功与失败都必须生成日志,不能只记录成功任务。

实际使用时,还应在失败记录中补充模型名称、请求 ID 和经过脱敏的输入摘要,便于后续定位。

第五步:把人工修改也变成流程数据

假设用户原始需求是:

为一款新上市的无糖茶饮写小红书文案。

已确认卖点:0糖、茉莉花香、500ml。

目标用户:关注控糖的上班族。

禁止使用“减肥”“治疗”等表述。

实际发送给模型的提示词为:

你是一名消费品牌内容编辑。

请根据用户提供的已确认资料,生成一篇小红书文案。

不得补充未经提供的价格、折扣、功效或销量数据。

输出标题、正文和话题标签。

提示词版本:xhs_v3。

模型原始输出中出现了:

  午后想喝点清爽的?这瓶无糖茉莉茶可以试试。
  • 现在购买还可享受第二件半价,
500ml容量,适合通勤和办公室饮用。

人工修改稿变为:

  午后想喝点清爽的?这瓶无糖茉莉茶可以试试。

+ 0糖配方,带有清新的茉莉花香,

500ml容量,适合通勤和办公室饮用。

修改说明:

  • 🔴 删除:未经资料确认的“第二件半价”;
  • 🟢 新增:用户已提供的“0糖”和“茉莉花香”;
  • 🟡 核验:确认容量为 500ml;
  • 修改类型:事实核验 + 卖点补充

最终定位结果很清楚:错误来自模型自行补充促销信息,而不是人工编辑引入。

下一步也不应该只是提醒运营“仔细一点”,而应升级提示词,进一步明确“不得推测促销政策”,必要时再加入发布前的数字与营销信息审核规则。

配图 6:模型原始输出与人工最终稿并列显示。
建议在同一条记录中展示两列内容,并突出删除、新增和事实更正部分。

四、有了日志,怎样在 5 分钟内定位问题

日志不是为了追责,而是为了把“我觉得”变成“记录显示”。

情况一:模型答非所问

按以下顺序检查:

1. user_input 是否完整;

2. 实际发送的提示词是否丢失上下文;

3. prompt_version 是否为预期版本;

4. 表单字段是否映射到了错误位置;

5. 模型是否收到空字符串或被截断的内容。

如果原始输入完整,但发送给模型的内容不完整,问题在流程映射;如果输入和提示词都完整,才需要继续判断模型选择或提示词设计是否合适。

情况二:同一任务结果忽好忽坏

重点对比:

  • 是否调用了同一个模型;
  • 模型参数是否变化;
  • 是否发生自动重试;
  • 每次调用是否复用了相同上下文;
  • 不同结果对应的请求时间与提示词版本。

生成式模型本身具有一定随机性,但不能把所有波动都归咎于“AI 不稳定”。很多时候,真正变化的是参数、上下文或工作流配置。

情况三:最终稿出现模型原文中没有的错误

直接并列比较:

model_output  ↔  human_output

如果错误只出现在 human_output,就说明问题发生在编辑环节。此时应检查操作人、修改说明和最终发布版本,而不是继续调整模型提示词。

配图 7:失败任务筛选页面。
筛选条件设置为 status = failed,或 error_message 非空;建议同时显示请求 ID、创建时间、模型和错误信息。

一张可以收藏的排错清单

1. 是否生成了 request_id

2. 原始输入是否完整?

3. 提示词版本是否正确?

4. 实际调用了哪个模型?

5. 接口是否成功返回?

6. 是否发生超时或重试?

7. 模型原始输出是否正常?

8. 人工修改了哪些内容?

9. 最终结果来自哪个版本?

10. 日志中是否包含不该保存的敏感信息?

当团队持续记录一段时间后,日志还会暴露更有价值的规律。

如果运营总在修改标题,可能是标题规则不清楚;如果经常修正数字,应加强知识来源和事实核验;如果每篇都要调整品牌语气,则应优化提示词中的品牌风格要求,而不是让运营重复返工。

五、从“能记录”升级到“长期可用”的四条规则

1. 敏感信息不要原样落表

手机号、身份证号、客户隐私和内部机密应脱敏或不记录。日志的目标是帮助排错,不是复制一份新的敏感数据仓库。

2. API Key 永远不要写进日志

密钥应保存在自动化工具的凭证管理或环境变量中。日志可以记录“使用了哪个凭证配置”,但不能保存真实密钥。

3. 长文本不要无限塞进单元格

输入和输出较长时,可以保存摘要、文件地址或对象存储链接。需要注意访问权限,避免“表格做了权限控制,外部文件却公开可见”。

4. 先用表格,别急着上专业平台

个人与小团队先用飞书多维表格、Excel 或腾讯文档即可。只有当调用量、并发量、检索需求或审计要求明显上升后,再考虑迁移到数据库和专业可观测平台。

后续可以逐步增加:

  • 自动重试次数;
  • 成本估算;
  • 满意度评分;
  • 父任务 ID;
  • 提示词版本号;
  • 人工修改类型;
  • 修改差异统计;
  • 最终发布版本;
  • 审核人与审核时间。

不要第一天就设计几十个字段。今天先记录 8—12 个关键字段,实际运行一周,再根据排错需要增加内容。

现在就做一次“故意失败”的测试

复制本文的日志表模板,到 api.884819.xyz 按照当前页面和接口文档完成一次模型调用测试。

第一次可以故意填写一个错误参数,确认表格是否留下 failed 记录和错误信息;然后修正配置,再完成一次成功调用。

只有成功与失败都能找到对应记录,这套可追踪的 AI 工作流才算真正搭好。

行动清单如下:

  • 建立一张日志表;
  • 创建 request_id
  • 接入一次真实 API 调用;
  • 同时记录成功与失败;
  • 分开保存模型原文和人工修改稿;
  • 用失败筛选视图完成第一次排错。
新用户注册即送体验token。

日志解决的是“出错后去哪里查”。但当工作流每天产生大量调用时,新的问题会随之出现:哪些任务失败最多、哪个模型成本更高、哪版提示词返工更频繁?

下一篇,我们将继续使用同一张日志表,搭建一个零代码 AI 工作流仪表盘,自动统计成功率、响应时间、人工修改率和调用成本。 本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。

#AI工作流 #AI教程 #自动化 #API调用 #Prompt优化 #飞书多维表格 #人工智能 #8848AI