前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯9865
  • OpenAI 将 ChatGPT 打造成操作系统:工作区、协作文档、MCP 全上线
  • OpenAI Codex 上线 GPT-6.1 Sol:性能逼近 Astra 但成本更低
  • OpenAI 扩展 ChatGPT 插件:新增应用侧边栏、文件查看器和 MCP 自动化
  • OpenAI Codex 新增跨设备云开发环境和语音 CLI
  • GPT-6.1 Sol发布:低成本匹敌旗舰,价格仅为1/5
  • GPT-6.1 Sol一周内连发,以低价挑战自家旗舰
  • OpenAI推出Dots:基于GPT-6 Astra的常驻智能体
  • OpenAI Dots对标Meta Muse,推全天候后台智能体
  • DevDay发布Codex重大更新:安全扫描、Ultrafast极速档
  • GPT-6.1 Sol内部测试:成本仅Astra五分之一,但欺骗率略升
  • GPT-6.1 Sol:五分之一价格,近 Astra 智能
  • GPT-6.1 Sol 登陆 GitHub Copilot,支持多步 Agent 编码
  • OpenAI DevDay 2026 重磅发布:20+ 新品与 GPT-6 新动向
  • Replit 解析 Agent 模型调度:无套索设计让模型自主决策
  • Simon Willison OpenAI DevDay 2026 实时博客
  • NVIDIA Kumo刷新表格数据预测精度与效率边界
  • 企业级AI记忆架构:Hindsight在财务审查中分离记忆与权限
  • MCP Agents的源码级验证:来源感知验证方法
  • MCP 协议:让 AI 智能体安全接入现有 API
  • 每个任务一个git worktree:避免coding agent文件冲突
  • 机器记忆Agent实践:发现自己在用Recall而非Reflect
  • 8个真实n8n自动化案例:发票处理与线索富化实战
  • Cloudflare 用 AI 发现代码库加密方案,推进后量子迁移
  • DeepSeek Harness 桌面端 v0.2:支持插件安装与自动化任务
  • Ember-1对比Kimi K3:速度快3.4倍效果相当
  • Cursor/Replit/Perplexity为何自训练模型而非套壳
  • OpenAI 发布 GPT-6.1 Sol:编程与电脑操控智能体,价格为 Astra 五分之一
  • Google开源RRSI:让AI Agent自己优化提示词和工具链
  • GPT-6.1 Astra因欺骗性行为被OpenAI紧急叫停
  • Mac mini本地跑8B模型反而比4B更差
  • 12款AI客户端OpenAI兼容端点配置表
  • 每周节省数小时React开发的30个Cursor提示词
  • H Company开源Holo4:支持电脑控制的27B/35B大模型
  • AI作为团队成员:分配、治理与审查实践指南
  • IncidentBrain:能从故障中学习的SRE事故响应代理
  • AI代理读取整页的代价:Playwright与thinbrowser对比
  • PostgreSQL 与 MySQL 存储引擎可插拔架构详解
  • 阿里 Qwen 发布全双工语音模型 Qwen-Audio-3.1
  • Anthropic 发布 Claude Sonnet 5.5:基准跃升、价格不变
  • Edge 浏览器新增性能分析工具与 WebMCP AI 智能体 API
  • AI编程增量改动如何悄然腐蚀系统架构
  • DeepSeek V4费用因时段和渠道差异可达2倍
  • MCP服务器供应链攻击警示:credential窃取实案
  • Claude Code 下一代功能:Mods、插件、项目与标签系统
  • 用 Gemini Live API 构建实时语音 AI 代理
  • 7 种生产环境 AI 代理沙箱隔离方案
  • Grok 4.7登陆AWS Bedrock:50万token上下文支持编程
  • Claude Sonnet 5.5 发布:提速 30% 降价 30%
  • Claude Sonnet 5.5 高风险请求会被静默降级至 Sonnet 5
  • OpenAI披露可像蠕虫传播的新型提示注入攻击
  • Salesforce Agentforce 曝零点击数据泄露漏洞
  • 已加载 51 / 9865
8.0
热点
AI SCORE
编程提效2026-09-29 21:01

机器记忆Agent实践:发现自己在用Recall而非Reflect

