> ## Documentation Index
> Fetch the complete documentation index at: https://ahvn.top/llms.txt
> Use this file to discover all available pages before exploring further.

# 30 分钟用户工作坊：记忆 Agent

> 将 Agent 接入你的数据 — manifest 工作区、profile、MCP 与记忆层，零胶水代码。

<Note>
  本工作坊是 `demos/user/` 入门轨道的文档转录。每一步对应 HeavenBase 仓库中的可运行脚本。
</Note>

你将从 manifest 打开工作区 (Workspace)，用三种方式查询数据，配置声明式 MCP profile，并将 `memory` / `memstate` profile 用作持久化笔记层。无需 API 密钥。

<br />

## 1. 前置条件

安装 HeavenBase，并从源码检出目录同步环境：

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
git clone https://github.com/Magolor/HeavenBase.git
cd HeavenBase
rtk bash scripts/sync-env.bash
```

所有演示产物仅写入 `demos/.temp/`。

<br />

## 2. 从 Manifest 打开工作区

**脚本：** `demos/user/01_workspace_from_manifest.py`

编写 `workspace.yaml`，用 `WorkspaceManifest` 打开，并对首个实体 (Entity) 执行 CRUD：

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb
from heavenbase.utils.files import pj, touch_dir

TEMP = touch_dir(pj("demos/.temp/user-01", abs=True))

manifest = hb.WorkspaceManifest(
    id="user-01-manifest",
    config={"backends": {"main": {"type": "inmem"}}},
    entities=[
        {
            "entity_id": "product",
            "name": "Product",
            "fields": {
                "object_id": {"type": "identifier", "pk": True},
                "name": {"type": "short-text"},
                "price": {"type": "float"},
                "body": {"type": "long-text"},
            },
        }
    ],
)
manifest.save(pj(TEMP, "workspace.yaml", abs=True))

ws = hb.HeavenBase.from_manifest(hb.WorkspaceManifest.load(pj(TEMP, "workspace.yaml", abs=True)))
desk_id = ws.upsert("product", {"object_id": "p-desk", "name": "Oak Desk", "price": 95.0, "body": "compact oak desk"})
ws.set(desk_id, {"price": 89.0}, entity="product")

frame = ws.query("product").where({"price": {"$lte": 100}}).select("name", "price").execute()
print(frame.to_str())
```

运行：

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
rtk uv run python demos/user/01_workspace_from_manifest.py
```

<br />

## 3. 三种查询方式

**脚本：** `demos/user/02_query_three_ways.py`

用 Python DSL、Mongo 风格 `where({...})` 与 `query_json` 提出同一产品问题，再用 `explain()` 检查路由 (Routing)：

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb

ws = hb.HeavenBase("user-02-query", backends={"main": {"type": "inmem"}})
# register Product entity, seed rows ...

py_frame = (
    ws.query("product")
    .where({"price": {"$lte": 130}, "body": {"$match": "audio"}})
    .select("name", "price")
    .limit(2)
    .execute()
)

json_frame = ws.query_json(
    "product",
    {
        "filter": {"price": {"$lte": 130}, "body": {"$match": "audio"}},
        "select": ["name", "price"],
        "limit": 2,
    },
).execute()

explain = ws.query("product").where({"body": {"$match": "audio"}}).explain()
print(explain)
```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
rtk uv run python demos/user/02_query_three_ways.py
```

<br />

## 4. Profile 与 MCP

**脚本：** `demos/user/03_profiles_and_mcp.py`

启用 `agent` 与 `memory`，注册配置 `ProfileSpec`，打印 MCP serve JSON，并在进程内模拟 Agent 工具调用：

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb
import heavenbase.ext as ext
from heavenbase.extensions.system.toolkit.profiles import profile_spec_from_mapping, register_profile

register_profile(
    profile_spec_from_mapping(
        "user-demo",
        {
            "extends": ["agent"],
            "entities": ["agent-product"],
            "skills": ["*"],
            "serializer": "markdown",
        },
    ),
    replace=True,
)

ws = hb.HeavenBase("user-03-profiles", backends={"main": {"type": "inmem"}})
ws.enable_extension("agent")
ws.enable_extension("memory")
ws.register({...})  # agent-product entity
ws.upsert("agent-product", {"object_id": "p1", "name": "Desk", "price": 80})

print(ws.to_mcp_json(name="user-03-heavenbase", profile="user-demo", host="127.0.0.1", port=7011))

toolkit = ws.to_mcp(profile="user-demo")
print(toolkit.run_to_str("query", entity="agent-product", spec={"select": ["name", "price"]}))
print(toolkit.run("read_skill", skill_name="workspace-guide")["text"].splitlines()[0])

memory = ws.to_mcp(profile="memory")
memory.run("remember", key="onboarding", text="Profiles v2 scope entities, skills, and serializers.")
```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
rtk uv run python demos/user/03_profiles_and_mcp.py
```

<br />

## 5. Memory 与 Memstate 层

**脚本：** `demos/user/04_memory_layer.py`

用 `profile="memory"` 管理扁平笔记，用 `profile="memstate"` 管理带版本的项目 keypath：

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb

ws = hb.HeavenBase("user-04-memory", preset="debug")
memory = ws.to_mcp(profile="memory")
memstate = ws.to_mcp(profile="memstate")

memory.run("remember", key="setup", text="Use uv sync; demos write only to demos/.temp/.", tags=["setup"])
memory.run("search_memory", text="uv sync")

memstate.run("memstate_set", project_id="demo", keypath="prefs.theme", value="dark")
memstate.run("memstate_remember", project_id="demo", keypath="docs/readme", content="v2 notes")
memstate.run("memstate_history", project_id="demo", keypath="docs/readme")
memstate.run("memstate_delete", project_id="demo", keypath="docs/readme")
```

两个 profile 在首次使用时都会自动启用可选的 `memory` 扩展。

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
rtk uv run python demos/user/04_memory_layer.py
```

<br />

## Summary

* 你从 manifest 打开了工作区，用三种方式查询数据，并用 `explain()` 检查了路由。
* 声明式 `ProfileSpec` 对象为 MCP Agent 限定实体、Skill 与 serializer 范围。
* `memory` 与 `memstate` profile 将 Agent 笔记存储为普通 HeavenBase 行。

<br />

## 进一步探索

<Tip>
  **相关资源：**

  * [工作区 manifest](/features/workspace-manifest) — 重放构造配置与扩展
  * [首个 MCP](/zh/quickstart/first-mcp) — 提供工作区与 Capsule 工具集
  * [Agent 扩展](/features/agent-extension) — 持久化会话、Skill 与 recipe
  * [User 演示轨道](https://github.com/Magolor/HeavenBase/tree/master/demos/user) — 完整可运行脚本
</Tip>

<br />
