Token导航 LogoToken导航TokenDH.com
Vector Mind logo
搜索检索未说明官方级别未说明来源级核验

Vector Mind

MCP Server

VectorMind 是一个轻量级向量数据库服务,基于 Redis 提供语义搜索能力,支持 REST API 和 MCP 协议。

工具数

9

提示词数

0

GitHub Stars

1

资源数

0
搜索向量数据库GoAPI集成

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

RecallFlow

提供方

RecallFlow

最后核验

2026/5/17 20:19

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

VectorMind

一个基于Redis的文本RAG(检索增强生成)系统,具有REST API端点和MCP(模型上下文协议)服务器支持。

什么是VectorMind?

VectorMind是一个轻量级的矢量数据库服务,它使用Redis作为后端存储提供语义搜索功能。它从文本内容中创建嵌入,并支持基于相似性的搜索操作。

主要特点

  • 双接口:同时公开REST API(端口8080)和MCP服务器(端口9090)以获得灵活性
  • 向量存储:使用Redis和HNSW(分层导航小世界)索引进行高效的相似性搜索
  • 嵌入支持:例如:使用 ai/mxbai-embed-large 模型
  • 文档管理:使用可选标签和元数据存储文档
  • 文档分块:自动将长文档拆分为重叠的块,以实现更好的语义搜索
  • 相似性搜索:基于具有可配置距离阈值和标签过滤的文本查询查找类似文档

建筑

VectorMind由以下部分组成:

  • Redis服务器:通过RediSearch存储嵌入并提供矢量搜索功能
  • VectorMind服务:Go应用程序,处理嵌入生成并公开API
  • 嵌入模型:例如,它使用 ai/mxbai-embed-large 文本嵌入模型(可配置)
graph TD
    CLIENT1[Client REST API]:::client
    CLIENT2[Client MCP Protocol]:::client

    CLIENT1 -->|HTTP POST
/embeddings
/search
/chunk-and-store| API
    CLIENT2 -->|MCP Protocol| MCP

    subgraph "Docker Compose Environment"
        subgraph "VectorMind Service - Ports: 9090, 8080"
            MCP[MCP Server
Port: 9090]:::mcpserver
            API[REST API
Port: 8080]:::restapi
            VM[VectorMind Container]:::vectormind

            MCP --> VM
            API --> VM
        end

        VM -.->|MODEL_RUNNER_BASE_URL| MODEL

        subgraph "AI Model Layer"
            MODEL[Embedding Model
ai/mxbai-embed-large]:::model
        end

        VM -.->|REDIS_ADDRESS
depends_on| REDIS

        subgraph "Storage Layer"
            REDIS[(Redis Server
Port: 6379)]:::redis
            DATA[(/data Volume)]:::volume

            REDIS --> DATA
        end
    end

    classDef vectormind fill:#4A90E2,stroke:#2E5C8A,stroke-width:2px,color:#fff
    classDef redis fill:#DC382D,stroke:#A72822,stroke-width:2px,color:#fff
    classDef model fill:#10B981,stroke:#059669,stroke-width:2px,color:#fff
    classDef mcpserver fill:#8B5CF6,stroke:#6D28D9,stroke-width:2px,color:#fff
    classDef restapi fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#fff
    classDef client fill:#6B7280,stroke:#4B5563,stroke-width:2px,color:#fff
    classDef volume fill:#EC4899,stroke:#BE185D,stroke-width:2px,color:#fff

入门指南

先决条件

  • Docker、Docker模型运行器和Docker代理编写

启动VectorMind

  1. 使用Docker Compose (推荐):

创建compose.yml 包含以下内容的文件:

services:

  redis-server:
    image: redis:8.2.3-alpine3.22
    environment: 
      - REDIS_ARGS=--save 30 1
    ports:
      - 6379:6379
    volumes:
      - ./data:/data

  vectormind-tests:
    image: k33g/vectormind:0.0.3
    ports:
      - 9090:9090
      - 8080:8080
    environment:
      REDIS_INDEX_NAME: vectormind_index
      REDIS_ADDRESS: redis-server:6379
      REDIS_PASSWORD: ""

      MCP_HTTP_PORT: 9090
      API_REST_PORT: 8080

    models:
      embedding-model:
        endpoint_var: MODEL_RUNNER_BASE_URL
        model_var: EMBEDDING_MODEL

    depends_on:
      redis-server:
        condition: service_started

models:

  embedding-model:
    model: ai/mxbai-embed-large

