OpenViking Documentation

Self-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy OpenViking on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name openviking -p 3030:3030 --restart always docker.io/langfuse/langfuse-worker:3
Configured Services & Ports
⚙️ langfuse-worker
image: docker.io/langfuse/langfuse-worker:3
🔌 Ports: 127.0.0.1:3030:3030
⚙️ langfuse-web
image: docker.io/langfuse/langfuse:3
🔌 Ports: 3000:3000
⚙️ clickhouse
image: docker.io/clickhouse/clickhouse-server
🔌 Ports: 127.0.0.1:8123:8123, 127.0.0.1:9000:9000
⚙️ minio
image: cgr.dev/chainguard/minio
🔌 Ports: 9090:9000, 127.0.0.1:9091:9001
⚙️ redis
image: docker.io/redis:7
🔌 Ports: 127.0.0.1:6379:6379
⚙️ postgres
image: docker.io/postgres:${POSTGRES_VERSION:-17}
🔌 Ports: 127.0.0.1:5432:5432
docker-compose.yml
yaml (docker-compose.yml)
# Make sure to update the credential placeholders with your own secrets.
# We mark them with # CHANGEME in the file below.
# In addition, we recommend to restrict inbound traffic on the host to langfuse-web (port 3000) and minio (port 9090) only.
# All other components are bound to localhost (127.0.0.1) to only accept connections from the local machine.
# External connections from other machines will not be able to reach these services directly.
services:
  langfuse-worker:
    image: docker.io/langfuse/langfuse-worker:3
    restart: always
    depends_on: &langfuse-depends-on
      postgres:
        condition: service_healthy
      minio:
        condition: service_healthy
      redis:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
    ports:
      - 127.0.0.1:3030:3030
    environment: &langfuse-worker-env
      NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
      DATABASE_URL: ${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/postgres} # CHANGEME
      SALT: ${SALT:-vikingbot-salt-2026}
      ENCRYPTION_KEY: ${ENCRYPTION_KEY:-0000000000000000000000000000000000000000000000000000000000000000}
      TELEMETRY_ENABLED: ${TELEMETRY_ENABLED:-false}
      LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES: ${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}
      CLICKHOUSE_MIGRATION_URL: ${CLICKHOUSE_MIGRATION_URL:-clickhouse://clickhouse:9000}
      CLICKHOUSE_URL: ${CLICKHOUSE_URL:-http://clickhouse:8123}
      CLICKHOUSE_USER: ${CLICKHOUSE_USER:-clickhouse}
      CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-clickhouse}
      CLICKHOUSE_CLUSTER_ENABLED: ${CLICKHOUSE_CLUSTER_ENABLED:-false}
      LANGFUSE_USE_AZURE_BLOB: ${LANGFUSE_USE_AZURE_BLOB:-false}
      LANGFUSE_S3_EVENT_UPLOAD_BUCKET: ${LANGFUSE_S3_EVENT_UPLOAD_BUCKET:-langfuse}
      LANGFUSE_S3_EVENT_UPLOAD_REGION: ${LANGFUSE_S3_EVENT_UPLOAD_REGION:-auto}
      LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID:-minio}
      LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY:-miniosecret}
      LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: ${LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT:-http://minio:9000}
      LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: ${LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE:-true}
      LANGFUSE_S3_EVENT_UPLOAD_PREFIX: ${LANGFUSE_S3_EVENT_UPLOAD_PREFIX:-events/}
      LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: ${LANGFUSE_S3_MEDIA_UPLOAD_BUCKET:-langfuse}
      LANGFUSE_S3_MEDIA_UPLOAD_REGION: ${LANGFUSE_S3_MEDIA_UPLOAD_REGION:-auto}
      LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID:-minio}
      LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY:-miniosecret}
      LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: ${LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT:-http://localhost:9090}
      LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: ${LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE:-true}
      LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: ${LANGFUSE_S3_MEDIA_UPLOAD_PREFIX:-media/}
      LANGFUSE_S3_BATCH_EXPORT_ENABLED: ${LANGFUSE_S3_BATCH_EXPORT_ENABLED:-false}
      LANGFUSE_S3_BATCH_EXPORT_BUCKET: ${LANGFUSE_S3_BATCH_EXPORT_BUCKET:-langfuse}
      LANGFUSE_S3_BATCH_EXPORT_PREFIX: ${LANGFUSE_S3_BATCH_EXPORT_PREFIX:-exports/}
      LANGFUSE_S3_BATCH_EXPORT_REGION: ${LANGFUSE_S3_BATCH_EXPORT_REGION:-auto}
      LANGFUSE_S3_BATCH_EXPORT_ENDPOINT: ${LANGFUSE_S3_BATCH_EXPORT_ENDPOINT:-http://minio:9000}
      LANGFUSE_S3_BATCH_EXPORT_EXTERNAL_ENDPOINT: ${LANGFUSE_S3_BATCH_EXPORT_EXTERNAL_ENDPOINT:-http://localhost:9090}
      LANGFUSE_S3_BATCH_EXPORT_ACCESS_KEY_ID: ${LANGFUSE_S3_BATCH_EXPORT_ACCESS_KEY_ID:-minio}
      LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY: ${LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY:-miniosecret}
      LANGFUSE_S3_BATCH_EXPORT_FORCE_PATH_STYLE: ${LANGFUSE_S3_BATCH_EXPORT_FORCE_PATH_STYLE:-true}
      LANGFUSE_INGESTION_QUEUE_DELAY_MS: ${LANGFUSE_INGESTION_QUEUE_DELAY_MS:-}
      LANGFUSE_INGESTION_CLICKHOUSE_WRITE_INTERVAL_MS: ${LANGFUSE_INGESTION_CLICKHOUSE_WRITE_INTERVAL_MS:-}
      REDIS_HOST: ${REDIS_HOST:-redis}
      REDIS_PORT: ${REDIS_PORT:-6379}
      REDIS_AUTH: ${REDIS_AUTH:-vikingbot-redis-secret}
      REDIS_TLS_ENABLED: ${REDIS_TLS_ENABLED:-false}
      REDIS_TLS_CA: ${REDIS_TLS_CA:-/certs/ca.crt}
      REDIS_TLS_CERT: ${REDIS_TLS_CERT:-/certs/redis.crt}
      REDIS_TLS_KEY: ${REDIS_TLS_KEY:-/certs/redis.key}
      EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-}
      SMTP_CONNECTION_URL: ${SMTP_CONNECTION_URL:-}

  langfuse-web:
    image: docker.io/langfuse/langfuse:3
    restart: always
    depends_on: *langfuse-depends-on
    ports:
      - 3000:3000
    environment:
      <<: *langfuse-worker-env
      NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:-vikingbot-nextauth-secret-2026}
      LANGFUSE_INIT_ORG_ID: ${LANGFUSE_INIT_ORG_ID:-vikingbot-org}
      LANGFUSE_INIT_ORG_NAME: ${LANGFUSE_INIT_ORG_NAME:-Vikingbot Org}
      LANGFUSE_INIT_PROJECT_ID: ${LANGFUSE_INIT_PROJECT_ID:-vikingbot-project}
      LANGFUSE_INIT_PROJECT_NAME: ${LANGFUSE_INIT_PROJECT_NAME:-Vikingbot Project}
      LANGFUSE_INIT_PROJECT_PUBLIC_KEY: ${LANGFUSE_INIT_PROJECT_PUBLIC_KEY:-pk-lf-vikingbot-public-key-2026}
      LANGFUSE_INIT_PROJECT_SECRET_KEY: ${LANGFUSE_INIT_PROJECT_SECRET_KEY:-sk-lf-vikingbot-secret-key-2026}
      LANGFUSE_INIT_USER_EMAIL: ${LANGFUSE_INIT_USER_EMAIL:[email protected]}
      LANGFUSE_INIT_USER_NAME: ${LANGFUSE_INIT_USER_NAME:-Vikingbot Admin}
      LANGFUSE_INIT_USER_PASSWORD: ${LANGFUSE_INIT_USER_PASSWORD:-vikingbot-admin-password-2026}

  clickhouse:
    image: docker.io/clickhouse/clickhouse-server
    restart: always
    user: "101:101"
    environment:
      CLICKHOUSE_DB: default
      CLICKHOUSE_USER: ${CLICKHOUSE_USER:-clickhouse}
      CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-clickhouse}
    volumes:
      - langfuse_clickhouse_data:/var/lib/clickhouse
      - langfuse_clickhouse_logs:/var/log/clickhouse-server
    ports:
      - 127.0.0.1:8123:8123
      - 127.0.0.1:9000:9000
    healthcheck:
      test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 1s

  minio:
    image: cgr.dev/chainguard/minio
    restart: always
    entrypoint: sh
    # create the 'langfuse' bucket before starting the service
    command: -c 'mkdir -p /data/langfuse && minio server --address ":9000" --console-address ":9001" /data'
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minio}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-miniosecret}
    ports:
      - 9090:9000
      - 127.0.0.1:9091:9001
    volumes:
      - langfuse_minio_data:/data
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 1s
      timeout: 5s
      retries: 5
      start_period: 1s

  redis:
    image: docker.io/redis:7
    restart: always
    command: >
      --requirepass ${REDIS_AUTH:-vikingbot-redis-secret}
      --maxmemory-policy noeviction
    ports:
      - 127.0.0.1:6379:6379
    volumes:
      - langfuse_redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 3s
      timeout: 10s
      retries: 10

  postgres:
    image: docker.io/postgres:${POSTGRES_VERSION:-17}
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 3s
      timeout: 3s
      retries: 10
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
      POSTGRES_DB: ${POSTGRES_DB:-postgres}
      TZ: UTC
      PGTZ: UTC
    ports:
      - 127.0.0.1:5432:5432
    volumes:
      - langfuse_postgres_data:/var/lib/postgresql/data

