2026-09-01 · 原文发布日
给AI智能体留飞行记录仪
n8n免费模板:Groq驱动的客服智能体每调一次工具就写一行日志到n8n数据表,记录会话、工具名、输入和返回;另做一项数字审计,检查最终回答里的每个数字是否能在问题、工具输入或结果中找到,找不到的写进审计备注,回复末尾附一行工具使用摘要。作者明确说这只做算术核对不做事实判断。
原文要点
原模板是一个Groq驱动的客服智能体:n8n Chat触发器接收消息并维持会话,智能体可调用计算器工具和一个内置三笔虚构订单的演示订单查询工具;流程把智能体的中间步骤转成每次工具调用一行日志,写入n8n内置Data Table,字段含session_id、logged_at、step_index、tool_name、tool_input、observation、final_answer_excerpt、audit_note;另有数字审计,把最终回答里的每个数字与问题、工具输入、工具结果比对,找不到来源的数字写进审计备注,回复末尾附一行工具使用摘要。作者明确该检查只做数字算术核对、不做事实判断,不拦截不改写回答;日志依赖智能体节点开启返回中间步骤,若未来版本变更日志会变空而不是出错。Groq免费档API key即可运行演示。
这次做成什么
给自己的AI智能体加一份“飞行记录仪”:每次工具调用落一行日志,回答发出前做数字来源核对并在回复末尾附工具摘要。练习方案:先用模板自带的三笔虚构订单跑一遍,再用本站独立写的审计代码和测试问题验证日志行与审计备注,最后才把演示工具换成真实订单查询。
准备什么
- n8n实例,版本包含内置Data Tables功能
- 一个Groq API key并在Groq Chat Model节点中选用
- 原模板已开启智能体节点返回中间步骤的选项,需保持开启
- 无需外部数据库,日志存在n8n自己的数据表里
具体怎么做
导入模板并接Groq凭据
从n8n工作流库获取该免费模板导入,打开Groq Chat Model节点选择自己的Groq凭据。先不改任何工具,用模板自带的计算器和演示订单查询工具运行一次,确认聊天触发器能正常收发消息。
建飞行日志数据表
在n8n Data Tables中新建一张表,按artifacts配置建好session_id、logged_at、step_index、tool_name、tool_input、observation、final_answer_excerpt、audit_note八列,并在写入节点中选中这张表、逐列绑定字段。
理解日志写入逻辑
模板把智能体返回的中间步骤数组逐条展开:每个元素对应一次工具调用,取工具名、输入、返回结果,加上会话ID、序号、时间戳和最终回答节选,一行一行写入数据表。智能体没用工具时也会留一行说明,这一行往往最关键。
挂上数字审计
在生成最终回答之后、回复用户之前接入审计代码节点,可粘贴artifacts里本站独立编写的示例代码:提取回答中的全部数字,在原始问题、各次工具输入、各次工具结果中查找,找不到的记入audit_note,并生成“使用了哪些工具”的一行摘要拼在回复末尾。
用测试问题验证
在聊天里发送下方example的测试问题,触发一次订单查询加一次计算。然后打开数据表检查:应有两行工具日志,audit_note为空或标注未匹配数字;回复末尾应有一行工具使用摘要。
替换真实业务工具
确认日志机制工作正常后,把演示订单查询工具换成真实的订单状态接口,保持工具名称和输入输出结构一致,日志和审计无需改动;日志不绑定具体工具和模型,换模型也不影响记录。
可直接复制的材料
飞行日志数据表列配置
本站按原文列名整理的建表方案,列类型以你的n8n Data Tables版本可选类型为准。
表名建议:agent_flight_log
列定义(均为文本列,logged_at可存ISO时间字符串):
session_id 会话ID,同一次对话多行日志共享
logged_at 写入时间,ISO 8601格式
step_index 工具调用序号,从1开始
tool_name 工具名,如 calculator、order_lookup
tool_input 传给工具的原始输入,JSON字符串
observation 工具返回结果,JSON字符串
final_answer_excerpt 最终回答前200字符节选
audit_note 数字审计备注,无异常时为空字符串
未使用任何工具时:tool_name填 none,tool_input与observation填空,step_index填0。数字审计示例代码(Code节点,JavaScript)
本站独立编写的示意实现,需按你流程里实际的字段名调整$json取值;短数字容易被偶然匹配,只作提示不作结论。
// 输入:$json.finalAnswer 最终回答,$json.question 原始问题,$json.steps 工具步骤数组
const answer = String($json.finalAnswer || "");
const haystacks = [String($json.question || "")];
for (const s of ($json.steps || [])) {
haystacks.push(JSON.stringify(s.input || ""), JSON.stringify(s.output || ""));
}
const hay = haystacks.join(" ");
const nums = answer.match(/\d+(?:\.\d+)?/g) || [];
const unsupported = [...new Set(nums.filter(n => !hay.includes(n)))];
const toolsUsed = [...new Set(($json.steps || []).map(s => s.tool))];
const auditNote = unsupported.length
? "未找到来源的数字: " + unsupported.join(", ")
: "";
const summaryLine = "[飞行日志] 使用工具: " + (toolsUsed.length ? toolsUsed.join("、") : "无")
+ (auditNote ? ";" + auditNote : ";数字均有来源");
return [{ json: { audit_note: auditNote, reply: answer + "\n" + summaryLine } }];订单查询系统提示词片段
本站为配合数字审计独立撰写的约束提示词,可放进智能体系统消息;原模板行为以模板实际配置为准。
你是客服助手。回答订单金额、数量、运费等任何数字之前,必须先调用订单查询或计算器工具获得该数字,不得凭记忆编造。回答中只允许出现来自用户问题、工具输入或工具返回的数字。查不到的信息直接说明未查到,不要估算。输入与输出示例
本站虚构演示,A102等数字为演示订单数据,非模板实际运行结果。
输入
聊天发送:我的订单A102一共两件,单价129元,运费另算8元,帮我算总价并告诉我订单状态。对应输出
智能体调用order_lookup({"orderId":"A102"})返回{"status":"已发货","items":2,"unitPrice":129},再调用calculator计算2*129+8=266。回复为:订单A102状态为已发货,总价266元(2件×129元+运费8元)。\n[飞行日志] 使用工具: order_lookup、calculator;数字均有来源。数据表新增两行:step_index=1 tool_name=order_lookup,step_index=2 tool_name=calculator,两行audit_note均为空。做完检查这些
- 聊天触发一次后,数据表行数等于该轮工具调用次数,未用工具时有一行tool_name为none的记录
- 每行日志的tool_input与observation与画布执行记录中对应工具的输入输出一致
- 回答中凭空出现的数字(如把运费说成10元)会出现在audit_note里
- 回复末尾固定有一行以[飞行日志]开头的工具使用摘要
- 把演示订单工具换成真实接口后,日志列映射无需修改仍能写入
容易卡住的地方
- 日志完全依赖智能体节点返回中间步骤,该选项被关闭或版本变更时日志会变空而不是报错,升级后要复查
- 数字匹配是宽松的字串匹配,像2这样的短数字几乎总能偶然匹配上,审计备注要人工看而非当判决
- 审计只做数字核对,不含数字的虚构句子不会被发现,它也不拦截或改写错误回答
- Groq凭据未配置时智能体本身无法运行,但日志表结构可以先建好
- 演示订单工具只有三笔虚构订单,接真实业务前不要用它回答真实客户
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Log, audit and escalate AI agent tool calls with Groq, Discord and data tables
- 原作者
- Melbin Francis
- 原始发布日期
- 2026-08-31T22:48:26.114Z
- 来源
- https://n8n.io/workflows/18959