以下命令启动 VectorMind:

docker compose up -d

这将开始:

  • 端口上的Redis服务器 6379
  • 端口上的VectorMind MCP服务器 9090
  • 端口上的VectorMind REST API 8080
  1. 环境变量:

撰写文件会自动配置:

  • REDIS_INDEX_NAME:vectormind_index
  • REDIS_ADDRESS:redis服务器:6379
  • MCP_HTTP_PORT: 9090
  • API_REST_PORT: 8080
  • MODEL_RUNNER_BASE_URL:通过模型配置设置
  • EMBEDDING_MODEL:ai/mxbai嵌入大

验证安装

检查VectorMind是否正在运行:

curl http://localhost:8080/health

预期响应:

{
  "status": "healthy",
  "server": "mcp-vectormind-server"
}

如何使用VectorMind

REST API使用

1.获取嵌入模型信息

获取有关正在使用的嵌入模型的信息:

curl http://localhost:8080/embedding-model-info

答复:

{
  "success": true,
  "model_id": "ai/mxbai-embed-large",
  "dimension": 1024
}

此终结点返回:

  • success:布尔值,指示请求是否成功
  • model_id:正在使用的嵌入模型的标识符
  • dimension:嵌入向量的维度

2.创建嵌入

使用可选标签和元数据存储文本内容:

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Squirrels run in the forest",
        "label": "animals",
        "metadata": "id=animals_1"
    }'

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Birds fly in the sky",
        "label": "animals",
        "metadata": "id=animals_2"
    }'

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Frogs swim in the pond",
        "label": "animals",
        "metadata": "id=animals_3"
    }'

curl -X POST http://localhost:8080/embeddings \
    -H "Content-Type: application/json" \
    -d '{
        "content": "Fishes swim in the sea",
        "label": "animals",
        "metadata": "id=animals_4"
    }'

答复:

{"id":"doc:b1c36710-9d94-41cb-abfc-aa404b896d1f","content":"Squirrels run in the forest","label":"animals","metadata":"id=animals_1","created_at":"2025-11-09T08:36:01.962629337Z","success":true}
{"id":"doc:fbc259cc-eb8d-425e-a444-d4f5b26400cb","content":"Birds fly in the sky","label":"animals","metadata":"id=animals_2","created_at":"2025-11-09T08:36:02.093359462Z","success":true}
{"id":"doc:0154fc6d-887b-4af2-a5a7-c8b37183554f","content":"Frogs swim in the pond","label":"animals","metadata":"id=animals_3","created_at":"2025-11-09T08:36:02.247079753Z","success":true}
{"id":"doc:3953dfdd-2a92-48de-b61b-0119c9d106fc","content":"Fishes swim in the sea","label":"animals","metadata":"id=animals_4","created_at":"2025-11-09T08:36:02.367855295Z","success":true}

3.搜索类似文档

查找与查询文本类似的文档:

curl -X POST http://localhost:8080/search \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Which animals swim?",
    "max_count": 3,
    "distance_threshold": 0.7
  }'

curl -X POST http://localhost:8080/search \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Where are the squirrels?",
    "max_count": 3,
    "distance_threshold": 0.7
  }'

curl -X POST http://localhost:8080/search \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What can be found in the pond?",
    "max_count": 3,
    "distance_threshold": 0.7
  }'

答复:

{"results":[{"id":"doc:050c7cee-5891-4052-a3c9-40f2bd3abff7","content":"Fishes swim in the sea","distance":0.5175167322158813},{"id":"doc:efe2868d-3330-452c-ac2a-0e835caecdc9","content":"Frogs swim in the pond","distance":0.6700224280357361}],"success":true}
{"results":[{"id":"doc:14e7a8fb-78e5-4fe7-8969-7559b7cd9752","content":"Squirrels run in the forest","distance":0.48874980211257935}],"success":true}
{"results":[{"id":"doc:efe2868d-3330-452c-ac2a-0e835caecdc9","content":"Frogs swim in the pond","distance":0.6417693495750427}],"success":true}

参数:

  • text (必填):搜索查询
  • max_count (可选):最大结果数(默认值:5)
  • distance_threshold (可选):过滤结果的最大距离(越低=越相似)

4.搜索按标签筛选的类似文档

curl -X POST http://localhost:8080/search_with_label \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What lives in the forest?",
    "label": "animals",
    "max_count": 5,
    "distance_threshold": 0.8
  }'