volumes:
  langfuse_postgres_data:
    driver: local
  langfuse_clickhouse_data:
    driver: local
  langfuse_clickhouse_logs:
    driver: local
  langfuse_minio_data:
    driver: local
  langfuse_redis_data:
    driver: local

File: README.md


What is OpenViking

OpenViking is an open-source context database for AI agents. It stores memories, resources, and skills as one virtual filesystem under the viking:// protocol, so an agent browses its own context with ls, tree, and find instead of querying a black-box vector store. Content is processed into three tiers — L0 abstract, L1 overview, L2 details — and loaded on demand. Every retrieval leaves a trajectory you can watch and debug. Full introduction: Getting started.

The OpenViking Studio playground — a live demo you can open in the browser, no installation required.

Why OpenViking

  • One filesystem for all context. Memories, resources, and skills each get a viking:// URI. Agents locate and manipulate context deterministically, like a developer working with files. → Viking URI · Context types
  • Tiered loading cuts token spend. Every entry is processed into L0 (abstract), L1 (overview), and L2 (details) on write, then loaded only as deep as the task requires. → Context layers
  • Directory recursive retrieval. Vector search first locates the highest-scoring directory, then drills down layer by layer, so results arrive with their surrounding context intact. → Retrieval
  • Observable retrieval. Each query preserves its directory-browsing trajectory. When a result looks wrong, you can see exactly which path produced it. → Retrieval
  • Sessions become memory. After a session commits, OpenViking asynchronously extracts user preferences and agent experience into long-term memory. → Session