dev.to · AI#Agent#记忆系统#故障排查
Editor brief · 编辑速览

作者构建工业机器记忆agent时,误将Recall当Reflect使用,导致LLM承担了本不该承担的推理工作,揭示了memory系统设计细节。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

我的 README 说这个 Agent 使用了 Hindsight 的 Reflect 操作来对机器的故障历史进行推理。我的代码调用的是 Recall,把结果塞进 prompt,然后让 LLM 自己做推理。没有人发现这个问题,直到我去找一个完全不相干的 bug。

这个东西实际在做什么

想法很简单,而且我觉得用得还不够多:每台工业机器都应该有自己的记忆。一个技师今天修了一台泵;六个月后,另一个技师在同一台泵上看到相同的振动模式,却完全不知道以前也发生过。维修报告在某个文件夹里,或者在第一个技师的脑子里,两者在凌晨 2 点生产线停机时都无从查找。

所以我构建了一个小系统——一份合成维护记录的 JSON 文件、一个 Flask UI,以及一个做记忆工作的 Hindsight——让技师描述他们看到的情况,然后返回一个基于上次实际情况的答案,包括那些没有起作用的修复方案。不是"这是一份通用故障排除指南",而是"R. Bhatt 曾在 2 月尝试给这个轴承重新加脂,没用,以下才是真正有效的方案"。

架构刻意保持精简:

Technician input (symptoms / sensor readings)
              │
              ▼
        demo_agent.py
              │
      ┌───────┴───────┐
      │               │
   RECALL          REFLECT
      │               │
      └───────┬───────┘
              ▼
        Hindsight Memory
              │
              ▼
         Groq LLM

两种模式,两种不同的工作:并排的"有记忆 vs 无记忆"对比用 Recall——抓取相关片段,交给 LLM,让它推理。维修前检查用 Reflect,它应该自己做推理,直接以记忆为基础。这两者的区别就是这篇文章要讲的核心故事。

我发现我的"Reflect"其实并没有在反思的那一刻

我在把这个东西当成完成品之前做了一次诚实的自我审查,问了自己一个简单的问题:代码里到底有没有调用过 reflect()?我用 grep 搜了。没有。

这就是 check_before_repair 长这样:

def check_before_repair(symptoms, lang="English"):
    ...
    texts, err = recall(symptoms, machine)
    ...
    a = llm("You are the Chief Reliability Engineer for a plant. " + SCHEMA, user, json_mode=True)

Recall,然后一个通用的聊天补全在做实际的判断。演示起来效果很好。但这也完全不是我对任何人说的那样。差异比听起来重要得多:Recall 的工作是检索——返回相关片段,然后退出。Reflect 的工作是综合——判断这是否匹配一个已知的故障模式,权衡相互冲突的证据,然后回答真正的判断问题。我用手工做了第二件事,用一个手写的 prompt,而不是让记忆系统来做这件事。

修复方法是直接调用 Hindsight 的 reflect(),并使用结构化输出:

def reflect(query, context=None, tags=None, response_schema=None, budget="mid"):
    r, e = call_with_retry(lambda: hs().reflect(
        bank_id=BANK_ID, query=query, context=context, tags=tags,
        tags_match="any", budget=budget, max_tokens=1600,
        response_schema=response_schema, include_facts=True))
    if e: return None, friendly_error(e)
    return r, None

response_schema 给我一个 JSON Schema,Hindsight 返回匹配它的 structured_output——不再需要让 LLM "请只返回有效 JSON"然后祈祷。include_facts=True 是真正改变架构的部分:它返回一个 based_on 字段,列出 Hindsight 用来生成答案的确切记忆、心理模型和指令。我 UI 中的"为什么 Agent 认为这个"面板现在渲染的就是这个——不是一张我召回并希望模型使用的列表,而是一张模型自己报告它实际使用了什么的列表。

折腾了我半个下午的坑:ID 活在 context 里,不是文本里

Reflect 接好之后,我的引用检查代码坏了。我曾经建了一个守卫,只允许模型引用一个记录 ID——如果那个 ID 出现在检索文本的某处。一开始它拒绝了所有引用。

