ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

给调试小黄鸭加上证据边界

给调试小黄鸭加上证据边界

向小黄鸭解释报错,本来就有用:为了把问题讲清楚,我们会重新整理输入、预期和实际结果。接上模型以后,这个动作更方便了,也多了一个风险——回复太像结论,容易让人跳过验证。

我想做的调试助手只负责整理材料与提出假设。它不把“听起来合理”标成“已经修复”,也不根据几句抱怨推断人的心理状态。一次合格的输出,至少应当说清楚:看到了什么、还缺什么、下一步如何证伪。

检查与执行要分开

Chrome 的 2026 年 10 月 DevTools 月报介绍了 MCP 的 JavaScript 执行控制,例如--no-javascript-evaluation。这篇月报实际发表于 9 月 22 日;“十月版”不能改写成十月刚发布。对独立工具的启发很具体:允许读日志,与允许执行脚本,应当是不同开关。

下面的例子没有连接模型,也不执行日志中的任何内容。它把输入整理成一份调试请求,输出两种互相竞争的解释:配置不一致,或输入不符合约定。候选解释只是示例,不是从日志推导出的诊断。真正使用时,应把模型回复放在“假设”栏,并要求每项附一个可观察的验证步骤。

脱敏是第二道防线

提交前先选择最小日志片段,删除账号、路径和业务数据,再做规则过滤。例子会遮住常见 token、Bearer 和邮箱,但这种正则不认识全部秘密:换一种字段名、把凭证写进 URL 查询串,都可能漏掉。它不能成为“日志可以随便上传”的理由。

本地运行node duck.js可验证常见敏感字段被遮住、空日志被拒绝、输入长度受限。这里没有上传服务、自动修复或浏览器集成;也没有做通用 DLP 检测。若要真正发送模型请求,界面应该先展示将发送的原文,取得用户的具体确认,并把执行权限留在另一道门后。

我喜欢小黄鸭的原因,不是它总能回答,而是它提醒人把问题讲完整。AI 助手也应保留这份克制:先帮我形成一个能验证的问题,再等证据决定结论。

可独立运行的核心例子

function redact(text) { return text .replace(/\bBearer\s+[A-Za-z0-9._~+\/-]+/gi, 'Bearer [已遮蔽]') .replace(/\b(token|api[_-]?key|password)\s*[:=]\s*[^\s,;]+/gi, '$1=[已遮蔽]') .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, '[邮箱]'); } function request(log, expected, actual) { if (!log.trim() || !expected.trim() || !actual.trim()) throw Error('请补充日志、预期与实际结果'); if ([log,expected,actual].some(x => x.length > 4000)) throw Error('请缩小为最小复现'); return { evidence:redact(log), expected:redact(expected), actual:redact(actual), permission:'只整理材料,不执行命令', hypotheses:[ {label:'示例假设:配置不同', verify:'对照两次运行的配置差异'}, {label:'示例假设:输入不同', verify:'固定同一份最小输入后重跑'} ], status:'待人工验证' }; } const sample=request('token=abc123 user=me@example.com', '返回200', '返回401'); if (sample.evidence.includes('abc123') || sample.evidence.includes('me@')) throw Error('脱敏回归失败'); let rejected=false; try { request('', '200', '401'); } catch { rejected=true; } if (!rejected) throw Error('空日志应被拒绝'); console.log(JSON.stringify(sample,null,2));

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进