How the pieces fit together: Architecture. The thinking behind the design: The Database Paradigm for Context Engineering.

text
viking://
├── resources/              # Resources: project docs, repos, web pages, etc.
│   └── my_project/
│       ├── docs/
│       │   ├── api/
│       │   └── tutorials/
│       └── src/
└── user/
    └── {user_id}/
        ├── memories/
        │   └── preferences/
        │       ├── writing_style
        │       └── coding_habits
        ├── resources/
        │   └── private_project/
        ├── skills/
        │   ├── search_code
        │   └── analyze_data
        └── peers/
            └── web-visitor-alice/

The three loading tiers:

  • L0 (Abstract): a one-sentence summary for quick relevance checks.
  • L1 (Overview): core information and usage scenarios for planning.
  • L2 (Details): the full original data, read only when needed.

Each directory carries its own L0/L1 layers, so relevance can be judged before any full file is read:

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

Proof it works

OpenViking 0.3.22 has been evaluated on long-conversation user memory (LoCoMo) and multi-turn agent tasks (tau2-bench). Full results and setup details, including knowledge-base QA, are in the benchmark report; reproduction scripts live in ./benchmark.

  • User memory (LoCoMo): with OpenViking, all three agent integrations land at 80–83% accuracy — up from 24–57% on their native memory — while input tokens drop by 34.3–91.0% and query latency by 58.45–66.10%.
  • Agent experience (tau2-bench): experience memory lifts task success by +6.87pp (retail) and +11.87pp (airline) over the same LLM without memory.

Quick start

💡 Want to see it in action first? Try OpenViking Studio — a live hosted instance with a context playground, semantic search, and a multi-agent hub. No installation required.

Requires Python 3.10 or higher.

bash
pip install openviking --upgrade
openviking-server init      # interactive wizard: providers, models, ov.conf
openviking-server doctor    # validate setup
openviking-server           # start (background: nohup openviking-server > openviking.log 2>&1 &)

init walks you through provider setup and writes ~/.openviking/ov.conf. It supports Volcengine, OpenAI, Codex OAuth, Kimi, GLM, and local Ollama — for Ollama it can detect and install the runtime and pull models suited to your hardware. doctor checks the config file, Python version, provider connectivity, and disk space without a running server. Manual ov.conf templates, per-provider examples, environment variables, and Windows setup: Configuration guide · Quick start docs.

The install already includes the ov client CLI. With the server running:

bash
ov status
ov add-resource https://github.com/volcengine/OpenViking # --wait
ov ls viking://resources/
ov tree viking://resources/volcengine -L 2
# wait some time for semantic processing if not --wait
ov find "what is openviking"
ov grep "openviking" --uri viking://resources/volcengine/OpenViking/docs/en

Next steps:

  • Client configuration (ov config), standalone CLI installs (npm / cargo), and advanced usage such as index rebuilding: CLI setup
  • Docker and production deployment: Deployment guide

Use it with your agent

Integrations inject OpenViking recall into your agent's context and auto-commit session memory:

Setup instructions for each agent: Agent integrations overview.

OpenViking Helper (Beta)

OpenViking Helper is a desktop console, currently in beta for macOS and Windows x64:

  • Visual local agent setup: detects OpenViking CLI, Claude Code, Codex, Cursor, Trae, and OpenCode, then configures supported plugin, MCP, Hook, and CLI integrations.
  • Session trace inspection: parses Claude Code, Codex, and Trae sessions to show OpenViking recall, prompt injection, MCP calls, capture, and commit events.
  • Local memory and skill management: views local memory / rule files and SKILL.md skills, then syncs them to OpenViking.

Download:

VikingBot

VikingBot is an AI agent framework built on top of OpenViking:

bash
pip install "openviking[bot]"
openviking-server --with-bot
ov chat   # in another terminal

The official Docker image bundles VikingBot and starts it by default alongside the server and console UI. Details: VikingBot guide.

Deploy in production

For production, run OpenViking as a standalone HTTP service — see Server deployment and the Deployment guide.

Commercial editions

The open-source edition is not crippled. OpenViking in this repo is fully open source under AGPLv3: no feature gates, no account required, no activation key. Follow Deploy in production above and run it in production yourself — and that will stay true.

The two editions below answer "who operates it and where it runs", not "can I use it".

| ☁️ Managed SaaS
Officially hosted on Volcano Engine. Nothing to set up, nothing to operate.

Personal — for individual developers. Free trial for up to 50 files, and scales far beyond local hardware with VikingDB.
Enterprise — multi-user context management, team collaboration and permissions, enterprise SLA and support.

Existing open-source users can move over with the migration tool.
→ Volcano Engine product page · Documentation
Global hosting for regions outside China is coming to BytePlus. | 🏢 Self-Managed
Runs inside your own environment. Data never leaves it.