参数:

  • text (必填):搜索查询
  • label (必填):用于筛选结果的标签
  • max_count (可选):最大结果数(默认值:5)
  • distance_threshold (可选):过滤结果的最大距离(更低=更相似)

5.压缩和存储文档

将一个长文档分割成重叠的小块,并使用相同的标签和元数据存储所有块:

# Read the document content and escape it for JSON
DOCUMENT_CONTENT=$(cat document.md | jq -Rs .)

curl -X POST http://localhost:8080/chunk-and-store \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${DOCUMENT_CONTENT},
    \"label\": \"my-label\",
    \"metadata\": \"category=documentation\",
    \"chunk_size\": 1024,
    \"overlap\": 256
  }"

参数:

  • document (必填):要分块和存储的文档内容
  • label (可选):应用于所有块的标签
  • metadata (可选):应用于所有块的元数据
  • chunk_size (必填):每个块的字符大小(必须≤嵌入维度)
  • overlap (必需):块之间重叠的字符数(必须小于chunk_size)

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

此端点可用于:

  • 处理超过嵌入模型限制的长文档
  • 创建重叠块以更好地保存上下文
  • 使用一致的标签批量存储多个块

6.拆分和存储Markdown部分

将markdown文档按节(标题如#、##、###)拆分,并用嵌入存储所有节。大于嵌入维度的部分会自动细分,同时保留部分标题:

# Read the markdown document and escape it for JSON
MARKDOWN_CONTENT=$(cat document.md | jq -Rs .)

curl -X POST http://localhost:8080/split-and-store-markdown-sections \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${MARKDOWN_CONTENT},
    \"label\": \"documentation\",
    \"metadata\": \"project=vectormind\"
  }"

参数:

  • document (必填):要拆分和存储的降价文档内容
  • label (可选):标签适用于所有部分/块
  • metadata (可选):应用于所有节/块的元数据

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

运作原理:

  • 按标题(#######等)拆分markdown文档
  • 每个部分都存储为单独的块
  • 如果截面超过嵌入尺寸,则会自动细分
  • 重要:细分时,每个子块(第一个子块除外)都将添加节头以保留上下文
  • 所有块共享相同的标签和元数据

示例:如果“##矢量简介”一节的长度为3000个字符,并且超过了嵌入维度(1024),它将被拆分为3个子块:

  1. ## Introduction to Vectors\n\n[first 1024 chars of content]
  2. ## Introduction to Vectors\n\n[next 1024 chars of content]
  3. ## Introduction to Vectors\n\n[remaining content]

此端点可用于:

  • 处理结构化降价文档
  • 通过节标题保留语义上下文
  • 无需手动分块即可自动处理大块

7.使用自定义分隔符拆分和存储

用自定义分隔符拆分文档,并使用嵌入存储所有块。大于嵌入维度的块会自动细分,同时保留前2行非空行作为上下文:

# Read the document and escape it for JSON
DOCUMENT_CONTENT=$(cat startrek.txt | jq -Rs .)

curl -X POST http://localhost:8080/split-and-store-with-delimiter \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${DOCUMENT_CONTENT},
    \"delimiter\": \"-----\",
    \"label\": \"star-trek-diseases\",
    \"metadata\": \"source=federation-medical-database\"
  }"

参数:

  • document (必填):要拆分和存储的文档内容
  • delimiter (必填):用于分割文档的分隔符(例如,“-----”、“###”等)
  • label (可选):应用于所有块的标签
  • metadata (可选):应用于所有块的元数据

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

运作原理:

  • 按指定的分隔符拆分文档
  • 每个块都存储为单独的文档
  • 如果块超过嵌入维度,则会自动细分
  • 重要:细分时,原始块的前2行非空行将添加到每个子块(第一行除外)之前,以保留上下文
  • 所有块共享相同的标签和元数据

示例:如果一个块以以下开头:

Disease: Andorian Ice Plague
Provenance: Andoria, Andorian Empire

并且超过嵌入维度,它将被拆分为子块,其中每个子块(第一个子块除外)将以以下开头:

Disease: Andorian Ice Plague
Provenance: Andoria, Andorian Empire

[remaining content]

此端点可用于:

  • 使用自定义分隔符处理结构化数据
  • 通过关键标识行维护文档上下文
  • 使用一致分隔符的数据集(类似CSV、日志文件等)
  • 自动处理大型记录,无需手动分块

8.使用层次结构拆分和存储Markdown(🧪 实验)

按标题拆分markdown文档,同时保留层次结构上下文。每个块都包括带有标题、层次和内容字段的结构化元数据。大于嵌入维度的块会自动细分:

# Read the markdown document and escape it for JSON
MARKDOWN_CONTENT=$(cat document.md | jq -Rs .)

curl -X POST http://localhost:8080/split-and-store-markdown-with-hierarchy \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": ${MARKDOWN_CONTENT},
    \"label\": \"documentation\",
    \"metadata\": \"project=vectormind\"
  }"

