# OpenViking: agent memory you can ls, read and edit

> A context database that keeps an agent's knowledge, memory and skills in one filesystem under viking://, with generated summaries in front of the content. The build is heavier than the install line, and the project still calls itself alpha.

**volcengine/OpenViking** — Self-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.

- Repository: https://github.com/volcengine/OpenViking
- Website: https://openviking.ai/
- Stars: 38,969 · Forks: 3,052
- Language: Python
- License: AGPL-3.0
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/volcengine-openviking

## viking:// turns agent memory into a directory you can read

The decision that separates OpenViking from a plain vector store is visible in one URI scheme. Context is organised as a virtual filesystem under `viking://`, and the agent moves through it with the verbs you would use on disk: `ls`, `tree`, `read`, `write` and `grep`. That is the argument the project makes about agent memory in general, which it calls a black box where text goes in, embeddings come out, and nobody can see what was actually stored. Here you open any directory, read what the agent believes, edit it and write the change back. The tree partitions by kind as well as by project. `viking://resources/` holds documents, repos and web pages, while under `viking://user/{user_id}/` you get `memories/` for preferences and experience, `resources/` for that user's own material, `skills/` for how to perform tasks, and `peers/` for other users. Every item carries a `viking://` URI, so one address works for browsing by hand and for retrieval by the agent. The payoff is that debugging memory becomes file inspection instead of guesswork. The cost is a layout your prompts, plugins and tooling have to learn.

## L0 abstracts and L1 overviews sit in front of the content

Every directory that has been semantically processed gets two generated files, and an agent is meant to read them before it reads anything else:

```
viking://resources/my_project/
├── .abstract.md           # L0: quick relevance check
├── .overview.md           # L1: structure and key points
└── docs/
    ├── .abstract.md
    ├── .overview.md
    └── api/
        ├── auth.md         # L2: full content, loaded on demand
        └── endpoints.md
```

L0 is a one-sentence abstract for a quick relevance check, L1 is an overview with core information and usage scenarios for planning, and L2 is the full original data, read only when needed. This layering is the mechanism behind the input token savings the project reports, and it is also where the risk sits. The text an agent decides on is generated text, not the source. A wrong L0 abstract prunes a directory that in fact held the answer, and nothing in the interface tells the agent it was pruned. The upside of the filesystem choice applies here too: open `.abstract.md` and `.overview.md` in an editor and you can see within seconds whether the generated abstract describes the directory underneath it.

## find runs your query, search plans one from the session

Retrieval is split into two commands with different costs, and the split exists because of scoping. `find` runs a query directly. `search` plans retrieval from the session context. The project frames this as searching a directory rather than the whole index, scoping semantic search to a project or a memory subtree instead of scanning a flat vector pool. In a deployment holding material for many users, a flat pool means every query competes with everything anyone has ever stored, and the subtree form lets you bound the candidate set before ranking. The same boundary shows up on disk, where `viking://user/{user_id}/` keeps memories, resources, skills and peers in separate subtrees per user. This is what should decide the question for you. One project with one agent is the easy case, where any retrieval layer will do. Many users with their own memories, skills and peer directories is the case the layout was drawn for, and the case where a single flat index across tenants would blur who is allowed to see what.

## pip install openviking pulls a C++, Rust and Python build

The install line is short and the build behind it is not. The quick start asks for Python 3.10 plus access to an embedding model and a VLM, cloud or local:

```bash
pip install openviking --upgrade
openviking-server init      # configure providers and models
openviking-server doctor    # check configuration and connectivity
openviking-server           # start the server
```

Underneath, the declared build backend is `setuptools.build_meta` with `setuptools>=61.0`, `setuptools-scm>=8.0`, `cmake>=3.15`, `maturin>=1.0,<2.0` and `wheel` in `requires`. `setup.py` resolves a CMake path, a C compiler and a C++ compiler, points at an engine source directory under `src/`, and picks a host engine build config from the machine architecture. Its one escape hatch is the environment variable `OV_SKIP_CPP_BUILD` set to `1`, and skipping the build removes the native engine rather than substituting another. The Rust side is a Cargo workspace of three members, `crates/ov_cli`, `crates/ragfs` and `crates/ragfs-python`, released with `opt-level = 3`, LTO and symbol stripping. A plain `pip install` can therefore demand a working toolchain on the target machine, which is the cost to price before you pick a container runtime or a prebuilt image. The dependency set also pins the parsing stack at `tree-sitter==0.25.2` and `tree-sitter-python==0.25.0`, with a comment saying the pin exists to avoid unvalidated upstream API and grammar changes.

## init does not finish until a model provider is configured