Online — deployed into your own cloud account / VPC, BYOC supported, with outbound access for updates and licensing.
Offline — fully air-gapped environments with no internet access, for regulated industries.

Adds distributed deployment and official support on top of the open-source edition, activated by license key.

→ Talk to us about self-managed deployment |
| --- | --- |

Just want to run the open-source edition? Go ahead — you don't need to contact anyone. Head to Quick start.

Research

OpenViking open-sources a subset of the core capabilities described in the VikingMem paper:

VikingMem: A Memory Base Management System for Stateful LLM-based Applications
Jiajie Fu, Junwen Chen, Mengzhao Wang, Aoxiang He, Maojia Sheng, Xiangyu Ke, Yifan Zhu, and Yunjun Gao.
arXiv:2605.29640, 2026. Accepted by VLDB 2026.
📄 Read the paper on arXiv

Partner Projects

OpenViking welcomes collaboration with other open-source projects to build the context data ecosystem. Our confirmed partners include:

  • deer-flow - Open-source long-horizon SuperAgent harness
  • NoKV - AI native distributed file system
  • loopx - Lightweight loop engineering state kernel
  • Hermes Agent - The agent that grows with you

Interested in joining our partner list? Please submit an issue to our community to apply.

Community & contributing

OpenViking is still in its early stages, and there is plenty left to build.

Security and privacy

This project takes security seriously.
For vulnerability reporting and supported versions, see SECURITY.md

License

The OpenViking project uses different licenses for different components:

  • Main Project: AGPLv3 - see the LICENSE file for details
  • crates/ov_cli: Apache 2.0 - see the LICENSE for details
  • examples: Apache 2.0 - see the LICENSE for details
  • third_party: Respective original licenses of third-party projects

File: bot/deploy/docker/README.md

Vikingbot Docker 一键部署

本目录提供 Vikingbot 的 Docker 一键部署脚本,支持本地快速部署和多架构支持。

前置要求

请先安装 Docker:

部署脚本还会使用 Python 3 验证现有 ov.conf 的 JSON 结构和 Gateway 端口。

验证依赖:

bash
docker --version
python3 --version

快速开始

从火山引擎镜像部署(推荐)

如果你已经有推送到火山引擎镜像仓库的镜像,可以直接拉取并部署:

bash
# 1. 创建必要的目录结构
mkdir -p ~/.vikingbot/

# 2. 启动容器
docker run -d \
    --name vikingbot \
    --restart unless-stopped \
    --platform linux/amd64 \
    -v ~/.vikingbot:/root/.vikingbot \
    -p 18791:18791 \
    vikingbot-cn-beijing.cr.volces.com/vikingbot/vikingbot:latest \
    gateway

# 3. 查看日志
docker logs --tail 50 -f vikingbot

按 Ctrl+C 退出日志查看,容器继续后台运行。

本地代码构建镜像部署

如果你想从本地代码构建镜像并部署:

一行命令部署

bash
./deploy/docker/deploy.sh

脚本会自动检测本地架构(arm64/amd64)并构建适配的镜像。

分步部署

1. 构建镜像

bash
./deploy/docker/build-image.sh

2. 部署服务

bash
./deploy/docker/deploy.sh

3. 停止服务

bash
./deploy/docker/stop.sh

多架构支持

脚本自动支持多架构,无需手动配置!

自动检测(推荐)

脚本会自动检测你的系统架构并使用对应镜像:

bash
# Apple Silicon (M1/M2/M3) - 自动使用 linux/arm64
./deploy/docker/deploy.sh

# Intel/AMD - 自动使用 linux/amd64
./deploy/docker/deploy.sh

手动指定架构

如需手动指定:

bash
# 构建 arm64 镜像(Apple Silicon)
PLATFORM=linux/arm64 ./deploy/docker/build-image.sh

# 构建 amd64 镜像(Intel/AMD)
PLATFORM=linux/amd64 ./deploy/docker/build-image.sh

# 同时构建两个架构(多架构镜像)
MULTI_ARCH=true ./deploy/docker/build-image.sh

使用指定架构部署

bash
# 使用 arm64 镜像部署
PLATFORM=linux/arm64 ./deploy/docker/deploy.sh

# 使用 amd64 镜像部署
PLATFORM=linux/amd64 ./deploy/docker/deploy.sh

文件说明

文件 说明
build-image.sh 一键构建 Docker 镜像(支持多架构)
deploy.sh 一键部署(自动构建镜像+启动容器,自动检测架构)
stop.sh 停止并清理容器
image_upload.sh 将本地镜像上传到火山引擎镜像仓库
image_upload.example.yaml 镜像上传配置文件示例
README.md 本文档

使用 Docker Compose

项目根目录也提供了 docker-compose.yml:

bash
# 启动服务
docker-compose up -d

# 查看日志
docker-compose logs -f

# 停止服务
docker-compose down

环境变量配置

build-image.sh

变量 默认值 说明
IMAGE_NAME vikingbot 镜像名称
IMAGE_TAG latest 镜像标签
DOCKERFILE deploy/Dockerfile Dockerfile 路径
NO_CACHE false 是否不使用缓存
PLATFORM 自动检测 目标平台 (linux/amd64, linux/arm64)
MULTI_ARCH false 是否构建多架构镜像

示例:

bash
# 构建带版本标签的镜像
IMAGE_TAG=v1.0.0 ./deploy/docker/build-image.sh

# 不使用缓存重新构建
NO_CACHE=true ./deploy/docker/build-image.sh

