ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

散步清单可以记忆,不能替人下单

散步清单可以记忆,不能替人下单

一个散步助手可以记住“想去河边”“回程买面包”,但“记住偏好”和“代替执行”之间,隔着一条很实在的线。尤其当 Agent 能调用浏览器或商店接口时,一条随口记下的愿望,不该直接变成订单。

把动作写成状态,而不是一句自然语言

我会把清单分成建议、待确认、已完成三栏。加入清单只产生建议;涉及购买的项目必须由用户显式确认,才能进入待执行状态。完成又是另一个动作,不能因为确认过就自动打勾。普通散步地点也保留“未执行”的状态,免得下一次打开时,系统编出一次不存在的行程。

10 月 22 日移交给 AAIF 的 Agent Skills强调可复用工作流。我的理解是:工作流越容易复用,越要把确认点放在状态转换里。仅在提示词末尾写“请谨慎”,既不能留下明确记录,也难以阻止代码把建议直接当命令。

记忆要有来源和删除口

下面的纯函数不发送请求、不定位,也不下单。每条项目保留创建来源,购买确认必须传入一条与当前项目 ID 对应的确认记录。示例中的记录仍由调用方构造,生产系统必须由可信的用户交互产生,不能相信模型自己给出的approved:true。

保存清单时,还应区分一次性任务与长期偏好。一次买过面包,不等于以后每次都要买;删除一条记录,也应该能删除它对推荐的影响。这里没有做跨设备同步或账号身份验证,本地示例只演示最容易被省略的状态约束。

执行node walk.js会验证购买未确认时被拒绝、确认不能串用、已完成项目不重复执行。它不会核实真实路线、安全状况或商店营业时间,这些需要实际服务与当下信息。一个值得信任的散步助手,应该让人走得轻松,同时把决定权留在人手里。

可独立运行的核心例子

function create(id,title,kind='walk') { if(!id || !title.trim() || !['walk','purchase'].includes(kind)) throw Error('无效项目'); return {id,title,kind,state:'suggested',source:'user-entered'}; } function confirm(item,event) { if(item.state!=='suggested') throw Error('状态不允许确认'); if(event?.itemId!==item.id || event?.actor!=='user') throw Error('缺少本项目确认'); return {...item,state:'ready',confirmationId:event.id}; } function complete(item) { if(item.state!=='ready') throw Error('尚未确认或已经完成'); return {...item,state:'done'}; } function mustReject(fn) {let ok=false;try{fn();}catch{ok=true;}if(!ok)throw Error('应拒绝');} const bread=create('bread','回程买面包','purchase'); mustReject(()=>complete(bread)); mustReject(()=>confirm(bread,{id:'e0',actor:'user',itemId:'other'})); const ready=confirm(bread,{id:'e1',actor:'user',itemId:'bread'}); const done=complete(ready); mustReject(()=>complete(done)); if(bread.state!=='suggested' || done.state!=='done') throw Error('状态污染'); console.log(JSON.stringify({before:bread,after:done},null,2));

RELATED READING

延伸阅读

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