2

Python 客户端:retain / recall / reflect 与 bank_id

pip install hindsight-client,对同一 bank_id 写入记忆、检索、反思生成;可选 TypeScript 片段;说明 retain_async 与 Operations 轮询。

图文17 分钟Hindsight 官方文档 ↗

课程目录2 / 2

学习位置仅保存在当前浏览器,有效期 180 天。

01 / 图文教材

图文讲义

来源:Hindsight Docs · Quick StartPython ClientOperations。本讲义为中文跟做整理,非原文搬运。

本课目标

在第 1 课 API 已监听 http://localhost:8888 的前提下:

  1. 安装官方 HTTP 客户端 hindsight-client
  2. 理解 bank_id:记忆银行隔离命名空间(同一 Agent / 同一用户建议固定一个 ID)
  3. 按官方示例跑通 retain → recall → reflect
  4. 知道默认同步 retain 与 retain_async=True 时,recall 前可能需要 等异步 operation 完成
  5. (可选)对照官方 TypeScript 客户端同一组操作

步骤 1:安装客户端并连通

pip install hindsight-client
python -c "from hindsight_client import Hindsight; print('ok')"

对照结果:打印 ok。若 ModuleNotFoundError,确认用的是同一套 Python/pip(which python / which pip)。

官方 Quick Start 最小示例:

from hindsight_client import Hindsight

client = Hindsight(base_url="http://localhost:8888")

# Retain: Store information
client.retain(bank_id="my-bank", content="Alice works at Google as a software engineer")

# Recall: Search memories
client.recall(bank_id="my-bank", query="What does Alice do?")

# Reflect: Generate disposition-aware response
client.reflect(bank_id="my-bank", query="Tell me about Alice")

把上面保存为 02_quickstart.py 后运行:

python 02_quickstart.py

对照结果:三次调用都不抛未捕获异常。第一次 retain 会触发 LLM 抽事实与建索引,可能要等数秒到数十秒(取决于模型与网络)。若立刻报连接错误,先回到第 1 课确认 8888 通。

步骤 2:读懂 bank_id

概念含义
bank_id字符串 ID,标识一座「记忆银行」。retain / recall / reflect 必须使用同一个 ID,否则搜不到刚写入的内容。
隔离不同 Agent、不同租户、不同产品线应使用不同 bank_id,避免记忆串库。
创建第一次 retain 到某个 ID 通常即可开始用;也可用 client.create_bank(...) 显式配置 name / mission / disposition(见 Python SDK「Create Bank」)。

建议:本课全程固定 bank_id="my-bank"(或改成你自己的,如 demo-alice),三步不要混用。

可选:创建时带上 mission 与 disposition(只影响 reflect,不影响 recall;官方 Overview 说明):

from hindsight_client import Hindsight

client = Hindsight(base_url="http://localhost:8888")
client.create_bank(
    bank_id="my-bank",
    name="Assistant",
    mission="You're a helpful AI assistant - keep track of user preferences and conversation history.",
    disposition={
        "skepticism": 3,  # 1-5
        "literalism": 3,
        "empathy": 3,
    },
)

若该 bank_id 已存在,重复 create 可能报错——可换新 ID,或跳过本步直接 retain。

步骤 3:Retain — 写入记忆

官方 Python SDK 推荐写法(带打印,便于对照):

from hindsight_client import Hindsight

client = Hindsight(base_url="http://localhost:8888")

client.retain(
    bank_id="my-bank",
    content="Alice works at Google as a software engineer",
)
print("retained")

带更多选项(摘自 Python Client):

from datetime import datetime
from hindsight_client import Hindsight

client = Hindsight(base_url="http://localhost:8888")

client.retain(
    bank_id="my-bank",
    content="Alice got promoted",
    context="career update",
    timestamp=datetime(2024, 1, 15),
    document_id="conversation_001",
    metadata={"source": "slack"},
    retain_async=False,  # True = 后台处理,见步骤 6
)

官方「What's Happening」表对 Retain 的说明:内容会被处理,抽取事实、识别实体,并链入知识图谱

批量:

client.retain_batch(
    bank_id="my-bank",
    items=[
        {"content": "Alice works at Google", "context": "career"},
        {"content": "Bob is a data scientist", "context": "career"},
    ],
    document_id="conversation_001",
    retain_async=False,
)

步骤 4:Recall — 检索记忆

from hindsight_client import Hindsight

client = Hindsight(base_url="http://localhost:8888")

results = client.recall(bank_id="my-bank", query="What does Alice do?")
for r in results.results:
    print(r.text, getattr(r, "type", None))