# 构建 arm64 镜像
PLATFORM=linux/arm64 ./deploy/docker/build-image.sh

# 同时构建 amd64+arm64 多架构镜像
MULTI_ARCH=true ./deploy/docker/build-image.sh

deploy.sh

变量 默认值 说明
CONTAINER_NAME vikingbot 容器名称
IMAGE_NAME vikingbot 镜像名称
IMAGE_TAG latest 镜像标签
HOST_PORT 18791 主机端口
CONTAINER_PORT 18791 容器端口
COMMAND gateway 启动命令
AUTO_BUILD true 镜像不存在时自动构建
PLATFORM 自动检测 使用的镜像平台

示例:

bash
# 使用自定义端口
HOST_PORT=8080 ./deploy/docker/deploy.sh

# 不自动构建镜像
AUTO_BUILD=false ./deploy/docker/deploy.sh

# 强制使用 arm64 镜像
PLATFORM=linux/arm64 ./deploy/docker/deploy.sh

stop.sh

变量 默认值 说明
CONTAINER_NAME vikingbot 容器名称
REMOVE_IMAGE false 是否同时删除镜像
REMOVE_VOLUME false 是否同时删除数据卷

示例:

bash
# 完全清理(容器+镜像+数据卷)
REMOVE_IMAGE=true REMOVE_VOLUME=true ./deploy/docker/stop.sh

配置文件

首次部署时,脚本会自动创建配置文件:~/.vikingbot/ov.conf。脚本同时生成随机 Gateway Token;在非本机请求中通过 X-Gateway-Token 请求头传入该值。

编辑该文件填入你的 API keys:

json
{
  "bot": {
    "agents": {
      "provider": "openrouter",
      "model": "openrouter/anthropic/claude-3.5-sonnet",
      "api_key": "sk-or-xxx"
    },
    "gateway": {
      "host": "0.0.0.0",
      "port": 18791,
      "token": "脚本生成的随机值"
    }
  }
}

重要: bot.gateway.port 必须与 CONTAINER_PORT 一致;脚本默认都使用 18791。如果现有配置不是有效 JSON、缺少 bot.gateway,或端口不一致,部署会在替换旧容器前停止并提示修复配置。

访问控制台

部署成功后,访问:http://localhost:18791

常用命令

bash
# 查看日志
docker logs -f vikingbot

# 进入容器
docker exec -it vikingbot bash

# 运行 vikingbot 命令
docker exec vikingbot vikingbot status

# 重启容器
docker restart vikingbot

架构兼容性说明

系统 架构 自动检测 手动指定
Apple Silicon (M1/M2/M3) arm64 ✓ PLATFORM=linux/arm64
Intel Mac amd64 ✓ PLATFORM=linux/amd64
Linux PC/Server amd64 ✓ PLATFORM=linux/amd64
Linux ARM Server arm64 ✓ PLATFORM=linux/arm64
Windows (WSL2) amd64 ✓ PLATFORM=linux/amd64

与 VKE 部署共用 Dockerfile

注意:本地 Docker 部署和 VKE 部署共用同一个 Dockerfile(deploy/Dockerfile),确保了环境一致性。

  • VKE 部署:使用 deploy/vke/vke_deploy.py
  • 本地部署:使用 deploy/docker/deploy.sh
  • 两者都使用:deploy/Dockerfile

Dockerfile 已移除平台硬编码,支持灵活的多架构构建!

跨平台镜像构建(推送到仓库)

如果你需要构建可以在 Windows/Mac/Linux 多平台运行的镜像,可以使用 build-multiarch.sh:

前置准备

  1. 准备一个 Docker 镜像仓库(如 Docker Hub, ACR, Harbor 等)
  2. 登录到镜像仓库

构建并推送跨平台镜像

bash
# 构建 linux/amd64 + linux/arm64 双架构镜像并推送
REGISTRY=your-registry.com PUSH=true ./deploy/docker/build-multiarch.sh

环境变量配置

变量 说明 示例
REGISTRY 镜像仓库地址 registry.example.com
IMAGE_NAME 镜像名称 vikingbot
IMAGE_TAG 镜像标签 latest
PUSH 是否推送 true / false
PLATFORMS 目标架构 linux/amd64,linux/arm64

使用跨平台镜像

推送成功后,在任何平台都可以直接使用:

bash
# 在 Apple Silicon Mac 上
PLATFORM=linux/arm64 ./deploy/docker/deploy.sh

# 在 Intel/AMD Linux 上
PLATFORM=linux/amd64 ./deploy/docker/deploy.sh

# 或让脚本自动检测
./deploy/docker/deploy.sh

验证镜像架构

bash
# 查看镜像支持的架构
docker manifest inspect your-registry.com/vikingbot:latest

File: bot/deploy/vke/README.md

VKE 部署指南

本文档介绍如何将 Vikingbot 部署到火山引擎容器服务(VKE)。

目录


架构概述

text
/* Detailed source-code truncated for AI context efficiency. */

前置准备

1. 火山引擎账号

  • 注册火山引擎账号:https://www.volcengine.com/
  • 完成实名认证
  • 开通以下服务:
    • 容器服务 VKE
    • 容器镜像服务 CR
    • 对象存储 TOS(可选,用于持久化存储)

