跳转到内容

知识管理

2 篇包含标签 "知识管理" 的文章

用 Vault 系统构建 AI 时代的跨项目知识库

用 Vault 系统构建 AI 时代的跨项目知识库

Section titled “用 Vault 系统构建 AI 时代的跨项目知识库”

临摹项目学习法正在成为主流,只是学习资料分散、上下文断裂的痛点让 AI 助手难以发挥最大价值。本文介绍 HagiCode 项目的 Vault 系统设计——通过统一的存储抽象层,让 AI 助手能够理解和访问所有学习资源,实现真正的跨项目知识复用。

其实,在 AI 时代,我们学习新技术的方式正在悄然改变。传统的读书、看视频固然重要,但”临摹项目”——深入研究和学习优秀开源项目的代码、架构和设计模式——确实越来越高效。直接运行和修改高质量的开源项目,能让你最快理解真实世界的工程实践。

只是这种方式也带来了新的挑战。

学习资料太分散。笔记可能在 Obsidian 里,代码仓库散落在各个文件夹,AI 助手的对话历史又是一个独立的数据孤岛。每次需要 AI 帮助分析某个项目时,都得手动复制代码片段、整理上下文,过程相当繁琐。

上下文经常断掉。AI 助手无法直接访问本地学习资源,每次对话都得重新提供背景信息。临摹的代码仓库更新快,手动同步容易出错。更糟的是,多个学习项目之间难以共享知识——在 A 项目中学到的设计模式,AI 处理 B 项目时完全不知道。

这些问题的本质是”数据孤岛”。如果能有一个统一的存储抽象层,让 AI 助手能够理解和访问所有学习资源,问题就迎刃而解了。

为了解决这些痛点,我们在开发 HagiCode 时做了一个关键的设计决策:构建一个 Vault 系统作为统一的知识存储抽象层。这个决定带来的变化,可能比想象的还要大——稍后具体说。

本文分享的方案来自在 HagiCode 项目中的实践经验。HagiCode 是一个基于 OpenSpec 工作流的 AI 代码助手,它的核心理念是让 AI 不仅会”说”,更会”做”——能够直接操作代码仓库、执行命令、运行测试。GitHub:github.com/HagiCode-org/site

在开发过程中,我们发现 AI 助手需要频繁访问用户的各类学习资源:代码仓库、笔记文档、配置文件等。如果每次都要用户手动提供,体验就太糟糕了。这促使设计了 Vault 系统。

HagiCode 的 Vault 系统支持四种类型,分别对应不同的使用场景:

类型用途典型场景
folder通用文件夹类型临时学习资料、草稿
coderef专门用于临摹代码项目系统化学习某个开源项目
obsidian与 Obsidian 笔记软件集成现有笔记库的复用
system-managed系统自动管理项目配置、提示词模板等

其中 coderef 类型是 HagiCode 中最常用的,它为临摹代码项目提供了标准化的目录结构和 AI 可读的元数据描述。为什么要专门设计这个类型?因为临摹一个开源项目不是简单的”下载代码”,需要同时管理代码本身、学习笔记、配置文件等多种内容,coderef 把这些都规范好了。

Vault 的注册表以 JSON 格式持久化存储到文件系统:

_registryFilePath = Path.Combine(absoluteDataDir, "personal-data", "vaults", "registry.json");

这个设计看似简单,实则经过深思熟虑:

简单可靠。JSON 格式人类可读,便于调试和手动修改。当系统出现问题时,可以直接打开文件查看状态,甚至手动修复——这在开发阶段特别有用。

降低依赖。文件系统存储避免了数据库的复杂性。不需要额外安装和配置数据库服务,降低了系统复杂度和维护成本。

并发安全。使用 SemaphoreSlim 确保多线程安全。在 AI 代码助手的场景下,可能会有多个操作同时访问 vault 注册表,需要做好并发控制。

系统的核心能力在于能够自动将 vault 信息注入到 AI 提案的上下文中:

export function buildTargetVaultsText(
vaults: VaultForText[],
template: VaultPromptTemplate = DEFAULT_VAULT_PROMPT_TEMPLATE,
): string {
const readOnlyVaults = vaults.filter((vault) => vault.accessType === 'read');
const editableVaults = vaults.filter((vault) => vault.accessType === 'write');
const sections = [
buildVaultSection(readOnlyVaults, template.reference),
buildVaultSection(editableVaults, template.editable),
].filter(Boolean);
return `\n\n### ${template.heading}\n\n${sections.join('\n')}`;
}

这样 AI 助手就能自动理解可用的学习资源,无需用户每次手动提供上下文。这个设计让 HagiCode 的体验变得特别自然——告诉 AI “帮我分析 React 的并发渲染”,AI 就能自动找到之前注册的 React 学习 vault,而不是一遍遍贴代码。

系统将 vault 分为两种访问类型:

  • reference(只读):AI 仅用于分析和理解,不能修改内容
  • editable(可编辑):AI 可以根据任务需要修改内容

这种区分让 AI 知道哪些内容是”只读参考”,哪些是”可以动手改的”,避免了误操作风险。比如注册了一个开源项目的 vault 作为学习材料,肯定不希望 AI 随手修改里面的代码——那就标记为 reference。但如果是自己的项目 vault,就可以标记为 editable,让 AI 帮着改代码。

对于 coderef 类型的 vault,系统提供了一套标准化的目录结构:

my-coderef-vault/
├── index.yaml # vault 元数据描述
├── AGENTS.md # AI 助手的操作指南
├── docs/ # 存放学习笔记和文档
└── repos/ # 通过 Git 子模块管理临摹的代码仓库

这个结构的设计理念是什么?

docs/ 存放学习笔记,用 Markdown 格式记录对代码的理解、架构分析、踩坑经验。这些笔记不仅自己看,AI 也能读懂——在处理相关任务时会自动参考。

repos/ 通过 Git 子模块管理临摹的仓库,而不是直接复制代码。这样做有两个好处:一是保持与上游同步,一个 git submodule update 就能拿到最新代码;二是节省空间,多个 vault 可以引用同一个仓库的不同版本。

index.yaml 包含 vault 的元数据,让 AI 助手快速理解用途和内容。相当于给 vault 写了个”自我介绍”,AI 第一次见到就知道这是干嘛的。

AGENTS.md 是专门写给 AI 助手看的指南,说明如何处理 vault 中的内容。可以在这里告诉 AI:“分析这个项目时重点关注性能优化相关的代码”或者”不要修改测试文件”。

创建一个 CodeRef vault 很简单:

const createCodeRefVault = async () => {
const response = await VaultService.postApiVaults({
requestBody: {
name: "React Learning Vault",
type: "coderef",
physicalPath: "/Users/developer/vaults/react-learning",
gitUrl: "https://github.com/facebook/react.git"
}
});
// 系统会自动:
// 1. 克隆 React 仓库到 vault/repos/react
// 2. 创建 docs/ 目录用于笔记
// 3. 生成 index.yaml 元数据
// 4. 创建 AGENTS.md 指南文件
return response;
};

然后在 AI 提案中引用这个 vault:

const proposal = composeProposalChiefComplaint({
chiefComplaint: "帮我分析 React 的并发渲染机制",
repositories: [
{ id: "react", gitUrl: "https://github.com/facebook/react.git" }
],
vaults: [
{
id: "react-learning",
name: "React Learning Vault",
type: "coderef",
physicalPath: "/vaults/react-learning",
accessType: "read" // AI 只能读取,不能修改
}
],
quickRequestText: "重点关注 fiber 架构和 scheduler 实现"
});

场景一:系统化学习开源项目

创建一个 CodeRef vault,通过 Git 子模块管理目标仓库,在 docs/ 目录记录学习笔记。AI 可以同时访问代码和笔记,提供更精准的分析。在学习某个模块时写的笔记,AI 后续分析相关代码时会自动参考——就像有个”助手”记住了之前的思考。