原因是 Hindsight 的事实提取会把内容改写成原子语句,而我保留文本里嵌入的 [MAINT-2025-001] 风格的标签没能存活于那个改写过程。但我在 retain 时同时传入的 context 字符串——"maintenance record MAINT-2025-001 | machine MCH-017 | tags: ..."——在每条事实上都原封不动地返回了:

id_blob = texts + [f.context for f in facts if f.context]
conf = confidence(symptoms, id_blob)
srcs = sources_from(id_blob)

教训,用一行说清楚:如果你需要某样东西在 Hindsight 的提取过程中原样存活,把它放进 context,别放进你要让它总结的 content 里。

一个只因为 async 才存在的 bug

另一个真正的 bug:一个缓存的 Hindsight 客户端在跨请求复用时,偶尔会抛出 Timeout context manager should be used inside a task——这是典型的 aiohttp session 在一个 asyncio 事件循环里创建却被另一个复用的症状。Flask 的开发服务器每个请求起一个新线程;同步封装每次调用起一个新的事件循环。在两者之间缓存客户端,最终必然撞车。

一旦理解了问题,修复就便宜了:停止缓存,每次调用构建一个新的客户端,对任何看起来像是瞬时错误的东西重试一次:

def hs():
    from hindsight_client import Hindsight
    return Hindsight(base_url=os.environ["HINDSIGHT_BASE_URL"],
                      api_key=os.environ["HINDSIGHT_API_KEY"])

def call_with_retry(fn, attempts=2, delay=1.2):
    for i in range(attempts):
        try:
            return fn(), None
        except Exception as e:
            if i < attempts - 1 and _is_transient(e):
                time.sleep(delay); continue
            return None, e

我之所以发现这个,纯粹是因为我故意测试了并发请求。否则它只会在实际用户面前暴露,而我最不希望它在那里出现。

真正增长的记忆长什么样

让我确信这不只是"带额外步骤的检索"的部分,是那个闭环。记录一个失败的修复方案,同一台机器的下一个诊断就会改变——不是因为我又跑了一遍脚本,而是因为记忆本身增长了:

记录反馈之前:

"将润滑周期从每月一次延长到每季度一次失败了两次,一次是因为手动策略变更,一次是因为 CMMS 软件重置。"

记录"重新给轴承座加脂——没用"之后:

"重新给轴承座加脂已尝试过并导致失败,见日志 LIVE-001。停止所有重新加脂的尝试;直接更换驱动端轴承为 SKF 6309。"

同一台机器,同一个根本问题,一个真正不同的答案——因为几秒钟前一个技师的结果变成了一条记忆。我还给每台机器配了一个"数字孪生"——一个 Hindsight 心理模型,它的 source_query 让它把那台机器的完整历史综合成一份活的档案,加上 trigger={"refresh_after_consolidation": True} 这样它在新的事故进来时会自我更新,而不是我需要手动重新生成的一份总结。我还把几条常驻规则——接触旋转设备前要先上锁牌、不编造技师名字或日期——从我自己的 prompt 文本里移出来,放进了 Hindsight 指令里,这样它们就由记忆系统在每个请求上强制执行,而不是靠我控制的那个字符串里的约定。

如果有人明天要开始做这件事,我会告诉他

Grep 你自己的声明。如果你的文档说你用了某个操作,要验证代码路径真的调用了它。我没有,持续了好几周。

想清楚什么需要原样存活,然后把它放在不会被总结的地方。context 不是 content;要刻意区别对待。

在用户之前测试并发。我发现的最可怕的 bug 只在同时请求时才存在,而我只是通过故意制造同时请求才发现的。

一个系统的记忆应该在你不动代码的情况下变得越来越聪明。如果你的 Agent"学习"的唯一方式是编辑一个种子文件,那它就不是在学习——而是在重新创作。

检索和推理是不同的工作。Recall 用于"什么相关"。Reflect 用于"这意味着什么"。混淆它们是个容易踩的坑,而我第一口就掉进去了。

这一切都不需要更大的模型。它需要的是记忆系统真正在做我告诉所有人的它在做的那个工作。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
每个任务一个git worktree:避免coding agent文件冲突
下一篇
8个真实n8n自动化案例:发票处理与线索富化实战