2. 创建 VKE 集群

  1. 登录火山引擎控制台
  2. 进入 容器服务 VKE → 集群
  3. 点击 创建集群
  4. 配置集群参数:
    • 集群名称:vikingbot(或自定义)
    • Kubernetes 版本:选择最新稳定版(推荐 1.24+)
    • 容器运行时:containerd
    • 网络模式:Flannel 或 Calico
    • Service CIDR:默认即可
  5. 配置节点池:
    • 节点规格:推荐 2核4G 或更高(ecs.g1.large)
    • 节点数量:至少 2 个节点
    • 系统盘:40Gi SSD
  6. 确认配置并创建集群

等待集群创建完成(约 10-15 分钟)


3. 创建容器镜像仓库

  1. 进入 容器镜像服务 CR → 命名空间
  2. 点击 创建命名空间
    • 名称:vikingbot
    • 类型:私有
  3. 进入 镜像仓库
  4. 点击 创建镜像仓库
    • 名称:vikingbot
    • 命名空间:选择刚才创建的 vikingbot
    • 描述:Vikingbot 镜像仓库

4. 创建 TOS 存储桶(可选)

如果使用 TOS 作为持久化存储,需要创建存储桶:

  1. 进入 对象存储 TOS → 存储桶列表
  2. 点击 创建存储桶
  3. 配置参数:
    • 名称:vikingbot-data(或自定义)
    • 地域:选择与 VKE 集群相同的地域(如 cn-beijing)
    • 存储类型:标准存储
    • 权限:私有
  4. 点击 确定 创建

5. 获取访问凭证

5.1 创建 AccessKey(仅 TOS 存储需要)

  1. 鼠标悬停在右上角头像,点击 API 访问密钥
  2. 点击 新建密钥
  3. 完成手机验证
  4. 保存生成的 AccessKey ID 和 Secret Access Key

重要:Secret Access Key 只显示一次,请妥善保存!

5.2 获取 Kubeconfig

  1. 进入 容器服务 VKE → 集群
  2. 找到你的集群,点击 连接
  3. 在 集群访问凭证 页签,点击 下载 获取 Kubeconfig
  4. 将下载的文件保存到 ~/.kube/config,或配置 KUBECONFIG 环境变量

验证连接:

bash
kubectl get nodes

6. 配置本地环境

确保本地已安装:

  • Docker:用于构建镜像
  • kubectl:用于操作 Kubernetes 集群
  • Python 3:部署脚本需要

验证安装:

bash
docker --version
kubectl version --client
python3 --version

快速部署

步骤 1:复制配置文件

bash
mkdir -p ~/.config/vikingbot
cp deploy/vke/vke_deploy.example.yaml ~/.config/vikingbot/vke_deploy.yaml

步骤 2:编辑配置

bash
vim ~/.config/vikingbot/vke_deploy.yaml

填入以下信息:

yaml
volcengine_region: cn-beijing               # 地域

image_registry: vikingbot-cn-beijing.cr.volces.com  # 镜像仓库地址
image_namespace: vikingbot
image_repository: vikingbot
image_tag: latest

# 镜像仓库登录凭证(如果是私有仓库)
registry_username: "你的火山引擎账号"
registry_password: "你的火山引擎密码"

# 存储类型:local (EBS) 或 tos
storage_type: tos

# TOS 配置(仅 storage_type=tos 时需要)
volcengine_access_key: AKLTxxxxxxxxxx
volcengine_secret_key: xxxxxxxxxx
tos_bucket: vikingbot_data
tos_path: /.vikingbot/
tos_region: cn-beijing

步骤 3:执行部署

bash
cd /path/to/vikingbot
chmod +x deploy/vke/deploy.sh
deploy/vke/deploy.sh

部署脚本会自动完成:

  1. 构建 Docker 镜像
  2. 推送镜像到火山引擎 CR
  3. 创建 K8s 资源(Secret、PV、PVC、Deployment、Service)
  4. 等待部署完成

配置详解

vke_deploy.yaml 配置项

配置项 说明 必填 示例
volcengine_access_key 火山引擎 AccessKey ID 执行 TOS 部署时 AKLTxxxx
volcengine_secret_key 火山引擎 Secret Access Key 执行 TOS 部署时 xxxx
volcengine_region 地域 是 cn-beijing
image_registry 镜像仓库地址 是 vikingbot-cn-beijing.cr.volces.com
image_namespace 命名空间 是 vikingbot
image_repository 仓库名称 是 vikingbot
image_tag 镜像标签 否 latest
use_timestamp_tag 使用时间戳标签 否 false
registry_username 镜像仓库用户名 否
registry_password 镜像仓库密码 否
storage_type 存储类型:local 或 tos 否 local
tos_bucket TOS 桶名 storage_type=tos vikingbot_data
tos_path TOS 路径 storage_type=tos /.vikingbot/
tos_region TOS 地域 storage_type=tos cn-beijing
k8s_namespace K8s 命名空间 否 default
k8s_replicas Pod 副本数 否 1
kubeconfig_path kubeconfig 路径 否 ~/.kube/config

手动部署

如果不想使用一键部署脚本,可以按以下步骤手动操作。

1. 构建并推送镜像

bash
# 构建镜像
docker build --platform linux/amd64 -f deploy/Dockerfile -t vikingbot .

# 登录镜像仓库
docker login vikingbot-cn-beijing.cr.volces.com -u  -p 

# Tag 镜像
docker tag vikingbot vikingbot-cn-beijing.cr.volces.com/vikingbot/vikingbot:latest

# 推送
docker push vikingbot-cn-beijing.cr.volces.com/vikingbot/vikingbot:latest

