news 2026/9/15 8:17:39

Hindsight 三大核心方法实战指南:Retain、Recall 与 Reflect 的完整使用与源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hindsight 三大核心方法实战指南:Retain、Recall 与 Reflect 的完整使用与源码解析

Hindsight 三大核心方法实战指南:Retain、Recall 与 Reflect 的完整使用与源码解析

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

Hindsight 是一个为 AI Agent 设计的"会学习的记忆系统",其全部能力浓缩在三个核心操作中:retain(存储信息)、recall(检索记忆)、reflect(基于记忆推理回答)。本文以 Hindsight 官方开发者文档的主方法(Main Methods)章节为骨架,结合仓库中 Python/Node.js 客户端与 Rust CLI 的真实实现,完整讲解这三个方法的调用方式、全部参数、返回结构与底层工作原理,帮助你掌握如何用 Hindsight 为 Agent 构建持久化、可检索、可推理的记忆层。

前置条件:本文示例假定你已完成 Hindsight 的安装并跑通了 Quick Start,本地 API 服务与客户端均已就绪。

三大方法概览:从存储到推理的完整闭环

Hindsight 的记忆模型是一个"存储 → 检索 → 推理"的三段式流水线:

阶段你要做的事输入输出是否调用 LLM
Retain存储信息原始文本/文档/对话记忆 ID(Memory IDs)是(事实抽取)
Recall查找信息自然语言查询排序后的事实 + 观察(ranked facts + observations)
Reflect推理信息问题/提示词基于证据的推理回答是(生成)

三者中,Retain 使用 LLM 做事实抽取,Recall 纯检索不使用 LLM,Reflect 使用 LLM 做生成;Recall 与 Reflect 都会消费"观察(observations)",而只有 Reflect 会应用记忆库的"倾向(disposition)"来塑造推理风格。

在仓库的 Python 客户端中,这三个方法定义于 hindsight_client.py,是Hindsight客户端类上的同步方法(另有aretain/arecall/areflect异步版本);而 client_wrapper.py 中的HindsightClient在此基础上扩展出banksmental_modelsdirectivesmemories等命名空间,核心的三个 retain/recall/reflect 则直接继承自基类。

Retain:把信息存入记忆库

Retain 接收对话、文档、事实等原始内容,将其写入一个记忆库(memory bank)。关键认知是:Hindsight 并不会原样存储原始文本,而是通过 LLM 从中抽取结构化事实、识别实体(entities),并在知识图谱中建立连接——非结构化信息由此转化为可查询的结构化记忆。这一点在 retain.md 中有明确说明,也与客户端实现中retain最终将单个 item 包装为 batch 提交给retain_memories接口的行为一致。

Python 用法

# 存储单条事实 client.retain( bank_id="my-bank", content="Alice joined Google in March 2024 as a Senior ML Engineer" ) # 存储一段对话 conversation = """ User: What did you work on today? Assistant: I reviewed the new ML pipeline architecture. User: How did it look? Assistant: Promising, but needs better error handling. """ client.retain( bank_id="my-bank", content=conversation, context="Daily standup conversation" ) # 批量存储多个条目 client.retain_batch( bank_id="my-bank", items=[ {"content": "Bob prefers Python for data science"}, {"content": "Alice recommends using pytest for testing"}, {"content": "The team uses GitHub for code reviews"} ] )

Node.js 用法

// 存储单条事实 await client.retain('my-bank', 'Alice joined Google in March 2024 as a Senior ML Engineer'); // 存储一段对话 const conversation = ` User: What did you work on today? Assistant: I reviewed the new ML pipeline architecture. User: How did it look? Assistant: Promising, but needs better error handling. `; await client.retain('my-bank', conversation, { context: 'Daily standup conversation' }); // 批量存储多个条目 await client.retainBatch('my-bank', [ { content: 'Bob prefers Python for data science' }, { content: 'Alice recommends using pytest for testing' }, { content: 'The team uses GitHub for code reviews' } ]);

CLI 用法

# 存储单条事实 hindsight memory retain my-bank "Alice joined Google in March 2024 as a Senior ML Engineer" # 从文件存储 hindsight memory retain-files my-bank conversation.txt --context "Daily standup" # 存储多个文件(目录) hindsight memory retain-files my-bank docs/