对照结果:至少应看到与 Alice / Google / software engineer 相关的文本片段。若 results.results 为空:

  1. 确认 bank_id 与 retain 时完全一致
  2. 若刚才用了 retain_async=True,先完成步骤 6 的轮询再 recall
  3. 同步 retain 刚结束时,偶尔需再等几秒(后台 consolidation 会继续跑,但不阻塞基础事实入库;以你本机响应为准)

带预算与类型过滤(官方选项):

results = client.recall(
    bank_id="my-bank",
    query="What does Alice do?",
    types=["world", "observation"],
    max_tokens=4096,
    budget="high",  # low | mid | high
)

Hindsight 的 TEMPR 检索会并行跑四路:Semantic / Keyword(BM25) / Graph / Temporal(见 Overview),因此「Alice 去年春天做了什么」这类时序问句比纯向量库更合适。

步骤 5:Reflect — 基于记忆生成回答

from hindsight_client import Hindsight

client = Hindsight(base_url="http://localhost:8888")

answer = client.reflect(bank_id="my-bank", query="Tell me about Alice")
print(answer.text)

对照结果:打印一段自然语言回答,内容应引用银行里关于 Alice 的事实。reflect 会结合 mission / directives / disposition(若已配置)生成 disposition-aware 回答;官方说明这些配置只影响 reflect,不影响 recall

带上下文与预算:

answer = client.reflect(
    bank_id="my-bank",
    query="What should I know about Alice?",
    budget="low",
    context="preparing for a meeting",
)
print(answer.text)

三步对照表(官方 Quick Start「What's Happening」):

操作做什么
Retain处理内容,抽事实,识别实体并链入知识图谱
Recall四路检索并行,找相关记忆
Reflect用检索到的记忆生成带 disposition 的回答

步骤 6:异步 retain 与 Operations 轮询

默认示例里 retain_async=False(或未设)时,HTTP 调用会等到处理完成再返回,随后可直接 recall。

当你传入 retain_async=True(或大批量 retain_batch 走异步)时,官方 Operations 说明:请求会立刻返回 operation_id,worker 在后台跑。在 operation 未 completed 前就 recall,可能搜不到刚提交的内容。

官方异步示例(async 客户端):

import asyncio
from hindsight_client import Hindsight

async def main():
    client = Hindsight(base_url="http://localhost:8888")
    submission = await client.aretain_batch(
        bank_id="my-bank",
        items=[
            {"content": "Alice joined Google in 2023"},
            {"content": "Bob prefers Python over JavaScript"},
        ],
        retain_async=True,
    )
    op_id = submission.operation_id
    while True:
        s = await client.operations.get_operation_status("my-bank", op_id)
        if s.status in ("completed", "failed", "cancelled"):
            print("finished:", s.status)
            break
        await asyncio.sleep(2)

    results = await client.arecall(bank_id="my-bank", query="What does Alice do?")
    for r in results.results:
        print(r.text)
    client.close()

asyncio.run(main())

对照结果:轮询打印 finished: completed 后再 recall,应能命中新写入内容。若 failed,用 error_message 排查 LLM Key / 配额,必要时 retry_operation

步骤 7(可选):同一流程的 TypeScript

官方 Quick Start:

npm install @vectorize-io/hindsight-client
import { HindsightClient } from '@vectorize-io/hindsight-client';

const client = new HindsightClient({ baseUrl: 'http://localhost:8888' });

await client.retain('my-bank', 'Alice works at Google as a software engineer');
await client.recall('my-bank', 'What does Alice do?');
await client.reflect('my-bank', 'Tell me about Alice');

参数顺序是 (bankId, content/query),与 Python 的关键字参数写法不同,但语义一致。

步骤 8:自检与收尾

检查项期望
pip show hindsight-client已安装
同一 bank_idretain / recall / reflect 三处一致
recall 有结果results.results 非空,文本与 Alice 相关
reflect 有正文answer.text 非空
异步路径先等到 operation completed 再 recall

实战建议:

  1. 开发时先用同步 retain(retain_async=False),链路跑通再开异步提吞吐。
  2. 为每个 Agent 固定 bank_id,并在配置中心集中管理,避免硬编码散落。
  3. 需要人格 / 合规时,用 create_bank 的 mission、directives、disposition,再依赖 reflect
  4. 深入主题继续读官方:RetainRecallReflectMemory Banks

到这里,你已经按官方路径完成本地服务启动与 retain / recall / reflect 主路径,可以把 Hindsight 接到自己的 Agent 循环里作为长期记忆层。