场景二:复用 Obsidian 笔记库

如果已经在用 Obsidian 管理笔记,直接把现有的 vault 注册到 HagiCode 中就行。AI 可以直接访问知识库,无需手动复制粘贴。这个功能特别实用,很多人都有积累多年的笔记库,接入之后 AI 就能”读”懂知识体系。

场景三:跨项目知识复用

多个 AI 提案可以引用同一个 vault,实现知识的跨项目复用。比如创建了一个”设计模式学习 vault”,里面记录了各种设计模式的笔记和代码示例。无论在分析哪个项目,AI 都能参考这个 vault 中的内容——知识不用重复积累。

系统严格校验路径,防止路径穿越攻击:

private static string ResolveFilePath(string vaultRoot, string relativePath)
{
var rootPath = EnsureTrailingSeparator(Path.GetFullPath(vaultRoot));
var combinedPath = Path.GetFullPath(Path.Combine(rootPath, relativePath));
if (!combinedPath.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
{
throw new BusinessException(VaultRelativePathTraversalCode,
"Vault file paths must stay inside the registered vault root.");
}
return combinedPath;
}

这确保了所有文件操作都在 vault 的根目录范围内,防止恶意路径访问。安全这块不能马虎,AI 助手要操作文件系统,必须把边界划清楚。

使用 HagiCode Vault 系统时,有几点需要特别注意:

  1. 路径安全:确保自定义路径在允许的范围内,否则系统会拒绝操作。这是为了防止误操作和潜在的安全风险。

  2. Git 子模块管理:CodeRef vault 推荐使用 Git 子模块而非直接复制代码。好处前面说过——保持同步、节省空间。只是子模块有自己的使用方式,第一次使用可能需要熟悉一下。

  3. 文件预览限制:系统限制文件大小(256KB)和数量(500个),超大文件需分批处理。这个限制是为了性能考虑,如果遇到超大文件,可以手动拆分或者用其他方式处理。

  4. 诊断信息:创建 vault 会返回诊断信息,失败时可用于调试。遇到问题时先看诊断信息,大部分情况下都能找到线索。

HagiCode 的 Vault 系统本质上是在解决一个简单但深刻的问题:如何让 AI 助手理解和使用本地知识资源。

通过统一的存储抽象层、标准化的目录结构、自动化的上下文注入,实现了”一次注册,处处复用”的知识管理方式。创建一个 vault 后,无论是学习笔记、代码仓库还是文档资料,AI 都能自动访问和理解。

这种设计带来的体验提升是明显的。不再需要手动复制代码片段、重复解释背景信息——AI 助手就像一个真正了解项目情况的同事,能够基于已有知识提供更有价值的帮助。

本文分享的 Vault 系统,正是开发 HagiCode 过程中实际踩坑、实际优化出来的方案。如果觉得这套设计有价值,说明工程实力还不错——那么 HagiCode 本身也值得关注一下。

如果本文对你有帮助:

公测已开始,欢迎安装体验。

感谢您的阅读,如果您觉得本文有用,欢迎点赞、收藏和分享支持。 本内容采用人工智能辅助协作,最终内容由作者审核并确认。

AI时代如何临摹项目:Vault跨项目持久化存储系统

AI时代如何临摹项目:Vault跨项目持久化存储系统

Section titled “AI时代如何临摹项目:Vault跨项目持久化存储系统”

在AI辅助开发时代,如何让AI助手更好地理解我们的学习资源?HagiCode项目通过Vault系统实现了一个统一的、可被AI理解的知识存储抽象层,让临摹项目的学习效率大幅提升。

在AI时代,开发者学习新技术和架构的方式正在发生深刻变化。“临摹项目”——即深入研究和学习优秀开源项目的代码、架构和设计模式——已经成为一种高效的学习方法。相比传统的读书、看视频,直接阅读和运行高质量的开源项目能让你更快地理解真实世界的工程实践。

只是这种学习方式也面临着不少挑战。

学习资料太分散了。你的笔记可能在Obsidian里,代码仓库散落在各个文件夹,AI助手的对话历史又是一个独立的数据孤岛。当你想让AI帮你分析某个项目时,得手动复制代码片段、整理上下文,这个过程相当繁琐。

其实更麻烦的是上下文断裂。AI助手无法直接访问你的本地学习资源,每次对话都得重新提供背景信息。而且临摹的代码仓库更新很快,手动同步容易出错,多个学习项目之间也难以共享知识。

这些问题本质上都是”数据孤岛”导致的。如果能有一个统一的存储抽象层,让AI助手能够理解和访问你的所有学习资源,问题就迎刃而解了。

本文分享的Vault系统,正是我们在开发 HagiCode 过程中实践出来的解决方案。HagiCode 是一个AI代码助手项目,在我们的日常开发中,经常需要学习和参考各种开源项目。为了让AI助手更好地理解这些学习资源,我们设计了Vault跨项目持久化存储系统。

这套方案已经在HagiCode中经过了实际验证,如果你也面临类似的知识管理难题,希望这些经验能给你一些启发。毕竟,有些坑踩过了,总得留下点什么给后来的人。

Vault系统的核心思想很简单:创建一个统一的、可被AI理解的知识存储抽象层。从实现角度来看,系统具有几个关键特征。

系统支持四种vault类型,分别对应不同的使用场景:

// folder:通用文件夹类型
export const DEFAULT_VAULT_TYPE = 'folder';
// coderef:专门用于临摹代码项目的类型
export const CODEREF_VAULT_TYPE = 'coderef';
// obsidian:与Obsidian笔记软件集成
export const OBSIDIAN_VAULT_TYPE = 'obsidian';
// system-managed:系统自动管理的vault
export const SYSTEM_MANAGED_VAULT_TYPE = 'system-managed';

其中 coderef 类型是HagiCode中最常用的。它专门为临摹代码项目设计,提供了标准化的目录结构和AI可读的元数据描述。

Vault的注册表以JSON格式持久化存储,确保配置在应用重启后仍然可用:

public class VaultRegistryStore : IVaultRegistryStore
{
private readonly string _registryFilePath;
public VaultRegistryStore(IConfiguration configuration, ILogger<VaultRegistryStore> logger)
{
var dataDir = configuration["DataDir"] ?? "./data";
var absoluteDataDir = Path.IsPathRooted(dataDir)
? dataDir
: Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), dataDir));
_registryFilePath = Path.Combine(absoluteDataDir, "personal-data", "vaults", "registry.json");
}
}