Go 客户端

仓库提供了 Go 客户端(位于 hindsight-clients/go),但官方 API 文档中 Go 的 retain 示例区块当前是占位状态(源码片段尚未生成),因此这里不给出具体 Go 代码;其余操作同理。

retain 的核心参数(源码级解读)

对照 hindsight_client.py 中retain()的签名,Python 客户端支持以下参数:

参数类型说明
bank_idstr目标记忆库 ID(必填)
contentstr 或list[ContentBlock]记忆内容。既可以是普通字符串,也可以是有序的 content block 列表,使图片内联在它实际出现的位置(需要服务端具备视觉能力的 retain LLM)
timestampdatetime事件发生时间;缺省时服务端取当前时间
contextstr来源场景标签,如"team meeting""slack"
document_idstr逻辑文档 ID,用于分组与幂等 upsert
metadatadict[str, str]任意键值对元数据,随记忆返回
entitieslist[dict]希望保证被识别的实体列表,如[{"text": "...", "type": "..."}]
resolve_entitiesbool提供的实体是否与库内已有实体做解析合并(默认 True);False 表示按原文精确存储
tagslist[str]可见性作用域标签,用于 recall/reflect 时过滤
update_modestr"replace"(默认,整体替换旧文档)或"append"(增量拼接后重新处理)
retain_asyncboolTrue 时后台异步处理
operation_idstr调用方提供的 UUID,用于异步重试幂等

几个值得深挖的行为细节:

  • timestamp 的三种形态:省略/null时使用入库时刻;传 ISO 8601 字符串则采用该时刻;传"unset"则完全不记录时间戳,适合参考文档、书籍等"永恒材料"。时间戳会被注入 LLM 事实抽取提示词,让模型能以它为锚点解析"上周一"这类相对时间表达,也是"What happened last spring?"这类时间召回查询能够工作的前提。
  • context 是高杠杆输入:它被直接注入 LLM 提示词,同一句话在不同 context 下抽取出的记忆可能截然不同——例如"the project was terminated""performance review""product roadmap"两种 context 下会产生不同的记忆。
  • document_id 是幂等性的关键:提供document_id时执行 upsert——若库中已存在同 ID 文档,会先删除旧文档及其全部记忆再重新处理;省略时每次请求分配随机 UUID,重复摄入会产生重复记忆。
  • update_mode 的选择"append"适合日志、日记、聊天记录这类增量增长的内容——只需发送新增部分,Hindsight 会跳过未变化的 chunk,仅对新内容触发 LLM 抽取。注意 append 模式必须提供document_id
  • metadata 的存储规则:值一律按字符串存储并随召回返回;值为null的键会被丢弃而非存储,若需要键存活请传空字符串。
  • operation_id 保障重试安全:异步 retain 响应丢失或超时后盲目重试可能造成重复抽取与重复计费。自行提供operation_id(任意 UUID)后,相同 ID 的重提会返回原操作而不产生新工作;复用已属于其他操作的 ID 会返回 HTTP 409。
  • 成本优化:异步 retain 搭配 provider 批量 API(HINDSIGHT_API_RETAIN_BATCH_ENABLED=true,支持 OpenAI、Groq、Gemini)可将事实抽取的 LLM 成本降低约 50%,代价是最高 24 小时的批处理窗口——对本就后台运行的 retain 通常无感知。该优惠要求请求中async=true

retain 的响应结构

同步 retain 的响应包含:success(是否无错完成)、bank_id(接收内容的记忆库)、items_count(处理条目数)、async(是否异步执行)、usage(LLM 调用的 token 用量:input_tokens/output_tokens/total_tokens,仅同步操作返回)。异步 retain(含文件上传)则返回operation_ids,可通过 operations 端点轮询进度。

深入:文件摄入与批量摄入

  • 文件上传retain_files支持 PDF、DOCX、PPTX、XLSX、图片(OCR,取决于配置的解析器)、音频(转录)及 TXT/MD/CSV/JSON/YAML 等文本格式。单次最多 10 个文件、总量不超过 100 MB;每个文件成为独立文档,支持逐文件指定contextdocument_idtagsfiles_metadata)。文件处理始终异步,响应中的operation_ids与文件一一对应。上传的文件默认存储在 PostgreSQL,生产环境可切换 S3/GCS/Azure(HINDSIGHT_API_FILE_STORAGE_TYPE)。
  • 异步批量:大批量场景使用retain_async=True(Node 中async: true),调用立即返回,处理由 worker 服务后台执行;异步操作不返回usage指标。
  • 批量提交:CLI 逐个执行 retain 调用实现批量;而 Python/Node 的retain_batch是真正的单请求多条目提交,可减少网络开销并让 Hindsight 在相关内容间优化抽取。

