OpenViking 实战:在 Claude Code 和 GLM 之间实现跨模型上下文共享

OpenViking 实战:在 Claude Code 和 GLM 之间实现跨模型上下文共享

摘要:本文详细介绍如何使用 OpenViking 作为上下文管理中心,实现 Claude Code(VSCode 插件)和智谱 GLM 之间的对话内容共享和语义检索。通过 MCP(Model Context Protocol)集成,让不同 AI 模型能够访问共同的上下文记忆库。


目录

  1. [什么是 OpenViking](#什么是 OpenViking)
  2. 应用场景
  3. 系统架构
  4. 环境准备
  5. [安装 OpenViking](#安装 OpenViking)
  6. [配置 OpenViking](#配置 OpenViking)
  7. [启动 OpenViking 服务器](#启动 OpenViking 服务器)
  8. [创建 MCP 服务器](#创建 MCP 服务器)
  9. [配置 Claude Code](#配置 Claude Code)
  10. 测试验证
  11. 使用指南
  12. 常见问题
  13. 进阶技巧

什么是 OpenViking

OpenViking 是由字节跳动开发的 Agent-native Context Database(面向 AI Agent 的上下文数据库),主要功能包括:

  • 语义检索:基于向量嵌入的智能搜索
  • 上下文存储:自动分块、向量化存储对话和文档
  • 多模态支持:支持文本、PDF、网页等多种格式
  • API 接口:提供 HTTP API 和 CLI 工具
  • VLM 集成:支持视觉语言模型处理图像

官方仓库:OpenViking


应用场景

场景 1:跨模型上下文共享

复制代码
Claude Code 对话 → OpenViking ← GLM 对话
                         ↓
                    统一上下文库

场景 2:长期记忆管理

  • 保存重要的对话内容
  • 检索历史讨论
  • 跨会话知识积累

场景 3:文档知识库

  • 自动索引本地文档
  • 语义搜索相关内容
  • AI 辅助阅读和写作

系统架构

复制代码
┌─────────────────┐
│   Claude Code   │
│   (VSCode)      │
└────────┬────────┘
         │ MCP Protocol
         ▼
┌─────────────────────────────────┐
│     OpenViking MCP Server       │
│  (openviking_mcp.py)            │
└────────┬────────────────────────┘
         │ HTTP API
         ▼
┌─────────────────────────────────┐
│   OpenViking HTTP Server        │
│   (localhost:8765)              │
└────────┬────────────────────────┘
         │
         ▼
┌─────────────────────────────────┐
│   Vector Database + Storage     │
│   (Chroma + Local Files)        │
└─────────────────────────────────┘

环境准备

系统要求

  • 操作系统:Windows / macOS / Linux
  • Python:3.8 或更高版本
  • 内存:建议 4GB 以上
  • 网络:需要访问 embedding API(本教程使用智谱 AI)

检查 Python 环境

bash 复制代码
python --version

安装 OpenViking

步骤 1:使用 pip 安装

bash 复制代码
pip install openviking

步骤 2:验证安装

bash 复制代码
pip show openviking

预期输出:

复制代码
Name: openviking
Version: 0.1.17
Summary: An Agent-native context database

步骤 3:安装 MCP 依赖

bash 复制代码
pip install mcp

配置 OpenViking

步骤 1:创建配置目录

bash 复制代码
# Windows
mkdir %USERPROFILE%\.openviking

# macOS/Linux
mkdir ~/.openviking

步骤 2:创建主配置文件 ov.conf

Windows 路径C:\Users\YourUsername\.openviking\ov.conf

json 复制代码
{
  "embedding": {
    "dense": {
      "provider": "openai",
      "api_base": "https://open.bigmodel.cn/api/paas/v4/embeddings",
      "api_key": "你的_API_KEY",
      "model": "embedding-3",
      "dimension": 2048
    }
  },
  "vlm": {
    "provider": "openai",
    "api_base": "https://open.bigmodel.cn/api/paas/v4",
    "api_key": "你的_API_KEY",
    "model": "glm-4v"
  }
}

获取 API Key

  1. 访问 智谱 AI 开放平台
  2. 注册/登录账号
  3. 在 API Keys 页面创建新的密钥

步骤 3:创建 CLI 配置文件 ovcli.conf

bash 复制代码
# Windows
echo {"url": "http://localhost:8765"} > %USERPROFILE%\.openviking\ovcli.conf

# macOS/Linux
echo '{"url": "http://localhost:8765"}' > ~/.openviking/ovcli.conf

启动 OpenViking 服务器

方式 1:临时启动(测试用)

bash 复制代码
python -m openviking serve --port 8765

方式 2:后台启动(推荐)

Windows (PowerShell)

powershell 复制代码
Start-Process -WindowStyle Hidden python -ArgumentList "-m openviking serve --port 8765"

Windows (后台服务)

bash 复制代码
python -m openviking serve --port 8765 &

验证服务器运行

bash 复制代码
curl http://localhost:8765/health

预期输出:

json 复制代码
{"status":"ok"}

创建 MCP 服务器

为什么需要 MCP 服务器?

OpenViking 本身不包含 MCP 服务器模块,需要创建一个自定义的 MCP 服务器来桥接 Claude Code 和 OpenViking。

步骤 1:创建 MCP 服务器脚本

文件路径C:\Users\YourUsername\.openviking\openviking_mcp.py

python 复制代码
#!/usr/bin/env python3
"""OpenViking MCP Server for Claude Code integration.

Uses HTTP API to communicate with OpenViking server.
"""

import asyncio
import json
import logging
import tempfile
from pathlib import Path
from typing import Any
from datetime import datetime
from urllib.request import Request, urlopen
from urllib.error import URLError

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# MCP imports
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

# Configuration
OPENVIKING_URL = "http://localhost:8765"

# Create server
server = Server("openviking-server")


def http_post(path: str, data: dict) -> dict:
    """Make HTTP POST request to OpenViking server."""
    url = f"{OPENVIKING_URL}{path}"
    body = json.dumps(data).encode('utf-8')
    req = Request(url, data=body, headers={'Content-Type': 'application/json'})
    try:
        with urlopen(req, timeout=30) as response:
            return json.loads(response.read().decode('utf-8'))
    except URLError as e:
        raise Exception(f"HTTP request failed: {e}")


def http_get(path: str) -> dict:
    """Make HTTP GET request to OpenViking server."""
    url = f"{OPENVIKING_URL}{path}"
    req = Request(url)
    try:
        with urlopen(req, timeout=30) as response:
            return json.loads(response.read().decode('utf-8'))
    except URLError as e:
        raise Exception(f"HTTP request failed: {e}")


@server.list_tools()
async def list_tools() -> list[Tool]:
    """List available MCP tools."""
    return [
        Tool(
            name="ov_save_context",
            description="Save conversation context to OpenViking",
            inputSchema={
                "type": "object",
                "properties": {
                    "content": {
                        "type": "string",
                        "description": "Content to save (will be stored as markdown)"
                    },
                    "title": {
                        "type": "string",
                        "description": "Title for the context (optional, auto-generated if not provided)"
                    }
                },
                "required": ["content"]
            }
        ),
        Tool(
            name="ov_search",
            description="Search OpenViking for relevant context using semantic search",
            inputSchema={
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Search query for semantic retrieval"
                    },
                    "limit": {
                        "type": "integer",
                        "description": "Maximum number of results (default: 5)",
                        "default": 5
                    }
                },
                "required": ["query"]
            }
        ),
        Tool(
            name="ov_health",
            description="Check OpenViking server health status",
            inputSchema={
                "type": "object",
                "properties": {}
            }
        ),
        Tool(
            name="ov_list",
            description="List resources in OpenViking",
            inputSchema={
                "type": "object",
                "properties": {
                    "uri": {
                        "type": "string",
                        "description": "URI to list (default: viking://resources)",
                        "default": "viking://resources"
                    }
                }
            }
        )
    ]


@server.call_tool()
async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
    """Handle tool calls."""
    try:
        if name == "ov_health":
            result = http_get("/health")
            return [TextContent(
                type="text",
                text=json.dumps({
                    "status": "ok",
                    "message": "OpenViking server is running",
                    "server": result
                }, indent=2)
            )]

        elif name == "ov_save_context":
            content = arguments.get("content", "")
            title = arguments.get("title", "")

            if not title:
                title = f"conversation_{datetime.now().strftime('%Y%m%d_%H%M%S')}"

            # Create temp file with content
            with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False, encoding='utf-8') as f:
                f.write(f"# {title}\n\n{content}")
                temp_path = f.name

            try:
                # Use CLI to add resource
                import subprocess
                result = subprocess.run(
                    ['python', '-m', 'openviking', 'add-resource',
                     temp_path,
                     '--to', f'viking://resources/claude_conversations/{title}',
                     '--reason', 'Auto-saved from Claude Code MCP',
                     '--wait'],
                    capture_output=True,
                    text=True,
                    timeout=60
                )

                Path(temp_path).unlink(missing_ok=True)

                if result.returncode == 0:
                    return [TextContent(
                        type="text",
                        text=json.dumps({
                            "status": "success",
                            "message": f"Context saved to OpenViking as '{title}'",
                            "title": title,
                            "location": f"viking://resources/claude_conversations/{title}"
                        }, indent=2)
                    )]
                else:
                    return [TextContent(
                        type="text",
                        text=json.dumps({
                            "status": "error",
                            "error": result.stderr or "Failed to save context"
                        }, indent=2)
                    )]

            except Exception as e:
                Path(temp_path).unlink(missing_ok=True)
                raise

        elif name == "ov_search":
            query = arguments.get("query", "")
            limit = arguments.get("limit", 5)

            # Use CLI for search
            import subprocess
            result = subprocess.run(
                ['python', '-m', 'openviking', 'find',
                 query,
                 '--uri', 'viking://resources',
                 '--limit', str(limit)],
                capture_output=True,
                text=True,
                timeout=30
            )

            if result.returncode == 0:
                return [TextContent(
                    type="text",
                    text=json.dumps({
                        "status": "success",
                        "query": query,
                        "results": result.stdout
                    }, indent=2, ensure_ascii=False)
                )]
            else:
                return [TextContent(
                    type="text",
                    text=json.dumps({
                        "status": "error",
                        "error": result.stderr
                    }, indent=2)
                )]

        elif name == "ov_list":
            uri = arguments.get("uri", "viking://resources")

            import subprocess
            result = subprocess.run(
                ['python', '-m', 'openviking', 'ls', uri],
                capture_output=True,
                text=True,
                timeout=30
            )

            return [TextContent(
                type="text",
                text=json.dumps({
                    "status": "success" if result.returncode == 0 else "error",
                    "uri": uri,
                    "output": result.stdout or result.stderr
                }, indent=2, ensure_ascii=False)
            )]

        else:
            return [TextContent(
                type="text",
                text=f"Unknown tool: {name}"
            )]

    except Exception as e:
        logger.error(f"Error in {name}: {e}", exc_info=True)
        return [TextContent(
            type="text",
            text=json.dumps({
                "status": "error",
                "tool": name,
                "error": str(e)
            }, indent=2)
        )]


async def main():
    """Main entry point."""
    logger.info("Starting OpenViking MCP Server...")
    logger.info(f"OpenViking URL: {OPENVIKING_URL}")

    # Check server health
    try:
        health = http_get("/health")
        logger.info(f"Connected to OpenViking: {health}")
    except Exception as e:
        logger.error(f"Cannot connect to OpenViking server: {e}")
        logger.error("Make sure OpenViking server is running: python -m openviking serve")

    async with stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            server.create_initialization_options()
        )


if __name__ == "__main__":
    asyncio.run(main())

步骤 2:测试 MCP 脚本

bash 复制代码
python -c "from mcp.server import Server; print('MCP imports OK')"

配置 Claude Code

步骤 1:找到配置文件位置

Windows

复制代码
C:\Users\YourUsername\AppData\Roaming\Claude\claude_desktop_config.json

macOS

复制代码
~/Library/Application Support/Claude/claude_desktop_config.json

Linux

复制代码
~/.config/Claude/claude_desktop_config.json

步骤 2:编辑配置文件

如果文件不存在,创建它。添加以下内容:

json 复制代码
{
  "mcpServers": {
    "openviking": {
      "command": "python",
      "args": [
        "C:/Users/YourUsername/.openviking/openviking_mcp.py"
      ],
      "env": {
        "OPENVIKING_CONFIG_FILE": "C:/Users/YourUsername/.openviking/ov.conf"
      }
    }
  }
}

注意 :将路径中的 YourUsername 替换为你的实际用户名,并使用正斜杠 / 或双反斜杠 \\

步骤 3:重启 Claude Code

  1. 完全关闭 VSCode
  2. 重新打开 VSCode
  3. Claude Code 会自动加载 MCP 服务器

测试验证

测试 1:验证 OpenViking 服务器

bash 复制代码
curl http://localhost:8765/health

预期输出:

json 复制代码
{"status":"ok"}

测试 2:添加测试资源

bash 复制代码
python -m openviking add-resource "path/to/your/file.pdf" --to "viking://resources/test" --wait

测试 3:语义搜索

bash 复制代码
python -m openviking find "your search query" --uri "viking://resources" --limit 5

测试 4:在 Claude Code 中测试

重启后,在 Claude Code 对话框中输入:

复制代码
检查 OpenViking 状态

Claude 会自动调用 ov_health 工具并返回结果。


使用指南

在 Claude Code 中使用

保存对话内容

自然语言指令

复制代码
"把这段对话保存到 OpenViking"
"保存上下文:我们今天讨论了 AI 架构设计"
"记录这次关于 Python 性能优化的讨论"
搜索历史内容

自然语言指令

复制代码
"在 OpenViking 中搜索关于 LaTeX 的内容"
"查找之前关于控制理论的讨论"
"搜索所有关于 backstepping 的内容"
检查系统状态

自然语言指令

复制代码
"OpenViking 运行正常吗?"
"检查 OpenViking 服务器状态"

在 GLM 中使用

由于 GLM 目前不直接支持 MCP,你可以通过以下方式使用 OpenViking:

方式 1:命令行检索
bash 复制代码
# 搜索相关上下文
python -m openviking find "你的问题" --uri "viking://resources" --limit 3

# 将结果复制到 GLM 对话中
方式 2:创建快捷脚本
bash 复制代码
# 创建搜索脚本
echo '@echo off
python -m openviking find %1 --uri "viking://resources" --limit 5' > ov_search.bat

# 使用
ov_search.bat "your query"

常见问题

Q1: OpenViking 服务器无法启动

症状:端口被占用

解决

bash 复制代码
# 查找占用端口的进程
netstat -ano | findstr :8765

# 终止进程
taskkill /PID <进程ID> /F

Q2: MCP 服务器连接失败

症状:Claude Code 无法连接到 OpenViking

检查清单

  1. OpenViking 服务器是否运行:curl http://localhost:8765/health
  2. MCP 脚本路径是否正确
  3. 配置文件 JSON 格式是否正确
  4. Python 路径是否在系统 PATH 中

Q3: 向量化失败

症状add-resource 返回错误

解决

  1. 检查 API Key 是否有效
  2. 检查网络连接
  3. 查看配置文件中的 api_base 地址

Q4: 中文搜索结果不准确

解决

  • 使用智谱的 embedding 模型(对中文支持更好)
  • 调整搜索查询,使用更具体的关键词

进阶技巧

技巧 1:自动保存重要对话

创建一个系统提示词,定期保存对话:

复制代码
每当讨论一个重要话题时,自动调用 ov_save_context 保存内容

技巧 2:构建知识库

bash 复制代码
# 批量添加文档
for file in docs/*.pdf; do
    python -m openviking add-resource "$file" --to "viking://resources/docs" --wait
done

技巧 3:多会话上下文共享

在不同 AI 模型间共享上下文:

复制代码
Claude Code → OpenViking ← GLM/ChatGPT/Claude Web

技巧 4:API 直接调用

使用 Python 脚本直接调用 OpenViking API:

python 复制代码
import requests

# 搜索
response = requests.post('http://localhost:8765/api/v1/search/find', json={
    "query": "your search query",
    "target_uri": "viking://resources",
    "limit": 5
})
print(response.json())

项目结构总结

复制代码
.openviking/
├── ov.conf              # 主配置文件
├── ovcli.conf           # CLI 配置文件
├── openviking_mcp.py    # MCP 服务器脚本
└── data/                # 数据存储目录
    ├── vectordb/        # 向量数据库
    └── context/         # 上下文存储

总结

通过本教程,你已经实现了:

✅ OpenViking 服务器部署

✅ MCP 服务器创建和配置

✅ Claude Code 集成

✅ 跨模型上下文共享

✅ 语义检索功能

现在,你可以在不同的 AI 模型之间无缝共享上下文,构建属于你自己的 AI 知识库!


参考资料


如果这篇文章对你有帮助,请给个 赞和收藏 支持一下!有问题欢迎在评论区讨论。

相关推荐
Suryxin.3 小时前
从0开始复现nano-vllm「model_runner-py」下半篇之核心数据编排与执行引擎调度
人工智能·pytorch·深度学习·ai·vllm
PieroPc3 小时前
2026年,我的AI编程助手使用心得(纯个人体验,非评测)
javascript·css·html·fastapi·ai编程
GISer_Jing3 小时前
前端营销I(From AIGC)
前端·aigc·ai编程
一切尽在,你来3 小时前
AI大模型应用开发前置知识:Python 异步编程
python·ai编程
一切尽在,你来3 小时前
LangGraph 概览
人工智能·python·langchain·ai编程
逻极13 小时前
BMAD之落地实施:像CTO一样指挥AI编码 (Phase 4_ Implementation)——必学!BMAD 方法论架构从入门到精通
人工智能·ai·系统架构·ai编程·ai辅助编程·bmad·ai驱动敏捷开发
zhojiew14 小时前
将AgentScope的RAG能力集成到Strands Agent的实践
ai
EchoMind-Henry14 小时前
EchoMindBot_v1.0.0 发布了
人工智能·ai·ai agent 研发手记
宋小黑15 小时前
如何在 TRAE 中安装 UI/UX Pro Max Skill?完整图文教程
ai编程