这种设计的好处是简单可靠。JSON格式人类可读,便于调试和手动修改;文件系统存储避免了数据库的复杂性,降低了系统的依赖。毕竟,有时候简单的反而是最好的。

最关键的是,系统能够自动将vault信息注入到AI提案的上下文中:

export function buildTargetVaultsText(
vaults: VaultForText[],
template: VaultPromptTemplate = DEFAULT_VAULT_PROMPT_TEMPLATE,
): string {
const readOnlyVaults = vaults.filter((vault) => vault.accessType === 'read');
const editableVaults = vaults.filter((vault) => vault.accessType === 'write');
if (readOnlyVaults.length === 0 && editableVaults.length === 0) {
return '';
}
const sections = [
buildVaultSection(readOnlyVaults, template.reference),
buildVaultSection(editableVaults, template.editable),
].filter(Boolean);
return `\n\n### ${template.heading}\n\n${sections.join('\n')}`;
}

这样就实现了一个重要的功能:AI助手能够自动理解可用的学习资源,无需用户手动提供上下文。这倒也算是一种默契了。

对于coderef类型的vault,HagiCode提供了一套标准化的目录结构:

my-coderef-vault/
├── index.yaml # vault元数据描述
├── AGENTS.md # AI助手的操作指南
├── docs/ # 存放学习笔记和文档
└── repos/ # 通过Git子模块管理临摹的代码仓库

创建vault时,系统会自动初始化这个结构:

private async Task EnsureCodeRefStructureAsync(
string vaultName,
string physicalPath,
ICollection<VaultBootstrapDiagnosticDto> diagnostics,
CancellationToken cancellationToken)
{
Directory.CreateDirectory(physicalPath);
var indexPath = Path.Combine(physicalPath, CodeRefIndexFileName);
var docsPath = Path.Combine(physicalPath, CodeRefDocsDirectoryName);
var reposPath = Path.Combine(physicalPath, CodeRefReposDirectoryName);
// 创建标准目录结构
if (!Directory.Exists(docsPath))
{
Directory.CreateDirectory(docsPath);
}
if (!Directory.Exists(reposPath))
{
Directory.CreateDirectory(reposPath);
}
// 创建AGENTS.md指南
await EnsureCodeRefAgentsDocumentAsync(physicalPath, cancellationToken);
// 创建index.yaml元数据
await WriteCodeRefIndexDocumentAsync(indexPath, mergedDocument, cancellationToken);
}

这套结构的设计也是有讲究的:

  • docs/ 目录存放你的学习笔记,可以用Markdown格式记录对代码的理解、架构分析、踩坑经验等
  • repos/ 目录通过Git子模块管理临摹的仓库,而不是直接复制代码。这样既能保持代码同步,又能节省空间
  • index.yaml 包含vault的元数据,让AI助手快速理解这个vault的用途和内容
  • AGENTS.md 是专门写给AI助手看的指南,说明如何处理这个vault中的内容

或许这样组织起来,AI也能更容易理解你的想法吧。

除了手动创建vault,HagiCode还支持系统自动管理的vault:

public async Task<IReadOnlyList<VaultRegistryEntry>> EnsureAllSystemManagedVaultsAsync(
CancellationToken cancellationToken = default)
{
var definitions = GetAllResolvedDefinitions();
var entries = new List<VaultRegistryEntry>(definitions.Count);
foreach (var definition in definitions)
{
entries.Add(await EnsureResolvedSystemManagedVaultAsync(definition, cancellationToken));
}
return entries;
}

系统会自动创建和管理以下vault:

  • hagiprojectdata:项目数据存储,用于保存项目的配置和状态
  • personaldata:个人数据存储,用于保存用户的偏好设置
  • hbsprompt:提示词模板库,用于管理常用的AI提示词

这些vault在系统启动时自动初始化,无需用户手动配置。毕竟,有些事情交给系统去做就好了,人类何必操心呢。

一个重要的设计是访问控制。系统将vault分为两种访问类型:

export interface VaultForText {
id: string;
name: string;
type: string;
physicalPath: string;
accessType: 'read' | 'write'; // 关键:区分只读和可编辑
}
  • reference(只读):AI仅用于分析和理解,不能修改内容。适用于参考的开源项目、文档等
  • editable(可编辑):AI可以根据任务需要修改内容。适用于你的笔记、草稿等

这种区分很重要。它让AI知道哪些内容是”只读参考”,哪些是”可以动手改的”,避免了误操作风险。毕竟,谁也不想自己的心血被无意中改没了。

看完了原理,咱们来看看实际怎么用。

以下是一个完整的前端调用示例:

const createCodeRefVault = async () => {
const response = await VaultService.postApiVaults({
requestBody: {
name: "React Learning Vault",
type: "coderef",
physicalPath: "/Users/developer/vaults/react-learning",
gitUrl: "https://github.com/facebook/react.git"
}
});
// 系统会自动:
// 1. 克隆React仓库到vault/repos/react
// 2. 创建docs/目录用于笔记
// 3. 生成index.yaml元数据
// 4. 创建AGENTS.md指南文件
return response;
};

这个API调用会完成一系列操作:创建目录结构、初始化Git子模块、生成元数据文件等。你只需要提供基本信息,剩下的交给系统处理。其实这样也挺省心的。

创建好vault后,就可以在AI提案中引用它了:

const proposal = composeProposalChiefComplaint({
chiefComplaint: "帮我分析React的并发渲染机制",
repositories: [
{ id: "react", gitUrl: "https://github.com/facebook/react.git" }
],
vaults: [
{
id: "react-learning",
name: "React Learning Vault",
type: "coderef",
physicalPath: "/vaults/react-learning",
accessType: "read" // AI只能读取,不能修改
}
],
quickRequestText: "重点关注fiber架构和scheduler实现"
});

系统会自动将vault信息注入到AI的上下文中,让AI知道你有哪些学习资源可用。AI能理解你的想法,这倒也算是一种难得的默契了。

在使用Vault系统的过程中,我们总结了一些经验教训。

系统会严格校验路径,防止路径穿越攻击:

private static string ResolveFilePath(string vaultRoot, string relativePath)
{
var rootPath = EnsureTrailingSeparator(Path.GetFullPath(vaultRoot));
var combinedPath = Path.GetFullPath(Path.Combine(rootPath, relativePath));
if (!combinedPath.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
{
throw new BusinessException(VaultRelativePathTraversalCode,
"Vault file paths must stay inside the registered vault root.");
}
return combinedPath;
}

这点很重要。如果你在自定义vault路径,一定要确保路径在允许的范围内,否则系统会拒绝操作。安全这东西,怎么强调都不过分。

CodeRef vault推荐使用Git子模块而非直接复制代码:

private static string BuildCodeRefAgentsContent()
{
return """
# CodeRef Vault Guide
Repositories under `repos/` should be maintained through Git submodules
rather than copied directly into the vault root.
Keep this structure stable so assistants and tools can understand the vault quickly.
""" + Environment.NewLine;
}

这样做有几个好处:保持代码与上游同步、节省磁盘空间、便于管理多个版本的代码。毕竟,谁愿意一遍遍地重复下载同样的东西呢。

为了防止性能问题,系统限制了文件大小和类型:

private const int FileEnumerationLimit = 500;
private const int PreviewByteLimit = 256 * 1024; // 256KB

如果你的vault包含大量文件或超大文件,可能会影响预览功能的性能。这种情况下可以考虑分批处理或使用专门的搜索工具。毕竟,有些东西太大了,反而不好处理。

创建vault时会返回诊断信息,帮助调试:

List<VaultBootstrapDiagnosticDto> bootstrapDiagnostics = [];
if (IsCodeRefVaultType(normalizedType))
{
bootstrapDiagnostics = await EnsureCodeRefBootstrapAsync(
normalizedName,
normalizedPhysicalPath,
normalizedGitUrl,
cancellationToken);
}

如果创建失败,可以查看诊断信息了解具体原因。出错了就看看诊断信息,这倒也是一种解决问题的方法。

Vault系统通过统一的存储抽象层,解决了AI时代临摹项目的核心痛点:

  • 知识集中管理:所有学习资源集中在一个地方,不再散落各处
  • AI上下文自动注入:AI助手能够自动理解可用的学习资源,无需手动提供上下文
  • 跨项目知识复用:多个学习项目之间可以共享和复用知识
  • 标准化目录结构:提供一致的目录结构,降低学习成本

这套方案在HagiCode项目中已经经过了实际验证。如果你也在做AI辅助开发相关的工具,或者面临类似的知识管理问题,希望这些经验能给你一些参考。

其实技术方案的价值不在于有多复杂,而在于能不能解决实际问题。Vault系统的核心思想很简单——就是建立一个统一的、AI可理解的知识存储层。但正是这个简单的抽象,让我们的开发效率提升了不少。

有时候,简单的反而是最好的。毕竟,复杂的东西往往藏着更多的坑…


如果本文对你有帮助,欢迎来 GitHub 给个 Star,或者访问官网了解更多关于HagiCode的信息。公测已开始,现在安装即可体验完整的AI代码助手功能。

或许,你也可以试试看…

感谢您的阅读,如果您觉得本文有用,欢迎点赞、收藏和分享支持。 本内容采用人工智能辅助协作,最终内容由作者审核并确认。