Recall:用多策略检索搜索记忆

Recall 接收自然语言查询,返回排序后的事实与观察。其底层执行四种检索策略的并行融合:语义相似度(semantic embedding)、关键词 BM25(keyword)、知识图谱遍历(graph traversal)、时间(temporal)——四路结果经RRF(Reciprocal Rank Fusion)融合,再由 cross-encoder 重排序器(reranker)按原始查询对候选重新打分,最终输出单一排序列表。注意响应包含的是结构化事实而非原始文档

Python 用法

# 基础检索 results = client.recall( bank_id="my-bank", query="What does Alice do at Google?" ) for result in results.results: print(f"- {result.text}") # 带选项检索 results = client.recall( bank_id="my-bank", query="What happened last spring?", budget="high", # 更彻底的图遍历 max_tokens=8192, # 返回更多上下文 types=["world"] # 只检索世界事实 ) # 附带来源 chunk 以获取更多上下文 results = client.recall( bank_id="my-bank", query="Tell me about Alice", include_chunks=True, max_chunk_tokens=500 ) # 查看 chunk 细节(chunks 挂在响应层级,按记忆 ID 索引) for result in results.results: print(f"Memory: {result.text}") if results.chunks and result.id in results.chunks: chunk = results.chunks[result.id] print(f" Source: {chunk.text[:100]}...")

Node.js 用法

// 基础检索 const results = await client.recall('my-bank', 'What does Alice do at Google?'); for (const result of results.results) { console.log(`- ${result.text}`); } // 带选项检索 const filteredResults = await client.recall('my-bank', 'What happened last spring?', { budget: 'high', maxTokens: 8192, types: ['world'] }); // 附带实体信息 const entityResults = await client.recall('my-bank', 'Tell me about Alice', { includeEntities: true, maxEntityTokens: 500 }); // 查看实体详情 for (const [entityId, entity] of Object.entries(entityResults.entities || {})) { console.log(`Entity: ${entity.canonical_name}`); console.log(`Observations: ${entity.observations}`); }

CLI 用法

# 基础检索 hindsight memory recall my-bank "What does Alice do at Google?" # 带选项检索 hindsight memory recall my-bank "What happened last spring?" \ --budget high \ --max-tokens 8192 \ --fact-type world,experience # 详细输出 hindsight memory recall my-bank "Tell me about Alice" -v

recall 的完整参数清单

对照 hindsight_client.py 的recall()签名,主要参数如下:

参数默认值说明
query自然语言查询(唯一必填)。同时驱动语义嵌入、BM25 分词、图遍历种子与时间表达解析;原始查询文本还会传给 cross-encoder 重排序器。超过 500 token 的查询会被拒绝
types全部事实类别过滤:world(客观事实)、experience(事件与对话)、observation(由多条记忆合并出的、有证据支撑的信念)。每种类型独立跑完整的四策略管线,收窄types可同时降低结果集与查询成本
budget"mid"检索深度与广度:low适合快速简单查找,mid适合日常均衡查询,high适合寻找间接关联或穷尽覆盖
max_tokens4096返回事实可占用的最大 token 数。只统计每条事实的text字段;重排后按相关度顺序填充直至预算耗尽,超出剩余预算的长事实会被跳过(而非截断),以保证更相关的短记忆也能返回。设计哲学是"给 Agent 按 token 思考,而非按条数思考"
query_timestamp服务器当前时间查询发生时刻(ISO 8601),作为解析查询中相对时间表达与近因性打分的锚点。对回放历史对话、构建时间锚定检索的 Agent 至关重要
temporal_windownull显式{start, end}时间窗,直接用于时间检索分支。只排名、不过滤:窗口内的记忆被提升,窗口外的仍正常返回;比较的是记忆自身的事件时间而非入库时间。边界包含,无时区按 UTC 处理
include_chunksFalse附带每条事实来源的原始文本 chunk。chunk 在max_tokens过滤前获取,因此max_tokens=0时可以"只拿 chunk 不要事实";chunk 有独立预算(默认8192),最后一个 chunk 会被截断而非丢弃并带truncated标记
include_entities服务端默认开启附带实体规范名;设null可跳过实体 JOIN 查询减小响应体积
include_source_factsFalsetypesobservation时,为每条观察附带其来源事实(顶层source_facts字典按事实 ID 索引)。预算(默认4096)按结果顺序消耗,耗尽时是低排名结果失去来源事实
prefer_observationsFalse同时召回observation与原始事实时,若某观察由某条原始事实合并而来,则丢弃该原始事实让观察取而代之(释放的槽位由次优结果回填)。适合"全都要但不想看到重复内容"的场景
tags/tags_matchnull /"any"标签作用域过滤(见下文表格)
tag_groupsnull复合布尔标签过滤(见下文)
traceFalse附带详细调试轨迹:查询嵌入、入口点、各策略检索结果、RRF 融合候选、重排结果、检测到的时间约束与各阶段耗时。不影响检索逻辑
min_scoresnull各阶段分数下限(semantic/keyword在检索阶段按各自分支的 SQL 内剪枝;reranker/final在重排后作用于每个结果)