`openviking-server init` decides whether the server ever runs, because it is the step that writes `~/.openviking/ov.conf`. The provider options named in the quick start are Volcengine, OpenAI, Codex OAuth, Kimi, GLM and local Ollama, and none of them is a default. That list mixes two very different things: hosted API providers, where embedding and VLM calls leave your network for that provider, and one local runtime. The credential you need is different for each entry, which is why the next command matters more than it looks. `openviking-server doctor` checks configuration and connectivity, so a wrong key, an unreachable endpoint or a model name that does not exist surfaces there. Run it before the server starts, not after an agent session has already failed to retrieve anything. Ollama is the only entry in that list that removes the network hop, at the cost of putting model inference on the same machine as retrieval.

## The compose file publishes 1933 directly, and 1934 is a legacy proxy

The container path is where the deployment defaults get interesting. The compose file pulls `ghcr.io/volcengine/openviking:latest`, names the container `openviking`, mounts `~/.openviking` at `/app/.openviking`, and publishes `${OPENVIKING_SERVER_PORT:-1933}` on that same port, so the server answers on 1933 unless you override the variable. A `caddy:2` service sits alongside it as a reverse proxy, and its own comment marks port 1934 as legacy, retained for existing deployments, with new setups connecting directly to `openviking:1933`. The healthcheck runs `openviking-entrypoint --healthcheck` every 30 seconds with a 5 second timeout, 3 retries and a 30 second start period. The volume mount is worth noting next to the config step: the directory where `init` wrote `ov.conf` on your host is the same `~/.openviking` the container mounts. For anything past a laptop the file is explicit about what is missing. There is no TLS on the default path, and public HTTPS means editing the `Caddyfile`, setting `OPENVIKING_PUBLIC_BASE_URL` and `OV_ACME_EMAIL` in a `.env` file beside the compose file, then uncommenting the 80/443 lines. The comment ties that to OAuth and to MCP clients on the internet. Skip it and you are left with a plaintext HTTP port and an empty public base URL.

## Alpha status, AGPL-3.0, and benchmarks tied to one model pair

Three things deserve a look before anyone adopts this, and none of them are hidden. The classifier in `pyproject.toml` reads `Development Status :: 3 - Alpha`, and the release tags agree, running v0.4.21, v0.4.22 and a separate `sdk/go/v0.0.4`. The license field is `AGPL-3.0` with the authors listed as ByteDance, so if you intend to run this inside a product you do not publish, that text is the first file to read rather than an afterthought. The benchmark section is candid about its own scope. The evaluation ran OpenViking 0.3.22 on LoCoMo for long-conversation user memory and tau2-bench for multi-turn agent tasks, using Doubao 2.0 Pro as the VLM and Doubao-embedding-vision-251215 as the embedding model. The reported outcome is that all three agent integrations land at 80 to 83 percent accuracy on LoCoMo against 24 to 57 percent on their native memory, with input tokens down 34.3 to 91.0 percent and query latency down 58.45 to 66.10 percent, and that experience memory adds 6.87 percentage points on retail and 11.87 on airline tasks. Read those as ranges rather than single figures, and read them as results for one embedding model and one VLM on version 0.3.22, which is three patch lines behind the release you would install.

## Conclusion

Adopt OpenViking if you are building an agent whose memory you need to read, edit and diff, and you can supply an embedding model and a VLM, local or hosted. Do not adopt it expecting a drop-in library: the build pulls in CMake, a Rust toolchain and a native engine, and pyproject.toml still classifies the project as alpha. Before you commit, run `openviking-server doctor` against the provider you intend to use, because that is where a bad credential or an unreachable endpoint shows up.

## FAQ

### What is OpenViking?

It is a context database for AI agents that keeps knowledge, memory and skills in one filesystem under the viking:// URI scheme. Agents move through it with file operations such as ls, tree, read, write and grep, and every directory carries a generated summary.

### How to install openviking?

The quick start runs pip install openviking, then openviking-server init, openviking-server doctor and the server itself, and it needs Python 3.10 or newer plus access to an embedding model and a VLM. The init step writes ~/.openviking/ov.conf with your provider choice, and doctor checks configuration and connectivity.

### How to use OpenViking?

Browse the viking:// tree to inspect what the agent stored, then use find to run a query directly or search to plan retrieval from the session context. Directories expose a generated L0 abstract and L1 overview ahead of the L2 full content, and committing a session archives the conversation and extracts memories as Markdown you can inspect, edit and merge.

### Is OpenViking good?

The project classifies itself as Development Status :: 3 - Alpha, and the newest release is v0.4.22. Its own evaluation covers version 0.3.22 on LoCoMo and tau2-bench with a single embedding model and a single VLM, so the reported gains do not carry over automatically to a different model pair.

### openviking vs rag

The difference the project draws is scoping and layering. Semantic search is scoped to a project or memory subtree instead of scanning a flat vector pool, and generated L0 abstracts plus L1 overviews sit in front of the L2 full content so an agent can judge relevance before opening anything.

## Sources

- [Official documentation](https://openviking.ai/)
- [Official README](https://github.com/volcengine/OpenViking#readme)
- [Project repository](https://github.com/volcengine/OpenViking)
- [Release notes](https://github.com/volcengine/OpenViking/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/volcengine-openviking