2. 准备 Kubernetes Manifest

复制 deploy/vke/k8s/deployment.yaml,替换以下变量:

  • __IMAGE_NAME__:完整镜像名
  • __REPLICAS__:副本数
  • __ACCESS_MODES__:访问模式(ReadWriteOnce 或 ReadWriteMany)
  • __STORAGE_CLASS_CONFIG__:StorageClass 配置
  • __VOLUME_NAME_CONFIG__:VolumeName 配置

3. 创建 TOS Secret(仅使用 TOS 时)

bash
# Base64 编码 AccessKey
AK_B64=$(echo -n "your-access-key" | base64)
SK_B64=$(echo -n "your-secret-key" | base64)

# 创建 Secret
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: vikingbot-tos-secret
type: Opaque
data:
  AccessKeyId: ${AK_B64}
  SecretAccessKey: ${SK_B64}
EOF

4. 部署应用

bash
kubectl apply -f deploy/vke/k8s/deployment.yaml

验证部署

查看 Pod 状态

bash
kubectl get pods -l app=vikingbot

预期输出:

text
NAME                         READY   STATUS    RESTARTS   AGE
vikingbot-746d99fd94-xxxxx   1/1     Running   0          2m

查看 Service

bash
kubectl get svc vikingbot

查看日志

bash
# 查看所有 Pod 日志
kubectl logs -l app=vikingbot --tail=100

# 跟随日志
kubectl logs -f deployment/vikingbot

查看部署状态

bash
kubectl rollout status deployment/vikingbot

访问 Gateway(本地端口转发)

bash
kubectl port-forward svc/vikingbot 8080:80

然后访问:http://localhost:8080


故障排查

Pod 无法启动

bash
# 查看 Pod 事件
kubectl describe pod 

# 查看日志
kubectl logs

镜像拉取失败

检查:

  1. 镜像仓库地址是否正确
  2. 镜像是否已推送
  3. 仓库是否为私有,是否配置了 ImagePullSecret

存储挂载失败

bash
# 查看 PVC 状态
kubectl get pvc

# 查看 PV 状态
kubectl get pv

# 查看事件
kubectl describe pvc vikingbot-data

健康检查失败

健康检查路径:/health,端口:18791

bash
# 进入 Pod 内部检查
kubectl exec -it  -- bash

# 在 Pod 内测试
curl http://localhost:18791/health

常用命令

bash
# 扩容/缩容
kubectl scale deployment vikingbot --replicas=3

# 更新镜像
kubectl set image deployment/vikingbot vikingbot=vikingbot-cn-beijing.cr.volces.com/vikingbot/vikingbot:new-tag

# 重启 Deployment
kubectl rollout restart deployment/vikingbot

# 回滚
kubectl rollout undo deployment/vikingbot

# 删除所有资源
kubectl delete -f deploy/vke/k8s/deployment.yaml

附录

地域列表

地域 ID 地域名称
cn-beijing 华北2(北京)
cn-shanghai 华东2(上海)
cn-guangzhou 华南1(广州)
cn-shenzhen 华南2(深圳)

镜像仓库地址格式

text
{namespace}-{region}.cr.volces.com

示例:vikingbot-cn-beijing.cr.volces.com


参考链接


File: bot/vikingbot/console/README_GRADIO.md

Vikingbot Console - Gradio 版本

使用 Gradio 实现的纯 Python 控制台界面。

运行

bash
vikingbot gateway

这会自动在 http://localhost:18791 启动控制台 Web UI!

功能

1. Dashboard

  • 显示系统状态
  • 版本信息
  • 配置路径和工作区路径

2. Config

  • Skills & Hooks: 独立标签页
  • Agents / Providers / Channels / Gateway / Tools / Sandbox / Heartbeat: 每个在自己的标签页中
    • Agents: 展开 AgentDefaults
    • Providers: 每个 provider 在自己的子标签页中
    • Sandbox: backends 在自己的子标签页中
    • Channels: JSON 编辑器(可配置多个 channel)
    • Enums: 使用下拉框(SandboxBackend, SandboxMode)

3. Sessions

  • 刷新按钮:加载会话列表
  • 会话选择:选择会话查看内容
  • 会话内容显示:
    • 用户消息:绿色
    • 助手消息:红色
    • 其他消息:黑色

4. Workspace

  • 使用 Gradio 的 FileExplorer 组件
  • 显示工作区文件树
  • 选择文件查看内容

File: bot/vikingbot/openviking_mount/README.md

OpenViking 文件系统挂载模块

这个模块将 OpenViking 的虚拟文件系统挂载到本地文件系统路径,让用户可以像操作普通文件一样操作 OpenViking 上的数据。

这个模块只是一个实验功能,并没有被实际使用

功能特性

  • 文件系统范式: 将 OpenViking 的 viking:// URI 映射到本地文件路径
  • 多作用域支持: 支持 resources、session、user 等多种作用域挂载
  • 挂载管理: 支持多个挂载点的生命周期管理
  • 语义搜索: 通过文件系统路径进行语义搜索
  • 层级内容访问: 支持 L0 (abstract)、L1 (overview)、L2 (details) 三层内容访问

快速开始

基本使用

python
from vikingbot.openviking_mount import OpenVikingMount, MountConfig, MountScope
from pathlib import Path

# 创建挂载配置
config = MountConfig(
    mount_point=Path("./my_openviking_mount"),
    openviking_data_path=Path("./my_openviking_cache"),
    scope=MountScope.RESOURCES,
    auto_init=True,
    read_only=False
)

