All Products
Search
Document Center

Tablestore:File memory

Last Updated:Sep 24, 2026

File memory enables AI agents to read long-term context as files. Applications can directly manage files, or let the memory store service convert conversation messages into read-only files.

Features

The memory store service provides the following file capabilities.

Capability

Memory store type

File operations

Use cases

Conversation-to-file

inputType=messages, outputTypes includes file

List, read, and search service-generated read-only files

Continue writing through messages while letting the agent read memory as files

Direct file management

inputType=file, outputTypes=["file"]

Create, read, update, rename, delete, and manage versions

Existing Markdown memory, or need to organize directories and versions independently

Dream file organization

inputType=file, outputTypes=["file"]

Read text files across scopes and automatically write to a deterministic output scope

Deduplicate, summarize, correct, merge, or reorganize existing files

On Linux, you can also use agent-memory-fuse to mount file memory as a local directory, allowing agents and applications to access memory through standard file operations.

Prerequisites

  • You have created an AgentStorage instance and obtained the endpoint and instance name.

  • The Agent Storage SDK is installed: Python >= 1.0.10, TypeScript >= 0.0.13

Quick start

The following examples walk through installing the SDK, configuring credentials, initializing the client, and using file features to create a file memory store, write a Markdown file, and read it back. For more operations such as listing, updating, and deleting, see Common file operations below.

Python

from tablestore_agent_storage import AgentStorageClient


client = AgentStorageClient(
    api_key="your-api-key",
    ots_endpoint="https://your-instance.cn-beijing.ots.aliyuncs.com",
    ots_instance_name="your-instance-name",
)

scope = {
    "appId": "app-001",
    "tenantId": "user-001",
    "agentId": "assistant",
    "runId": "session-001",
}

client.create_memory_store({
    "memoryStoreName": "agent_files",
    "storageMode": "filemem",
})

client.add_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "content": "# 用户偏好\n\n- 喜欢美式咖啡\n- 偏好简洁回答\n",
})

item = client.get_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "view": "full",
})
print(item["content"])

TypeScript

import { AgentStorageClient } from '@tablestore/agent-storage';

async function main() {
  const client = new AgentStorageClient({
    apiKey: 'your-api-key',
    endpoint: 'https://your-instance.cn-beijing.ots.aliyuncs.com',
    instanceName: 'your-instance-name',
  });

  const scope = {
    appId: 'app-001',
    tenantId: 'user-001',
    agentId: 'assistant',
    runId: 'session-001',
  };

  await client.createMemoryStore({
    memoryStoreName: 'agent_files',
    storageMode: 'filemem',
  });

  await client.addItem({
    memoryStoreName: 'agent_files',
    scope,
    path: '/profile/preferences.md',
    content: '# 用户偏好\n\n- 喜欢美式咖啡\n- 偏好简洁回答\n',
  });

  const item = await client.getItem({
    memoryStoreName: 'agent_files',
    scope,
    path: '/profile/preferences.md',
    view: 'full',
  });
  console.log(item.content);
}

void main();

storageMode is a required parameter when creating a memory store and cannot be changed after creation. Subsequent file operations do not need to pass this parameter again; the Agent Storage SDK automatically fills in the type fields required by Item interfaces.

Convert conversations to read-only memory files

If your application already writes conversations through AddMemories, you can let the service asynchronously generate read-only memory files without maintaining file content yourself.

The following four steps can all be completed in the console or SDK. Each step shows both methods (SDK examples use Python).

1. Create a memory store

Create a memory store that outputs both structured memory and files:

Console

  1. Log on to the Agent Storage console, go to Memory store management, and click Create memory store.

  2. For Input type, select Short-term messages. For Output type, select File memory (you can also select Structured memory if you need semantic retrieval at the same time).

  3. Click OK to complete the creation.

SDK

from tablestore_agent_storage import AgentStorageClient

client = AgentStorageClient(
    api_key="your-api-key",
    ots_endpoint="https://your-instance.cn-beijing.ots.aliyuncs.com",
    ots_instance_name="your-instance-name",
)

client.create_memory_store({
    "memoryStoreName": "agent_memory",
    "description": "Agent 对话记忆",
    "inputType": "messages",
    "outputTypes": ["structured", "file"],
})

If you only need files, set outputTypes to ["file"]. inputType cannot be modified after creation. Memory stores that use messages as input can adjust outputTypes through UpdateMemoryStore.

2. Write conversations

Write conversation messages to the memory store. The service generates read-only files asynchronously.

Console

  1. Open the file memory store, go to the Short-term memory page, and click Write memory.

  2. For Input mode, select Conversation messages (JSON). Fill in the complete four-level scope (Application appId, Tenant/User tenantId, Agent agentId, Session runId).

  3. Paste the conversation messages JSON and click OK to submit. Files are generated asynchronously. After submission, you can check the generation task status on the Request log page.

SDK

Call AddMemories to write messages. File output only supports asynchronous generation, so sync must be false or omitted.

resp = client.add_memories({
    "memoryStoreName": "agent_memory",
    "scope": {
        "appId": "shopping-app",
        "tenantId": "user-001",
        "agentId": "shopping-assistant",
        "runId": "session-001",
    },
    "messages": [
        {"role": "user", "content": "我平时喝美式咖啡,不加糖。"},
        {"role": "assistant", "content": "好的,我会记住你的饮品偏好。"},
    ],
    "sync": False,
})
request_id = resp["requestId"]

Save the requestId from the response. Passing sync=true returns 400 INVALID_PARAMETER.

3. Wait for file generation to complete

Query the generation task status to confirm that the service has generated the read-only files.

Console

  1. Open the file memory store and go to the Request log page.

  2. Find the corresponding record by the Request ID saved during writing, check the Status column, and wait for the status to become completed.

SDK

Use the requestId returned by AddMemories to call GetMemoryTask:

task = client.get_memory_task({
    "memoryStoreName": "agent_memory",
    "requestId": request_id,
})
print(task["task"]["status"])

When task.status is completed, all configured outputs have been generated. For dual-output memory stores, the overall task is completed only after both structured memory and files have been generated.

4. List and read files

Use the exact four-level scope from the write operation to browse the service-generated read-only files. Service-generated files do not support wildcard scopes.

Console

  1. Log on to the Agent Storage console, open the file memory store, and go to the Long-term memory page.

  2. Switch to File memory and select the complete scope used during writing.

  3. Browse the generated read-only files in the file tree. Click a file to view its content and version history.

SDK

Call ListItems to list files, then read each one.

scope = {
    "appId": "shopping-app",
    "tenantId": "user-001",
    "agentId": "shopping-assistant",
    "runId": "session-001",
}

page = client.list_items({
    "type": "memoryfile",
    "memoryStoreName": "agent_memory",
    "scope": scope,
    "limit": 20,
})

# Get the actual path from items, then read the content
for entry in page["items"]:
    item = client.get_item({
        "type": "memoryfile",
        "memoryStoreName": "agent_memory",
        "scope": scope,
        "path": entry["path"],
        "view": "full",
    })
    print(item["path"], item["content"])

When the top-level readOnly in the response is true, these files are maintained by the service. Reading content requires setting view=full.

Calling create, update, rename, or delete interfaces on these files returns 409 READ_ONLY_STORE. To modify content, continue writing conversations or maintain the source memory through structured memory interfaces.

Mount as a local directory through FUSE

agent-memory-fuse maps a file memory store and an exact scope in a Tablestore instance to a Linux local directory. After mounting, agents and applications can use ls, cat, editors, or file APIs to read and write memory without integrating the Agent Storage SDK into the application.

Each mount corresponds to a single (instance, memoryStoreName, scope). This tool is designed for file memory, not as a general-purpose POSIX file system.

Prepare the environment

  • Obtain the agent-memory-fuse Linux executable that matches your runtime architecture, and add execute permissions.

  • FUSE is enabled in the Linux kernel, and the current user or container can access /dev/fuse.

  • fusermount3 is installed. On some systems, the command name is fusermount.

  • A file memory store with storageMode=filemem has been created. Prepare the instance HTTPS endpoint, instance name, and complete four-level scope.

  • An API Key, AccessKey, or STS temporary credential is ready. API Keys must be used with HTTPS endpoints.

Running in a container typically requires mapping /dev/fuse and granting CAP_SYS_ADMIN or equivalent user namespace mount permissions. Use least-privilege configuration based on your runtime environment.

chmod +x ./agent-memory-fuse
mkdir -p /mnt/agent-memory

Mount file memory

Run the following command. The scope in the example corresponds to the scope object in the quick start. Use quotes to wrap the complete scope to prevent the shell from interpreting special characters unexpectedly.

./agent-memory-fuse mount \
  --endpoint https://your-instance.cn-beijing.ots.aliyuncs.com \
  --instance your-instance-name \
  --credential apikey:your-api-key \
  --store agent_files \
  --scope 'app-001#user-001#assistant#session-001' \
  --session fuse-session-001 \
  /mnt/agent-memory

The mount command runs in the foreground and manages the mount lifecycle. The following log indicates that the initial directory load and mount succeeded.

mounted /mnt/agent-memory: store=agent_files files=1 readOnly=false

Keep this process running and access the mount directory from another terminal or business process. In production, use systemd or a container orchestration system to manage the process. Do not forcefully terminate the process while the mount is still in use.

The main parameters are as follows.

Parameter

Description

--endpoint

HTTPS endpoint of the Tablestore instance

--instance

Tablestore instance name

--credential

apikey:<key>, aksk:<id>:<secret>, or sts:<id>:<secret>:<token>

--store

Name of the memory store with storageMode=filemem

--scope

Exact scope separated by #: appId#tenantId#agentId#runId. Wildcards are not supported.

--session

Session identifier for this mount, used for server-side version attribution. Different write sessions should use different values.

--read-only

Optional. Restricts this mount to read-only.

Last positional argument

Local mount directory

--credential contains sensitive information. The example only shows the parameter format. Do not write real credentials into code, images, logs, or shared scripts. Prefer short-lived credentials with restricted permissions.

Read and write files

After the mount succeeds, you can read, create, modify, rename, and delete files as you would in a regular directory.

# View existing server-side files
find /mnt/agent-memory -type f
cat /mnt/agent-memory/profile/preferences.md

# Create or update files
mkdir -p /mnt/agent-memory/projects/alpha
printf '%s\n' '# 项目决策' '' '- 使用事件驱动架构' \
  > /mnt/agent-memory/projects/alpha/decisions.md
cat /mnt/agent-memory/projects/alpha/decisions.md

# Rename and delete files
mv /mnt/agent-memory/projects/alpha/decisions.md \
  /mnt/agent-memory/projects/alpha/architecture.md
rm /mnt/agent-memory/projects/alpha/architecture.md

Files are synced to the server on flush, fsync, or close. Production applications must check the return values of fsync and close. Some shell redirections do not surface errors during the close stage. For important writes, re-read the file after completion to confirm.

Directories are formed from file path prefixes. Directories that contain files can be restored across processes and remounts. Empty directories exist only within the current mount process.

Read-only mount

If the agent only needs to read memory, add --read-only before the mount directory argument.

./agent-memory-fuse mount \
  --endpoint https://your-instance.cn-beijing.ots.aliyuncs.com \
  --instance your-instance-name \
  --credential apikey:your-api-key \
  --store agent_files \
  --scope 'app-001#user-001#assistant#session-001' \
  --session fuse-reader-001 \
  --read-only \
  /mnt/agent-memory

For read-only file views generated from structured memory, the server automatically switches the mount to read-only. Write operations on a read-only mount return EROFS.

Rotate STS credentials

When mounting with STS credentials, you can rotate the complete AccessKey ID, AccessKey Secret, and STS Token without unmounting the directory. The credential provider must write the following JSON to standard output and pipe it to the rotation command.

{"accessKeyId":"new-access-key-id","accessKeySecret":"new-access-key-secret","stsToken":"new-sts-token"}
your-credential-provider | \
  ./agent-memory-fuse rotate-credential --mountpoint /mnt/agent-memory

The rotation command reads credentials from standard input to avoid putting new credentials in command-line arguments. A successful command indicates that the new credentials have been installed in the local mount process. Whether the credentials are valid will be confirmed in subsequent file requests. Only trusted processes can access the mount point and perform credential rotation.

Unmount file memory

After completing file operations and closing all open files, run the following command.

./agent-memory-fuse umount /mnt/agent-memory

After unmounting succeeds, the foreground mount process exits. If the system lacks both fusermount3 and fusermount, the unmount command returns an error. Install FUSE userspace tools first.

Limits and troubleshooting

  • Only valid UTF-8 text is supported. The maximum size of a single file is 100 KiB. Exceeding these limits returns EILSEQ or EFBIG, respectively.

  • Each scope supports a maximum of 2,000 current files by default. When the quota is reached, writes return ENOSPC.

  • When multiple clients concurrently modify the same file, stale file handles may return ESTALE. Reopen and read the latest content before deciding whether to retry.

  • Invalid credentials or an expired STS Token return EACCES. Rotate credentials or remount with valid credentials.

  • Service rate limiting or brief unavailability may return EAGAIN. The tool performs bounded retries first. Applications should still use backoff strategies to handle final errors.

  • Symbolic links, hard links, ACLs, extended attributes, sparse files, and cross-session file locks are not supported.

  • If you see operation not permitted or cannot open /dev/fuse, check device mapping, current user permissions, and container mount capabilities.

  • If you see an initial directory load error, check whether the endpoint, instance name, credentials, memory store name, and scope match.

File location

A file is identified by the memory store, scope, and path together.

  • memoryStoreName: The memory store name.

  • scope: The scope to which the file belongs. You must provide the complete appId, tenantId, agentId, and runId. Wildcard * is not supported.

  • path: The file path within the scope. We recommend using semantic paths with a leading /, such as /profile/preferences.md or /projects/alpha/decisions.md.

The same path can be used in different scopes. File content is isolated between scopes. The itemId returned by the list interface is the stable identifier of the file and is required when querying historical versions.

Common file operations

The following operations can be completed in the console or SDK. All console operations are on the Long-term memory page of the file memory store: first select the Application (appId) and Tenant/User (tenantId) (Agent and Session can be set to "All" for browsing; creating or uploading files requires a complete four-level scope), browse the file list by Path prefix on the left, and click a file to view its content, metadata, and version history on the right. SDK examples use the Python client, scope, and agent_files memory store from the quick start.

Read metadata only

Console

Select the target file in the file list on the left. The details panel on the right directly displays the file content, Creation time, Update time, and current Version ID. No additional operation is needed to view metadata.

SDK

Set includeContent to False. The response will not include content, which is suitable for checking file summaries and update times.

current = client.get_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "includeContent": False,
})
print(current["contentSha256"], current["updatedAt"])

Update file content

Console

Select the file, click Edit or replace data, modify the File content, and save. The console performs concurrency validation based on the current version. If the file has been modified by another request, the save fails. Refresh and retry.

SDK

For concurrent write scenarios, we recommend passing the contentSha256 from the last read as expectedSha256. When the file has been modified by another request, the service rejects the overwrite. The application should re-read the file and then decide whether to retry.

updated = client.update_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "content": "# 用户偏好\n\n- 喜欢拿铁\n- 偏好简洁回答\n",
    "expectedSha256": current["contentSha256"],
})

Rename a file

Console

Select the file, click Rename, enter the new File path, and confirm. If the target path already exists, a conflict is reported.

SDK

UpdateItem handles both content updates and renames. A single request must specify exactly one of content or newPath.

renamed = client.update_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/preferences.md",
    "newPath": "/profile/user-preferences.md",
    "expectedSha256": updated["contentSha256"],
})

When the target path already exists, a conflict is returned by default. Only set "overwrite": True when the business confirms that replacing the target file is allowed.

List files with pagination

Console

On the Long-term memory page, after selecting a scope, filter and browse the file list by Path prefix on the left with pagination. Click Refresh to get the latest list.

SDK

ListItems returns 100 files per page by default, with a maximum of 500 per page. When the response includes nextToken, pass it as-is in the next request.

next_token = None
while True:
    request = {
        "memoryStoreName": "agent_files",
        "scope": scope,
        "pathPrefix": "/profile/",
        "limit": 100,
    }
    if next_token:
        request["nextToken"] = next_token

    page = client.list_items(request)
    for entry in page["items"]:
        print(entry["path"])

    next_token = page.get("nextToken")
    if not next_token:
        break

Delete a file

Console

Select the file, click Delete, and confirm. Deletion removes the current file and creates a deletion version. Historical versions can still be viewed in Version history.

SDK

client.delete_item({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "path": "/profile/user-preferences.md",
    "expectedSha256": renamed["contentSha256"],
})

The delete operation removes the current file, but historical versions can still be queried by file ID.

Query historical versions

Each create, update, rename, or delete operation creates an immutable historical version. First, obtain the itemId from the current file or a previously saved response, then list the versions.

versions = client.list_item_versions({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "itemId": renamed["itemId"],
    "limit": 20,
})

version = versions["versions"][0]
snapshot = client.get_item_version({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "itemId": version["itemId"],
    "versionId": version["versionId"],
    "versionSeq": version["versionSeq"],
})
print(snapshot.get("content"))

You can use operation to filter created, modified, or deleted versions. The version list does not return content. Call GetItemVersion to read a specific snapshot.

Redact historical versions

Warning

Redaction is irreversible. Before executing, confirm that you have selected the correct historical version.

RedactItemVersion clears the path, content, content hash, and size of a historical snapshot. It preserves the operation type, version sequence, creation time, and redaction audit information. Repeat requests are idempotent. Redaction does not modify the current file or create a new version.

redacted = client.redact_item_version({
    "memoryStoreName": "agent_files",
    "scope": scope,
    "itemId": version["itemId"],
    "versionId": version["versionId"],
    "versionSeq": version["versionSeq"],
    "sessionId": "privacy-job-001",
})
print(redacted["redacted"], redacted["redactedAt"])

After redaction, calling GetItemVersion still returns the version, but it no longer includes content.

Read the file view of structured memory

If your application writes conversations or text to the service and uses structured memory interfaces for semantic retrieval, the same memory can also be browsed as files by the agent.

  • Continue writing and maintaining data through structured memory interfaces such as AddMemories, UpdateMemory, and DeleteMemory.

  • Use the Agent Storage SDK's list_items and get_item to list and read generated files.

  • When the ListItems response includes readOnly: true, the current file view is read-only. Create, update, rename, delete, and version operations are not supported.

    page = client.list_items({
        "memoryStoreName": "agent_memory",
        "scope": scope,
    })
    
    if page.get("readOnly"):
        for entry in page["items"]:
            item = client.get_item({
                "memoryStoreName": "agent_memory",
                "scope": scope,
                "path": entry["path"],
            })
            print(item["path"], item["content"])

File write operations on a read-only file view return READ_ONLY_STORE. In this case, modify the source memory through structured memory interfaces.

Common errors

Error code

Common cause

Suggested fix

VALIDATION_ERROR

Incomplete scope, invalid path, or the update request provided both content and newPath

Check the complete four-level scope, path, and request branch

NOT_FOUND

The memory store, scope, path, or version does not exist

Verify the file location information. Do not reuse file identifiers across scopes.

PATH_EXISTS

The target path for creation or renaming already exists

Use a different path. Only enable overwrite when the business confirms it is allowed.

SHA_MISMATCH

The file has been modified by another request

Re-read the file and decide whether to retry based on the latest content

LOCK_CONFLICT

Concurrent changes are occurring in the same scope

Retry after a brief backoff and re-read the latest file

READ_ONLY_STORE

Attempted to modify a read-only file view

Use structured memory interfaces to update the source memory instead

Limits

  • Only valid UTF-8 text is supported. The maximum size of a single file is 100 KiB.

  • The normalized path can be up to 800 bytes. Paths cannot point to the root directory and cannot contain empty path segments, ., .., or NUL characters.

  • Each scope supports a maximum of 2,000 current files by default.

  • All Item interfaces require a complete four-level scope. Wildcards are not supported.

  • Redacted historical versions cannot be restored.