tags 与 tags_match:作用域过滤的六种组合

tags默认nulltags_match默认anytags_match的取值决定过滤逻辑:

模式未打标签记忆匹配条件
any(默认)包含命中至少一个指定标签
any_strict排除命中至少一个指定标签
all包含命中全部指定标签
all_strict排除命中全部指定标签
exact排除标签集合完全等于指定集合

空过滤行为值得注意:tags省略/null/[]tags_matchexact时,等同于无过滤(全部记忆可召回);仅当tags_match="exact"且无标签时,才表示"只召回未打标签的全局记忆"——这是读取observation_scopes: "shared"合并出的全局观察的标准方式。

tag_groups:复合布尔过滤

tag_groups是递归布尔表达式的列表,列表内各分组顶层 AND,每个分组可以是叶子节点{tags, match}或复合节点{and: [...]}{or: [...]}{not: ...}。叶子节点的matchtags_match取值一致,默认any_strict。它还支持resolve: "fuzzy"做三元组相似度模糊匹配(如过滤typsecript仍能命中标签typescript,相似度阈值 0.45;库内标签超过 5000 个或模糊展开超过 32 个候选作用域时返回 422)。REST/MCP 请求模型中tag_groupstags互斥,同时提供会被拒绝。

recall 响应详解

results是按相关度排序的事实列表,每个结果包含:

  • id:事实唯一 ID,可用于与source_facts交叉引用或应用层去重
  • text:记忆库中存储的抽取事实文本
  • typeworld/experience/observation之一
  • context:retain 时设置的场景标签(未设置则为 null)
  • metadata:retain 时附加的键值对(未设置则为 null)
  • tags:该事实的可见性作用域标签
  • entities:关联实体的规范名列表(默认开启)
  • occurred_start/occurred_end:事件起止时间(LLM 抽取),无时间信息则为 null
  • mentioned_at:事实入库时间
  • document_id/chunk_id:所属文档与来源 chunk
  • source_fact_ids:observation 类型结果的来源事实 ID 列表
  • scores:各阶段分数——final(最终排名分数,results按它降序)、reranker(cross-encoder 归一化相关度 0-1,passthrough 重排模式下为 null)、semantic(向量余弦相似度 0-1,非语义分支召回则为 null)、keyword(BM25 分数 ≥0 无上界,非关键词分支召回则为 null)

关键提醒scores相对信号,反映单次查询内的排序,而非跨查询可比的绝对置信度——一次查询的0.8与另一次查询的0.8不可比。对多数 Agent,正确做法是按序消费记忆,让max_tokens决定装多少条,而不是按分数过滤。

响应中还可能包含:source_facts(observation 来源事实字典)、source_facts_truncated(预算截断标记)、chunks(chunk 字典,每项含id/text/chunk_index/truncated)、entities(实体状态字典,含entity_id/canonical_name/observations)、trace(仅trace: true时返回)。

Reflect:基于记忆的倾向感知推理