参数:

  • document (必填):要拆分和存储的降价文档内容
  • label (可选):应用于所有块的标签
  • metadata (可选):应用于所有块的元数据

回应:

{
  "success": true,
  "chunk_ids": ["doc:uuid-1", "doc:uuid-2", "doc:uuid-3"],
  "chunks_stored": 3,
  "created_at": "2025-11-30T10:30:00Z"
}

运作原理:

  • 解析markdown文档并提取标题及其层次关系
  • 每个块的格式如下:

- TITLE: 报头前缀(例如。, ##)和标题 - HIERARCHY: 完整的分层路径(例如。, Introduction > Getting Started > Installation) - CONTENT: 本节内容

  • 如果块超过嵌入维度,则会自动细分
  • 所有块共享相同的标签和元数据

块格式示例:

TITLE: ## Installation
HIERARCHY: Getting Started > Installation
CONTENT: To install VectorMind, follow these steps...

用例:

  • 处理具有深层层次结构的文档
  • 通过父子关系维护语义上下文
  • 在特定文档层次结构中搜索
  • 在矢量数据库中保留文档导航结构

备注:此功能是实验性的,块格式可能会在未来的版本中发生变化。

MCP使用

VectorMind公开了以下MCP工具:

1. about_vectormind

提供有关VectorMind MCP服务器的信息。

参数:无

2. create_embedding

使用可选标签和元数据从文本内容创建和存储嵌入。

参数:

  • content (必填):用于创建嵌入的文本内容
  • label (可选):文档的标签/标记
  • metadata (可选):文档的元数据

退货:具有文档ID、内容、标签、元数据和创建时间戳的JSON对象

3. similarity_search

基于文本查询搜索类似文档。返回按相似性排序的文档(最接近的第一个)。

参数:

  • text (必填):搜索类似文档的文本查询
  • max_count (可选):返回的最大结果数(默认值:1)
  • distance_threshold (可选):仅返回距离\ Getting Started > Installation`)

- CONTENT: 本节内容

  • 如果块超过嵌入维度,则会自动细分
  • 所有块共享相同的标签和元数据

块格式示例:

TITLE: ## Installation
HIERARCHY: Getting Started > Installation
CONTENT: To install VectorMind, follow these steps...

用例:

  • 处理具有深层层次结构的文档
  • 通过父子关系维护语义上下文
  • 在特定文档层次结构中搜索
  • 在矢量数据库中保留文档导航结构

备注:此功能是实验性的,块格式可能会在未来的版本中发生变化。

例子

将VectorMind与OpenAI JS SDK结合使用

示例/openai js sdk
import OpenAI from "openai";

// OpenAI Client
const openai = new OpenAI({
	baseURL: "http://localhost:12434/engines/v1",
	apiKey: "i-love-docker-model-runner",
});

const VECTORMIND_API = "http://localhost:8080";

const chunks = [
	`# Orcs
	Orcs are savage, brutish humanoids with dark green skin and prominent tusks. 
	These fierce warriors inhabit dense forests where they hunt in packs, 
	using crude but effective weapons forged from scavenged metal and bone. 
	Their tribal society revolves around strength and combat prowess, 
	making them formidable opponents for any adventurer brave enough to enter their woodland domain.`,

	`# Dragons
	Dragons are magnificent and ancient creatures of immense power, soaring through the skies on massive wings. 
	These intelligent beings possess scales that shimmer like precious metals and breathe devastating elemental attacks. 
	Known for their vast hoards of treasure and centuries of accumulated knowledge, 
	dragons command both fear and respect throughout the realm. 
	Their aerial dominance makes them nearly untouchable in their celestial domain.`,

	`# Goblins
	Goblins are small, cunning creatures with mottled green skin and sharp, pointed ears. 
	Despite their diminutive size, they are surprisingly agile swimmers who have adapted to life around ponds and marshlands. 
	These mischievous beings are known for their quick wit and tendency to play pranks on unwary travelers. 
	They build elaborate underwater lairs connected by hidden tunnels beneath the murky pond waters.`,

	`# Krakens
	Krakens are colossal sea monsters with massive tentacles that can crush entire ships with ease. 
	These legendary creatures dwell in the deepest ocean trenches, surfacing only to hunt or when disturbed. 
	Their intelligence rivals that of the wisest sages, and their tentacles can stretch for hundreds of feet. 
	Sailors speak in hushed tones of these maritime titans, whose very presence can create devastating whirlpools 
	and tidal waves that reshape entire coastlines.`,
];

// Function to create embeddings
async function createEmbedding(content, label = "", metadata = "") {
	const response = await fetch(`${VECTORMIND_API}/embeddings`, {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
		},
		body: JSON.stringify({
			content,
			label,
			metadata,
		}),
	});

	return await response.json();
}

// Function to search for similar documents
async function searchSimilar(text, maxCount = 5, distanceThreshold = 0.7) {
	const response = await fetch(`${VECTORMIND_API}/search`, {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
		},
		body: JSON.stringify({
			text,
			max_count: maxCount,
			distance_threshold: distanceThreshold,
		}),
	});

	return await response.json();
}

let userInput = "Tell me something about the dragons";

try {
	// Create embeddings from chunks
	console.log("Creating embeddings...\n");

	for (const chunk of chunks) {
		const result = await createEmbedding(chunk, "fantasy-creatures", "");
		console.log("Created embedding:", result);
	}

	// Search for similar documents
	console.log("\n\nSearching for similar documents...\n");

	const searchResult = await searchSimilar(userInput, 1, 0.7);
	console.log("Search results:\n", JSON.stringify(searchResult, null, 2));

	const documents = searchResult.results.map(r => r.content).join("\n");

	const completion = await openai.chat.completions.create({
		model: "hf.co/menlo/jan-nano-gguf:q4_k_m",
		messages: [
      { role: "system", content: "Using the following documents:" },
      { role: "system", content: "documents:\n"+ documents },
      { role: "user", content: "userInput" }
    ],
		stream: true,
	});

  console.log("=".repeat);

	for await (const chunk of completion) {
		process.stdout.write(chunk.choices[0].delta.content || "");
	}
} catch (error) {
	console.error("Error:", error);
}

将VectorMind与OpenAI Golang SDK结合使用

样品/openai go sdk
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"

	"github.com/openai/openai-go"
	"github.com/openai/openai-go/option"
)

const VECTORMIND_API = "http://localhost:8080"

// EmbeddingRequest représente la requête pour créer un embedding
type EmbeddingRequest struct {
	Content  string `json:"content"`
	Label    string `json:"label,omitempty"`
	Metadata string `json:"metadata,omitempty"`
}

// EmbeddingResponse représente la réponse de création d'embedding
type EmbeddingResponse struct {
	ID        string `json:"id"`
	Content   string `json:"content"`
	Label     string `json:"label"`
	Metadata  string `json:"metadata"`
	CreatedAt string `json:"created_at"`
	Success   bool   `json:"success"`
}

// SearchRequest représente la requête de recherche
type SearchRequest struct {
	Text              string  `json:"text"`
	MaxCount          int     `json:"max_count,omitempty"`
	DistanceThreshold float64 `json:"distance_threshold,omitempty"`
}

// SearchResult représente un résultat de recherche
type SearchResult struct {
	ID       string  `json:"id"`
	Content  string  `json:"content"`
	Distance float64 `json:"distance"`
}

// SearchResponse représente la réponse de recherche
type SearchResponse struct {
	Results []SearchResult `json:"results"`
	Success bool           `json:"success"`
}

// CreateEmbedding crée un embedding dans VectorMind
func CreateEmbedding(content, label, metadata string) (*EmbeddingResponse, error) {
	reqBody := EmbeddingRequest{
		Content:  content,
		Label:    label,
		Metadata: metadata,
	}

	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("erreur marshaling: %w", err)
	}

	resp, err := http.Post(VECTORMIND_API+"/embeddings", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("erreur requête: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("erreur lecture réponse: %w", err)
	}

	var result EmbeddingResponse
	if err := json.Unmarshal(body, &result); err != nil {
		return nil, fmt.Errorf("erreur unmarshaling: %w", err)
	}

	return &result, nil
}

// SearchSimilar recherche des documents similaires
func SearchSimilar(text string, maxCount int, distanceThreshold float64) (*SearchResponse, error) {
	reqBody := SearchRequest{
		Text:              text,
		MaxCount:          maxCount,
		DistanceThreshold: distanceThreshold,
	}

	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("erreur marshaling: %w", err)
	}

	resp, err := http.Post(VECTORMIND_API+"/search", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("erreur requête: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("erreur lecture réponse: %w", err)
	}

	var result SearchResponse
	if err := json.Unmarshal(body, &result); err != nil {
		return nil, fmt.Errorf("erreur unmarshaling: %w", err)
	}

	return &result, nil
}

func main() {

	baseURL := "http://localhost:12434/engines/llama.cpp/v1/"
	model := "hf.co/menlo/jan-nano-gguf:q4_k_m"

	client := openai.NewClient(
		option.WithBaseURL(baseURL),
		option.WithAPIKey(""),
	)

	ctx := context.Background()

	chunks := []string{
		`# Orcs
		Orcs are savage, brutish humanoids with dark green skin and prominent tusks.
		These fierce warriors inhabit dense forests where they hunt in packs,
		using crude but effective weapons forged from scavenged metal and bone.
		Their tribal society revolves around strength and combat prowess,
		making them formidable opponents for any adventurer brave enough to enter their woodland domain.`,

		`# Dragons
		Dragons are magnificent and ancient creatures of immense power, soaring through the skies on massive wings.
		These intelligent beings possess scales that shimmer like precious metals and breathe devastating elemental attacks.
		Known for their vast hoards of treasure and centuries of accumulated knowledge,
		dragons command both fear and respect throughout the realm.
		Their aerial dominance makes them nearly untouchable in their celestial domain.`,

		`# Goblins
		Goblins are small, cunning creatures with mottled green skin and sharp, pointed ears.
		Despite their diminutive size, they are surprisingly agile swimmers who have adapted to life around ponds and marshlands.
		These mischievous beings are known for their quick wit and tendency to play pranks on unwary travelers.
		They build elaborate underwater lairs connected by hidden tunnels beneath the murky pond waters.`,

		`# Krakens
		Krakens are colossal sea monsters with massive tentacles that can crush entire ships with ease.
		These legendary creatures dwell in the deepest ocean trenches, surfacing only to hunt or when disturbed.
		Their intelligence rivals that of the wisest sages, and their tentacles can stretch for hundreds of feet.
		Sailors speak in hushed tones of these maritime titans, whose very presence can create devastating whirlpools
		and tidal waves that reshape entire coastlines.`,
	}

	// Creation of embeddings
	fmt.Println("Creation of embeddings...")
	for _, chunk := range chunks {
		result, err := CreateEmbedding(chunk, "fantasy-creatures", "")
		if err != nil {
			fmt.Printf("Error when embedding: %v\n", err)
			continue
		}
		fmt.Printf("Embedding created: ID=%s, Success=%v\n", result.ID, result.Success)
	}

	// Search for similar documents
	fmt.Println("\n\nSearch for similar documents...")

	userInput := "Tell me something about the dragons"

	searchResult, err := SearchSimilar(userInput, 2, 0.7)
	if err != nil {
		fmt.Printf("Error search: %v\n", err)
	}

	fmt.Printf("Found: %d\n", len(searchResult.Results))

	var documents string

	for i, result := range searchResult.Results {
		fmt.Printf("  %d. Distance: %.4f\n", i+1, result.Distance)
		fmt.Printf("     ID: %s\n", result.ID)
		fmt.Printf("     Content: %s...\n", result.Content[:50])
		documents += result.Content + "\n"
	}

	fmt.Println(strings.Repeat("-", 50))
	fmt.Println("Chat Completion with retrieved documents as context:")

	messages := []openai.ChatCompletionMessageParamUnion{
		openai.SystemMessage("Using the following documents:"),
		openai.SystemMessage("documents:\n" + documents),
		openai.UserMessage(userInput),
	}

	param := openai.ChatCompletionNewParams{
		Messages:    messages,
		Model:       model,
		Temperature: openai.Opt(0.0),
	}

	stream := client.Chat.Completions.NewStreaming(ctx, param)

	for stream.Next() {
		chunk := stream.Current()
		// Stream each chunk as it arrives
		if len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" {
			fmt.Print(chunk.Choices[0].Delta.Content)
		}
	}

	if err := stream.Err(); err != nil {
		log.Fatalln("Error with the completion:", err)
	}
}

将VectorMind与Golang MCP客户端结合使用

示例/与go-mcp客户端一起使用
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"strings"

	"github.com/mark3labs/mcp-go/client"
	"github.com/mark3labs/mcp-go/client/transport"
	"github.com/mark3labs/mcp-go/mcp"
)

type SearchResult struct {
	ID       string  `json:"id"`
	Content  string  `json:"content"`
	Distance float64 `json:"distance"`
}

type SearchResponse struct {
	Results []SearchResult `json:"results"`
	Success bool           `json:"success"`
}

var chunks = []string{
	`# Orcs
		Orcs are savage, brutish humanoids with dark green skin and prominent tusks.
		These fierce warriors inhabit dense forests where they hunt in packs,
		using crude but effective weapons forged from scavenged metal and bone.
		Their tribal society revolves around strength and combat prowess,
		making them formidable opponents for any adventurer brave enough to enter their woodland domain.`,

	`# Dragons
		Dragons are magnificent and ancient creatures of immense power, soaring through the skies on massive wings.
		These intelligent beings possess scales that shimmer like precious metals and breathe devastating elemental attacks.
		Known for their vast hoards of treasure and centuries of accumulated knowledge,
		dragons command both fear and respect throughout the realm.
		Their aerial dominance makes them nearly untouchable in their celestial domain.`,

	`# Goblins
		Goblins are small, cunning creatures with mottled green skin and sharp, pointed ears.
		Despite their diminutive size, they are surprisingly agile swimmers who have adapted to life around ponds and marshlands.
		These mischievous beings are known for their quick wit and tendency to play pranks on unwary travelers.
		They build elaborate underwater lairs connected by hidden tunnels beneath the murky pond waters.`,

	`# Krakens
		Krakens are colossal sea monsters with massive tentacles that can crush entire ships with ease.
		These legendary creatures dwell in the deepest ocean trenches, surfacing only to hunt or when disturbed.
		Their intelligence rivals that of the wisest sages, and their tentacles can stretch for hundreds of feet.
		Sailors speak in hushed tones of these maritime titans, whose very presence can create devastating whirlpools
		and tidal waves that reshape entire coastlines.`,
}

func main() {

	ctx := context.Background()

	// MCP client initialization
	fmt.Println("🚀 Initializing MCP StreamableHTTP client...")
	// Create HTTP transport
	httpURL := "http://localhost:9090/mcp"
	httpTransport, err := transport.NewStreamableHTTP(httpURL)
	if err != nil {
		log.Fatalf("Failed to create HTTP transport: %v", err)
	}
	// Create client with the transport
	mcpClient := client.NewClient(httpTransport)
	// Start the client
	if err := mcpClient.Start(ctx); err != nil {
		log.Fatalf("Failed to start client: %v", err)
	}

	initRequest := mcp.InitializeRequest{}
	initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
	initRequest.Params.ClientInfo = mcp.Implementation{
		Name:    "MCP-Go Simple Client Example",
		Version: "1.0.0",
	}
	initRequest.Params.Capabilities = mcp.ClientCapabilities{}

	_, err = mcpClient.Initialize(ctx, initRequest)
	if err != nil {
		log.Fatalf("Failed to initialize: %v", err)
	}

	// Tools listing
	toolsRequest := mcp.ListToolsRequest{}
	// Get the list of tools
	toolsResult, err := mcpClient.ListTools(ctx, toolsRequest)
	if err != nil {
		log.Fatalf("Failed to list tools: %v", err)
	}
	fmt.Println("🛠️  Available tools:")
	for _, tool := range toolsResult.Tools {
		fmt.Printf("- %s: %s\n", tool.Name, tool.Description)
	}

	// Create Embeddings with `create_embedding` MCP tool
	fmt.Println("\n\nCreation of embeddings...")
	for _, chunk := range chunks {
		request := mcp.CallToolRequest{
			Params: mcp.CallToolParams{
				Name: "create_embedding",
				Arguments: map[string]any{
					"content":  chunk,
					"label":    "fantasy-creatures",
					"metadata": "",
				},
			},
		}
		toolResponse, err := mcpClient.CallTool(ctx, request)
		if err != nil {
			fmt.Printf("Error when embedding: %v\n", err)
			continue
		}
		if toolResponse == nil || len(toolResponse.Content) == 0 {
			fmt.Printf("No response from embedding tool\n")
			continue
		}
		fmt.Println("🛠️  Tool response:", toolResponse.Content[0].(mcp.TextContent).Text)

	}

	fmt.Println(strings.Repeat("=", 50))
	fmt.Println("Search for similar documents...")

	userInput := "Tell me something about the dragons"

	searchRequest := mcp.CallToolRequest{
		Params: mcp.CallToolParams{
			Name: "similarity_search",
			Arguments: map[string]any{
				"text":               userInput,
				"max_count":          2,
				"distance_threshold": 0.7,
			},
		},
	}
	searchResponse, err := mcpClient.CallTool(ctx, searchRequest)
	if err != nil {
		log.Fatalf("Error search: %v", err)
	}
	if searchResponse == nil || len(searchResponse.Content) == 0 {
		log.Fatalf("No response from search tool")
	}

	searchResult := searchResponse.Content[0].(mcp.TextContent).Text

	// Parse the JSON response
	var response SearchResponse
	err = json.Unmarshal([]byte(searchResult), &response)
	if err != nil {
		log.Fatalf("Error parsing search result: %v", err)
	}

	// Loop through results
	fmt.Println("\n📋 Search Results:")
	for _, result := range response.Results {
		fmt.Printf("\nID: %s\n", result.ID)
		fmt.Printf("Distance: %f\n", result.Distance)
		fmt.Printf("Content: %s\n", result.Content)
		fmt.Println(strings.Repeat("-", 50))
	}
}

开发和测试

VectorMind 使用基于以下内容的本地CI管道 Docker Compose 包含以下文件:

  • 主管道: compose.ci.yml
  • compose.ci.redis-test-server.yml
  • compose.ci.unit-tests.yml
  • compose.ci.multi-arch-build.yml
  • compose.ci.start-vectormind.yml
  • compose.ci.get-model-info.yml
  • compose.ci.create-embeddings.yml
  • compose.ci.search-embeddings.yml
  • compose.ci.stop-vectormind.yml
  • compose.ci.stop-redis.yml

启动CI管道:

docker compose -f compose.ci.yml up --remove-orphans --build

停止CI管道(以干净的方式):

docker compose -f compose.ci.yml down

本地CI管道

本地CI管道使用Docker Compose进行编排,并遵循以下工作流程:

graph TD
    Start([Start CI Pipeline]):::startNode

    Start --> Redis[redis-test-server
Redis Server]:::service
    Start --> UnitTests[unit-tests
Run Unit Tests]:::test

    UnitTests -->|success| MultiBuild[multi-arch-build
Multi-Architecture Build]:::build

    MultiBuild -->|success| StartVM[start-vectormind
Start VectorMind Service]:::service
    Redis --> StartVM

    StartVM -->|healthy| GetModelInfo[get-model-info
Get Embedding Model Info]:::test

    GetModelInfo -->|success| CreateEmb[create-embeddings
Create Test Embeddings]:::test

    StartVM -->|healthy| SearchEmb[search-embeddings
Search Embeddings]:::test

    CreateEmb -->|success| SearchEmb

    SearchEmb -->|success| StopVM[stop-vectormind
Stop VectorMind]:::cleanup

    StopVM -->|success| StopRedis[stop-redis
Stop Redis Server]:::cleanup

    StopRedis --> Complete([Pipeline Complete]):::endNode

    classDef startNode fill:#10B981,stroke:#059669,stroke-width:2px,color:#fff
    classDef service fill:#3B82F6,stroke:#2563EB,stroke-width:2px,color:#fff
    classDef test fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#fff
    classDef build fill:#8B5CF6,stroke:#7C3AED,stroke-width:2px,color:#fff
    classDef cleanup fill:#EF4444,stroke:#DC2626,stroke-width:2px,color:#fff
    classDef endNode fill:#6B7280,stroke:#4B5563,stroke-width:2px,color:#fff

管道阶段

  1. redis测试服务器:启动Redis服务器进行测试
  2. 单元测试:在短模式下运行单元测试
  3. 连拱结构:构建多架构Docker镜像(取决于单元测试的成功)
  4. 启动矢量风暴:启动VectorMind服务(取决于多拱形构建成功和redis测试服务器)
  5. 获取模型信息:获取嵌入模型信息(取决于start vectormind是否正常)
  6. 创建嵌入:创建测试嵌入(取决于启动vectormind是否正常并成功获取模型信息)
  7. 搜索嵌入:测试嵌入搜索功能(取决于创建嵌入成功和启动vectormind健康)
  8. 停止矢量风暴:停止VectorMind服务(取决于搜索嵌入是否成功)
  9. 停止redis:停止Redis服务器(取决于停止vectormind的成功)

目录标签

目录标签

搜索向量数据库GoAPI集成语义搜索本地部署RedisRESTAPIMCP协议

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

none

工具数量(toolCount,工具数)

9

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明none部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP