本文将剖析 Claude Context Chrome 扩展的技术架构,重点解析其如何将核心的 Milvus 向量数据库能力适配到浏览器环境。核心方案是构建一个基于 RESTful API 的 MilvusRestfulVectorDatabase 轻量实现(milvus-vectordb-stub.ts),并通过 ChromeMilvusAdapter 进行封装。同时,通过 webpack.config.js 中的精细配置,为 Node.js 专有模块提供 Polyfill,确保代码能在浏览器中运行。文章将结合 background.ts 中的 cosSim 函数等关键代码,阐述从嵌入生成、代码分割到向量搜索的完整工作流。
Claude Context Chrome 扩展技术架构:Milvus RESTful 适配与浏览器兼容
Chrome 扩展的沙箱环境与 Node.js 存在根本差异,无法直接使用 @zilliz/claude-context-core 中依赖 Node.js 原生模块(如 grpc)的向量数据库驱动。Claude Context Chrome 扩展的技术挑战,在于将基于 Milvus 的语义搜索能力完整地移植到浏览器中。其解决方案是构建一套纯前端的 Milvus RESTful 适配层,并通过构建工具进行必要的环境兼容。
核心工作流与关键组件
扩展的背景脚本 background.ts 是整个逻辑的枢纽,它协调了从 GitHub 仓库代码获取、代码分割、嵌入生成到 Milvus 存储与查询的全过程。
1. 代码分割与嵌入生成
在 background.ts 中,splitCode 函数负责将源代码文本分割成适合嵌入的片段。它采用了一种近似于 LangChain RecursiveCharacterTextSplitter 的字符级分割策略,主要依据字符长度(默认 chunkSize = 1000,chunkOverlap = 200)而非语法结构。这确保了分割逻辑在浏览器环境中的轻量与一致性。
// background.ts 中的分割函数
function splitCode(content: string, language: string = '', chunkSize: number = 1000, chunkOverlap: number = 200): { content: string; startLine: number; endLine: number }[] {
// ... 基于行和字符的分割逻辑
}
分割后的代码片段需要转换为向量。EmbeddingModel 类直接在浏览器中调用 OpenAI API,它通过 fetch 与 https://api.openai.com/v1/embeddings 端点通信,避免了任何 Node.js 的依赖。该类以批处理方式(EMBEDDING_BATCH_SIZE = 100)发送请求,优化了 API 调用效率。
// background.ts 中的嵌入模型类
class EmbeddingModel {
// ... 使用 fetch 直接调用 OpenAI API
static async embedBatch(texts: string[]): Promise<number[][]> {
const response = await fetch('https://api.openai.com/v1/embeddings', { ... });
// ...
}
}
2. 向量相似度计算:cosSim 函数
搜索时,需要计算查询向量与存储向量之间的余弦相似度。background.ts 中定义了一个纯 JavaScript 实现的 cosSim 函数,避免了依赖外部数学库。
// background.ts 中的余弦相似度计算
function cosSim(a: number[], b: number[]): number {
let dot = 0;
let normA = 0;
let normB = 0;
const len = Math.min(a.length, b.length);
for (let i = 0; i < len; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
if (normA === 0 || normB === 0) {
return 0;
}
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}
此函数虽然在 background.ts 中定义,但其计算逻辑与 milvus-vectordb-stub.ts 中 Milvus 搜索返回距离(distance)到相似度(score)的转换逻辑(score: 1 - distance)保持一致,共同确保了搜索结果的相关性排序准确。关于向量数据库的更多实现细节,可以参考 Claude Context 向量数据库实现:Milvus gRPC 与 RESTful 双引擎。
Milvus RESTful 适配层:ChromeMilvusAdapter 与 milvus-vectordb-stub
这是整个架构的核心创新。为了在浏览器中与 Milvus 交互,项目绕开了 Node.js 的 gRPC 驱动,转而实现了完整的 RESTful API 客户端。
milvus-vectordb-stub.ts 文件提供了一个完整的 MilvusRestfulVectorDatabase 类。它通过浏览器原生的 fetch API 与 Milvus 的 /v2/vectordb 端点通信,支持集合的创建、删除、数据插入和向量搜索。其 search 方法在返回结果前,会确保按相似度得分降序排序。
// milvus-vectordb-stub.ts 中的关键实现
export class MilvusRestfulVectorDatabase {
private baseUrl: string;
constructor(config: MilvusRestfulConfig) {
// 构建基础URL,确保以 /v2/vectordb 结尾
this.baseUrl = address.replace(/\/$/, '') + '/v2/vectordb';
}
async search(collectionName: string, queryVector: number[], options?: SearchOptions): Promise<VectorSearchResult[]> {
// ... 调用 /entities/search
// 将返回的 distance 转换为相似度 score
score: Math.max(0, Math.min(1, 1 - (item.distance || 1)))
// ... 最终按 score 降序排序
const sortedResults = filteredResults.sort((a, b) => b.score - a.score);
}
}
ChromeMilvusAdapter 则是面向 background.ts 的封装层。它将扩展特定的配置管理(MilvusConfigManager)与核心的 MilvusRestfulVectorDatabase 连接起来,提供了更符合扩展上下文的接口,如 insertChunks 和 searchSimilar。它在搜索后也进行了二次排序,双重保障结果顺序。
// chromeMilvusAdapter.ts 中的适配器
export class ChromeMilvusAdapter {
private milvusDb: MilvusRestfulVectorDatabase | null = null;
// ...
async searchSimilar(queryVector: number[], limit: number = 10, threshold: number = 0.3): Promise<SearchResult[]> {
const results = await this.milvusDb.search(this.collectionName, queryVector, searchOptions);
// 转换格式并再次排序
searchResults.sort((a, b) => b.score - a.score);
return searchResults;
}
}
浏览器环境兼容:Webpack Polyfill 配置
即使是使用了 fetch 替代 grpc,扩展的依赖库中可能仍包含对 Node.js 内置模块(如 crypto, path, vm)的引用。webpack.config.js 通过 resolve.fallback 和插件机制,为这些模块提供了浏览器兼容的替代品或空实现。
// webpack.config.js 中的 fallback 配置
resolve: {
fallback: {
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"buffer": require.resolve("buffer"),
"path": require.resolve("path-browserify"),
"vm": false, // 直接禁用 vm 模块
// ... 其他模块配置
}
},
plugins: [
// 将 vm 模块的引用替换为空桩文件
new webpack.NormalModuleReplacementPlugin(
/^vm$/,
require.resolve('./src/vm-stub.js')
)
]
关键配置包括:
"vm": false:直接禁用vm模块,这对于某些依赖环境检测的库是必要的。new webpack.NormalModuleReplacementPlugin(... vm ...):通过插件将任何import vm from 'vm'的语句重定向到一个空的桩文件./src/vm-stub.js,彻底避免运行时错误。- 其他模块如
crypto,path,zlib均通过crypto-browserify,path-browserify,browserify-zlib等社区提供的同构库进行填充。
这些配置共同构成了扩展在浏览器中稳定运行的基础。如果你想了解 Claude Context 更广泛的整体架构,包括其核心引擎的设计,可以阅读 Claude Context 核心引擎深度解析:嵌入、向量数据库与代码分割架构。
FAQ
Q: 如何验证 Chrome 扩展与 Milvus 服务器的连接是否正常?
A: 在扩展的选项页面通常会提供一个“测试连接”按钮。点击后,background.ts 会调用 handleTestMilvusConnection 方法,该方法会实例化一个 ChromeMilvusAdapter 并执行 testConnection 检查,最终向界面返回连接成功或具体的错误信息(如网络问题、认证失败、CORS 限制等)。
Q: 搜索结果的相关性分数(score)是如何计算的?
A: 相关性分数基于余弦相似度。首先,background.ts 中的 cosSim 函数用于计算本地向量间的相似度。同时,milvus-vectordb-stub.ts 在从 Milvus REST API 获取搜索结果时,会将返回的“距离”(distance)转换为相似度,公式为 score = 1 - distance。两种方式在数学上是等价的,确保了结果排序的一致性。
Q: 为什么选择 RESTful API 而非 WebSocket 与 Milvus 交互?
A: 浏览器环境对原生 TCP/UDP 连接的限制严格,而基于 HTTP 的 RESTful API 兼容性最好,可以无缝使用浏览器的 fetch API。同时,Milvus 官方提供了完整的 RESTful 端点(/v2/vectordb),能够支持扩展所需的所有集合管理和数据操作功能。