# 使用上下文管理器
with OpenVikingMount(config) as mount:
    # 列出目录
    files = mount.list_dir(mount.config.mount_point)
    for f in files:
        print(f"{f.name} ({'目录' if f.is_dir else '文件'})")
    
    # 读取文件
    content = mount.read_file(mount.config.mount_point / "some_file.md")
    print(content)
    
    # 获取摘要和概览
    abstract = mount.get_abstract(mount.config.mount_point / "some_dir")
    overview = mount.get_overview(mount.config.mount_point / "some_dir")
    print(f"摘要: {abstract}")
    print(f"概览: {overview}")
    
    # 语义搜索
    results = mount.search("什么是 OpenViking")
    for r in results:
        print(f"{r.uri}")

使用挂载管理器

python
from vikingbot.openviking_mount import OpenVikingMountManager, get_mount_manager
from pathlib import Path

# 获取全局管理器
manager = get_mount_manager()

# 创建资源挂载
mount = manager.create_resources_mount(
    mount_id="my_resources",
    openviking_data_path=Path("./ov_cache")
)

# 为会话创建挂载
session_mount = manager.create_session_mount(
    session_id="session_123",
    openviking_data_path=Path("./ov_cache")
)

# 列出所有挂载
mounts = manager.list_mounts()
for m in mounts:
    print(f"{m['id']} -> {m['mount_point']}")

# 获取挂载
mount = manager.get_mount("my_resources")

# 移除挂载
manager.remove_mount("my_resources", cleanup=True)

目录结构

text
vikingbot/openviking_mount/
├── __init__.py          # 模块入口,导出公共API
├── mount.py             # 核心挂载实现 (OpenVikingMount)
└── manager.py           # 挂载管理器 (OpenVikingMountManager)

API 参考

OpenVikingMount

主要的挂载类,提供文件系统操作。

初始化参数

参数 类型 说明
config MountConfig 挂载配置对象

MountConfig

字段 类型 默认值 说明
mount_point Path 必填 挂载点路径
openviking_data_path Path 必填 FUSE 本地缓存路径
session_id Optional[str] None 会话 ID(session 作用域时需要)
scope MountScope RESOURCES 挂载作用域
auto_init bool True 是否自动初始化
read_only bool False 是否只读模式

MountScope 枚举

值 说明
RESOURCES 只挂载资源目录
SESSION 只挂载会话目录
USER 只挂载用户目录
ALL 挂载所有作用域

主要方法

方法 说明
initialize() 初始化 OpenViking 客户端
list_dir(path) 列出目录内容
read_file(path) 读取文件内容
write_file(path, content) 写入文件内容
mkdir(path) 创建目录
delete(path, recursive) 删除文件/目录
get_abstract(path) 获取 L0 摘要
get_overview(path) 获取 L1 概览
search(query, target_path) 语义搜索
add_resource(source_path, target_path) 添加资源
sync_to_disk(path) 同步到磁盘
close() 关闭挂载

OpenVikingMountManager

挂载管理器,管理多个挂载点的生命周期。

主要方法

方法 说明
create_mount(mount_id, ...) 创建新挂载
get_mount(mount_id) 获取挂载
list_mounts() 列出所有挂载
remove_mount(mount_id, cleanup) 移除挂载
remove_all(cleanup) 移除所有挂载
create_session_mount(session_id, ...) 为会话创建挂载
create_resources_mount(mount_id, ...) 创建资源挂载

全局函数

函数 说明
get_mount_manager(base_mount_dir) 获取全局挂载管理器单例

路径映射

OpenViking URI 到本地文件路径的映射规则:

text
OpenViking URI                    本地路径
-------------------               ------------------
viking://resources/foo     ->    {mount_point}/resources/foo
viking://session/bar       ->    {mount_point}/session/bar
viking://user/baz          ->    {mount_point}/user/baz

测试

运行测试:

bash
cd /Users/bytedance/workspace/openviking/bot
.venv/bin/python test_openviking_mount.py

注意事项

  1. 直接写入限制: OpenViking 主要通过 add_resource 添加外部资源,直接文件写入需要特殊处理
  2. 性能考虑: 大量文件操作可能影响性能,建议批量处理
  3. 数据同步: sync_to_disk 是一个简化实现,生产环境可能需要更复杂的同步机制
  4. 只读模式: 设置 read_only=True 可以防止意外修改

下一步

  • 集成到 vikingbot 的 SessionManager 中
  • 添加 FUSE 支持实现真正的文件系统挂载
  • 实现更完善的双向同步机制
  • 添加更多测试用例

File: bot/workspace/skills/README.md

vikingbot Skills

This directory contains built-in skills that extend vikingbot's capabilities.

Skill Format

Each skill is a directory containing a SKILL.md file with:

  • YAML frontmatter (name, description, metadata)
  • Markdown instructions for the agent

Attribution

These skills are adapted from OpenClaw's skill system.
The skill format and metadata structure follow OpenClaw's conventions to maintain compatibility.

Available Skills

Skill Description
github Interact with GitHub using the gh CLI
github-proxy GitHub 国内访问加速,使用 githubproxy.cc 代理加速 GitHub 仓库克隆、文件下载等操作
weather Get weather info using wttr.in and Open-Meteo
summarize Summarize URLs, files, and YouTube videos
tmux Remote-control tmux sessions
skill-creator Create new skills