Reflect 运行一个代理式循环(agentic loop):Agent 自主使用多个检索工具搜索记忆库,应用记忆库的 disposition 特质塑造推理风格,最后产出一份扎根于检索结果的综合回答。与 recall 返回原始事实不同,reflect 返回的是 LLM 撰写的综合回答。

What happens:记忆与观察被召回,记忆库倾向(disposition)被应用,LLM 依据证据链推理生成回答。

Python 用法

# 基础 reflect response = client.reflect( bank_id="my-bank", query="Should we adopt TypeScript for our backend?", include_facts=True, ) print(response.text) print("\nBased on:", len(response.based_on.memories if response.based_on else []), "facts") # 带选项 reflect response = client.reflect( bank_id="my-bank", query="What are Alice's strengths for the team lead role?", budget="high", # 更彻底的推理 include_facts=True, ) # 查看影响回答的事实 for fact in (response.based_on.memories if response.based_on else []): print(f"- {fact.text}")

Node.js 用法

// 基础 reflect const response = await client.reflect('my-bank', 'Should we adopt TypeScript for our backend?'); console.log(response.text); console.log('\nBased on:', (response.based_on || []).length, 'facts'); // 带选项 reflect const detailedResponse = await client.reflect('my-bank', "What are Alice's strengths for the team lead role?", { budget: 'high' }); // 查看影响回答的事实 for (const fact of detailedResponse.based_on || []) { console.log(`- ${fact.text}`); }

CLI 用法

# 基础 reflect hindsight memory reflect my-bank "Should we adopt TypeScript for our backend?" # 更高推理预算 hindsight memory reflect my-bank "Analyze our tech stack" --budget high

reflect 参数详解

对照 hindsight_client.py 的reflect()签名:

参数默认值说明
query要反思的问题或提示(唯一必填)。如有影响答案的情境上下文,直接并入 query 而非独立字段
budget"low"控制回答前探索记忆库的彻底程度。low浅层快速搜索;mid在问题需要时检查多个来源;high跨所有知识层深度探索,可能用多种查询变体寻找间接关联
contextnull附加情境上下文(Node 示例中体现为 options.context)
max_tokens服务端默认4096限制最终生成回答的长度,不影响代理循环期间的检索量
response_schemanull可选 JSON Schema(对象、非空properties,支持嵌套)。提供后响应会额外包含structured_output字段——Agent 先推理出答案,再做一次抽取把答案按 schema 提取为 JSON。structured_outputtext的忠实投影,两者并存互不替代
tags/tags_matchnull /"any"作用于 Agent 可检索的原始事实、观察、mental models 的可见性作用域;同样的tags/tags_match还决定注入 reflect 提示词的 tagged directives
tag_groupsnull复合标签过滤,作用于与tags相同的数据源与指令选择;与tags互斥
include_factsFalse响应附带based_on对象,列出 Agent 实际用于构造回答的记忆、mental models 与 directives。只有代理循环中真实检索到的来源才能出现——引用经过校验,防止幻觉式引用
include_tool_callsFalse响应附带trace对象,记录代理循环中每次工具调用与 LLM 调用的完整执行日志(输入、输出、耗时)。设output: false可只保留工具输入以减小载荷
apply_all_directivesFalse忽略标签作用域,应用全部活动 directives(默认与记忆一样按标签作用域)
fact_typesnull限定参与推理的事实类型(world/experience/observation)
exclude_mental_models/exclude_mental_model_idsFalse / null排除全部或指定 mental models

response_schema:结构化输出示例

Python 端可用 Pydantic 定义结构:

from pydantic import BaseModel # 用 Pydantic 定义响应结构 class HiringRecommendation(BaseModel): recommendation: str confidence: str # "low", "medium", "high" key_factors: list[str] risks: list[str] = [] response = client.reflect( bank_id="hiring-team", query="Should we hire Alice for the ML team lead position?", response_schema=HiringRecommendation.model_json_schema(), ) # 将结构化输出解析回 Pydantic 模型 result = HiringRecommendation.model_validate(response.structured_output) print(f"Recommendation: {result.recommendation}") print(f"Confidence: {result.confidence}") print(f"Key factors: {result.key_factors}")

Node.js 端直接传 JSON Schema:

// 直接定义 JSON schema const responseSchema = { type: 'object', properties: { recommendation: { type: 'string' }, confidence: { type: 'string', enum: ['low', 'medium', 'high'] }, key_factors: { type: 'array', items: { type: 'string' } }, risks: { type: 'array', items: { type: 'string' } }, }, required: ['recommendation', 'confidence', 'key_factors'], }; const structuredResponse = await client.reflect('my-bank', 'What do you know about Alice and her career?', { responseSchema: responseSchema, }); // 结构化输出(若返回) if (structuredResponse.structuredOutput) { console.log('Recommendation:', structuredResponse.structuredOutput.recommendation || 'N/A'); console.log('Key factors:', structuredResponse.structuredOutput.key_factors || []); }

CLI 端使用--schema传入 JSON schema 文件:

# 先创建 JSON schema 文件 schema.json: cat > schema.json << 'EOF' { "type": "object", "properties": { "recommendation": {"type": "string"}, "confidence": {"type": "string", "enum": ["low", "medium", "high"]}, "key_factors": {"type": "array", "items": {"type": "string"}} }, "required": ["recommendation", "confidence", "key_factors"] } EOF # 然后使用 --schema 标志: hindsight memory reflect hiring-team \ "Should we hire Alice for the ML team lead position?" \ --schema schema.json # 清理临时 schema 文件 rm -f schema.json

reflect 的标签作用域语义

reflect 的标签过滤比 recall 多一层维度——它同时作用于三类数据源与 directives 选择:

Reflect 配置原始事实与观察Mental models生效的 directives
省略tags/tags_match/tag_groups全部(含未打标签)全部(含未打标签)仅未打标签/全局 directives
tags: [],默认tags_match: "any"全部全部仅全局 directives
无标签,tags_match: "exact"仅全局数据仅全局 models仅全局 directives
非空tagsany/all匹配数据 + 全局数据匹配 models + 全局 models匹配 directives + 全局 directives
非空tagsany_strict/all_strict仅匹配数据仅匹配 models匹配 directives + 全局 directives
非空tagsexact仅精确匹配数据仅精确匹配 models精确匹配 directives + 全局 directives
非空tag_groups匹配复合表达式匹配复合表达式匹配 directives + 全局 directives

注意第一行的刻意不对称:无作用域的 reflect 能搜索全部记忆,但不会加载带标签的 directives。想让某条 directive 作用于所有 reflect 调用,就把它留空标签;想作用域化,就给它打标签并在 reflect 请求中传入匹配的作用域。

reflect 响应结构

  • text:综合回答(格式良好的 Markdown 字符串),是 reflect 的主输出。提供response_schema时仍返回,structured_output由其派生而非替代。
  • structured_output:按response_schema解析出的结构化结果(仅当请求提供 schema 时存在,否则 null)。
  • structured_output_error:结构化视图无法产出的原因(provider 错误、超时、输出无法解析)。此时 reflect 本身仍成功(返回 200 与 markdowntext)。该字段的存在代表"可重试",是结构化输出异常时应告警的信号。
  • based_on:构造回答所用的来源(仅include_facts=True)。含三部分:memories(被检索并引用的记忆事实,各含id/text/type/context/occurred_start/occurred_end)、mental_models(使用的 mental models,各含id/text/context)、directives(推理中强制执行的指令,各含id/name/content)。
  • usage:代理循环全部 LLM 调用的 token 用量(input_tokens/output_tokens/total_tokens),用于成本追踪。
  • trace:代理循环完整执行日志(仅include_tool_calls=True)。含tool_calls(每次工具调用的tool名——lookup/recall/learn/expandinputoutput(若output: true)、duration_msiteration)与llm_calls(每次 LLM 调用的scope(如"agent_1""final")与duration_ms)。

Reflect 何时失败:宁可失败也不胡编

Reflect 的回答建立在它收集到的证据之上,因此无法收集证据时它不会回答——直接返回 500,而不是基于空数据给出自信的回答。失败场景包括:

  • 检索工具抛错:数据库、embedder 或 reranker 不可用;批内一次失败即整体失败,因为围绕未返回的工具写出的回答与"记忆库确实没有相关内容"无法区分。
  • 模型未产出回答done调用返回空,或最终综合阶段无输出。
  • 模型/传输层无法驱动工具调用:reflect 完全由结构化工具调用驱动,静默丢弃工具定义的传输层会响亮地失败,促使你切换到支持工具调用的模型。
  • provider 持续失败:非上下文溢出类的 LLM 错误在循环内重试一次后放弃。

成功的检索返回空结果不算失败——记忆库确实没有相关内容时,reflect 会在回答中如实说明。另外两类情况刻意不视为失败:上下文窗口溢出时会基于已有证据综合(这是预算问题而非依赖损坏);模型用错工具(缺参、调用不存在的工具)会被作为错误回传让它自行修正,而不是抛出异常。

三大方法对比总结

FeatureRetainRecallReflect
Purpose(目的)Store information 存储信息Find information 查找信息Reason about information 推理信息
Input(输入)Raw text/documents 原始文本/文档Search query 搜索查询Question/prompt 问题/提示
Output(输出)Memory IDs 记忆 IDRanked facts + observations 排序事实 + 观察Reasoned response 推理回答
Uses LLM(是否用 LLM)Yes (extraction) 是(抽取)No 否Yes (generation) 是(生成)
Uses observations(是否用观察)No 否Yes 是Yes 是
Disposition(是否应用倾向)No 否No 否Yes 是

从源码结构看,这三个方法在客户端实现上是三种截然不同的管线:retain走批处理提交与文件上传通道(retain_batch/file_retain),recall聚合了types/budget/max_tokens/tags/min_scores/temporal_window等十余个检索控制参数,reflect则把response_schema/include_facts/include_tool_calls等代理循环控制参数打包进一次调用。CLI 端(memory.rs)通过hindsight memory retain|recall|reflect三个子命令暴露相同能力,其parse_budgetparse_tags_matchparse_temporal_window等辅助函数与 API 层的枚举定义一一对应。

下一步学习路径

  • Retain— 存储记忆的高级选项(timestamp、update_mode、实体解析、观察作用域、异步摄入与成本优化)
  • Recall— 调优检索质量与性能(标签过滤、分数下限、时间窗、复合过滤)
  • Reflect— 配置倾向(disposition)与结构化输出
  • Memory Banks— 管理记忆库及其倾向

关联的完整 API 文档位于 skills/hindsight-docs/references/developer/api,Python 客户端完整实现见 hindsight_client.py,命名空间封装见 client_wrapper.py。

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 8:16:54

计算机毕业设计之基于Java的商场停车场管理系统的设计与实现

如今&#xff0c;在科学技术飞速发展的情况下&#xff0c;信息化的时代也已因为计算机的出现而来临&#xff0c;信息化也已经影响到了社会上的各个方面。它可以为人们提供许多便利之处&#xff0c;可以大大提高人们的工作效率。随着计算机技术的发展的普及&#xff0c;各个领域…

作者头像 李华
网站建设 2026/9/15 8:15:08

3步避坑指南:专业的购物网站建设保姆级教程与成本真相

3步避坑指南:专业的购物网站建设保姆级教程与成本真相 找建站公司报价从几千到几十万,怕被坑高价是常态。别急着签合同,先看这份保姆级建站教程,用GitHub开源仓库代码验证技术栈,把隐形费用摊开算。 专业的购物网站建设到底贵在哪? 很多老板以为网站就是个展示页,其实购物网站的核心在于 交易闭环 与…

作者头像 李华
网站建设 2026/9/15 8:15:03

06H处理器机器错误码增量解码原理与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 8:13:20

GEO 的胜负藏在标签里

最近勾俊伟老师对比了两家同城市、同赛道的办公装修公司&#xff0c;挺有代表性&#xff1a;两家都做了 GEO 优化&#xff0c;也都稳定出现在本地行业推荐的前 5 位&#xff0c;曝光量差不了多少&#xff0c;但有效咨询量差了快一倍。深挖之后发现&#xff0c;差就差在 AI 描述…

作者头像 李华
网站建设 2026/9/15 8:13:09

DSPro:WordPress一体化资源站与会员运营主题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 8:12:23

专业的购物网站建设完整流程:山东团队避坑指南

专业的购物网站建设完整流程:山东团队避坑指南 备案流程一头雾水,很多老板在拿到服务器IP后直接卡壳,不知道下一步该干嘛。别慌,这正是 专业的购物网站建设…

作者头像 李华