@backendkit-labs/代理企业
企业级AI代理 与RAG( Retrival-Augmented Generation) 在一个 Obsidian 保险库上设置, 六个预配置的部门代理简介, 一个金库的写作工具, 以及一个把所有东西都连接到一个工厂 AgentEngine- 相容的设定.
状态 :
core——企业使用案例要求. 在合并之前,要经过全面审查才能打破这些变化.
目录
安装
npm install @backendkit-labs/agent-enterprise @backendkit-labs/agent-core
对于完整的网页堆栈 :
npm install @backendkit-labs/agent-enterprise @backendkit-labs/agent-core @backendkit-labs/agent-web
快开始
import { createEnterpriseSetup } from '@backendkit-labs/agent-enterprise';
import { ProviderRegistry } from '@backendkit-labs/agent-core';
import { AgentServer } from '@backendkit-labs/agent-web';
// 1. Configure your LLM providers
const providers = new ProviderRegistry();
providers.register('openai', myOpenAIProvider);
// 2. Create the enterprise setup
const enterprise = createEnterpriseSetup({
vaultPath: '/shared/obsidian-vault',
providers,
defaultProvider: 'openai',
});
// 3. Index the vault (once at startup — subsequent runs only re-index changed files)
await enterprise.indexAll({ verbose: true });
// 4. Start the web server
const server = new AgentServer({
port: 3000,
engineFactory: enterprise.engineFactory,
cors: '*',
});
await server.start();
创建企业设置
主厂. 回返 { indexAll, engineFactory }。 。 。 .
选项
interface EnterpriseSetupOptions {
// Required
vaultPath: string; // absolute path to the Obsidian vault
providers: ProviderRegistry;
defaultProvider: string; // provider ID used when no per-agent override is set
// Optional
indexDir?: string; // where to store index files
// default: ~/.bk-agent/rag/enterprise/
embedder?: Embedder; // custom embedder, default: SimpleEmbedder
sessionsDir?: string; // per-session memory dir
// default: ~/.bk-agent/sessions/
extraProfiles?: AgentProfile[]; // add custom agent profiles alongside the 6 defaults
maxIterations?: number; // per-engine run limit, default: 20
}
返回值
interface EnterpriseSetup {
// Call once at startup (or periodically to pick up new vault notes)
indexAll(opts?: { verbose?: boolean }): Promise<void>;
// Compatible with AgentServer's engineFactory option
engineFactory: (sessionId: string, transport: Transport) => AgentEngine;
}
每个会话创建什么
每次打给 engineFactory 组装一个新鲜的,孤立的 AgentEngine 改为:
- 一个
ObsidianRAGProvider每个部门都放入该部门的金库文件夹 - 一个全球
ObsidianRAGProvider一般代理( 所有保险库文件夹) - 共享
VaultWriter持续的知识回到金库 - 所有六个企业
AgentProfiles 加上任意extraProfiles - 逐会论、语义和程序
MemorySystem存储于sessionsDir/<sessionId>/
企业代理简介
六部简介入内. 每个系统都有一个系统提示器,一个可选的RAG工具,以及用于prem数据隔离的可选提供者.
| 配置文件标识 | 代理名称 | RAG 工具 | 默认提供者 |
|---|---|---|---|
general | 一般助理 | search_kb (全球金库) | defaultProvider |
support | 辅助代理 | search_support_kb | defaultProvider |
hr | 人力资源代理 | search_hr_kb | local (敏感) |
sales | 销售代理 | search_sales_kb | defaultProvider |
finance | 财务代理 | search_finance_kb | local (敏感) |
ops | 业务代理 | search_ops_kb | defaultProvider |
人力资源和金融违约 local 提供如此敏感的工资和财务数据 永远不会离开你的网络.
单独使用配置文件
import {
GENERAL_PROFILE,
SUPPORT_PROFILE,
HR_PROFILE,
SALES_PROFILE,
FINANCE_PROFILE,
OPS_PROFILE,
ALL_ENTERPRISE_PROFILES,
ENTERPRISE_TOOLS,
VAULT_FOLDERS,
} from '@backendkit-labs/agent-enterprise';
// Register only the profiles you need
const agents = new AgentRegistry();
agents.register(GENERAL_PROFILE);
agents.register(SUPPORT_PROFILE);
agents.register({ ...HR_PROFILE, provider: 'ollama' }); // force on-prem
agents.register({ ...FINANCE_PROFILE, provider: 'ollama' }); // force on-prem
// Tool name constants
ENTERPRISE_TOOLS.SEARCH_KB; // 'search_kb'
ENTERPRISE_TOOLS.SEARCH_SUPPORT; // 'search_support_kb'
ENTERPRISE_TOOLS.SEARCH_HR; // 'search_hr_kb'
ENTERPRISE_TOOLS.SEARCH_SALES; // 'search_sales_kb'
ENTERPRISE_TOOLS.SEARCH_FINANCE; // 'search_finance_kb'
ENTERPRISE_TOOLS.SEARCH_OPS; // 'search_ops_kb'
// Vault folder name constants
VAULT_FOLDERS.GENERAL; // 'General'
VAULT_FOLDERS.SUPPORT; // 'Support'
VAULT_FOLDERS.HR; // 'HR'
VAULT_FOLDERS.SALES; // 'Sales'
VAULT_FOLDERS.FINANCE; // 'Finance'
VAULT_FOLDERS.OPS; // 'Operations'
添加自定义配置
const enterprise = createEnterpriseSetup({
...opts,
extraProfiles: [
{
id: 'legal',
name: 'Legal Advisor',
systemPrompt: `You are a legal knowledge assistant.
Search the knowledge base for relevant precedents and policies.
Always recommend consulting a licensed attorney for case-specific advice.`,
tools: ['search_kb'],
provider: 'local', // sensitive — stays on-prem
},
{
id: 'engineering',
name: 'Engineering Assistant',
systemPrompt: 'You are a software engineering assistant with access to our internal technical documentation.',
tools: ['search_kb', 'write_vault'],
},
],
});
RAG管道
RAG管道分两个阶段施工: 索引化 财务报告和审定财务报表 搜索。 。 。 .
编制索引阶段
启动时, indexAll() 将每个金库文件夹行走,将标记下的文件块块块块块块块块块块块入所配置的嵌入器块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块块.
// Full or incremental re-index (skips unchanged files)
await enterprise.indexAll({ verbose: true });
// [VaultIndexer] Indexed 142 files, 1,847 chunks in 4.2s (38 skipped, unchanged)
搜索阶段
当一个代理的RAG工具被调用时,它在预建的索引上进行同位素搜索,并将上方-K块作为上下文注入到 LLM 提示中:
User: "What is our parental leave policy?"
→ HR agent selected
→ search_hr_kb("parental leave policy")
→ Top 5 chunks from HR/ and General/ folders returned
→ LLM answers using the retrieved excerpts as grounding context
断层进取器
使用 VaultIndexer 直接用于精细的索引控制.
import { VaultIndexer } from '@backendkit-labs/agent-enterprise';
const indexer = new VaultIndexer({
vaultPath: '/shared/obsidian-vault',
indexPath: '/cache/support-index.json',
embedder: myEmbedder,
folders: ['Support', 'General'], // only index these folders (omit for all)
chunkSize: 500, // tokens per chunk
chunkOverlap: 50, // overlap between adjacent chunks
});
await indexer.index({ verbose: true });
const stats = indexer.getStats();
// { files: 42, chunks: 587, lastIndexedAt: '2026-06-11T09:00:00.000Z' }
递增索引
索引器跟踪文件修改时间 。 重运行 index() 只更改进程或新建文件 :
// First run — full index (may take seconds to minutes depending on vault size)
await indexer.index({ verbose: true });
// Subsequent runs — only re-indexes changed files (very fast)
await indexer.index({ verbose: true });
// [VaultIndexer] 3 files changed, re-indexed 28 chunks
断层写入器
VaultWriter 让特工们坚持知识回到奥比西德金库——关闭知识循环.
import { VaultWriter } from '@backendkit-labs/agent-enterprise';
const writer = new VaultWriter({
vaultPath: '/shared/obsidian-vault',
allowedFolders: ['General', 'Support'], // restrict where agents can write
});
// Create a ToolDefinition the engine can call
const writeTool = writer.createTool('general'); // 'write_vault' tool
// Write directly (from non-agent code)
await writer.writeNote({
folder: 'General',
filename: 'api-auth-pattern.md',
content: '# API Auth Pattern\n\nAll endpoints require a Bearer token...',
tags: ['api', 'patterns', 'security'],
});
代理如何使用 VaultWriter
探员 write_vault 在其工具列表中,可以在对话中直接引用:
User: "Document the new API authentication pattern we agreed on"
→ General agent
→ LLM calls write_vault({
folder: "General",
filename: "api-auth-2026.md",
content: "# API Auth Pattern\n\n..."
})
→ File created/updated in the vault
→ LLM: "I've documented the auth pattern in General/api-auth-2026.md"
嵌入器
嵌入器将文本字符串转换为浮向向量进行相似性搜索.
简单的Embedder( 默认- 没有外部依赖性)
一个有决定力的、以大麻为基础的嵌入器。 不需要 API 密钥或运行服务 。 准确度低于神经模型,但总是可用和零纬度:
import { SimpleEmbedder } from '@backendkit-labs/agent-enterprise';
const embedder = new SimpleEmbedder();
// Good for: prototyping, CI/CD, air-gapped systems, and fallback
OllamaEmbedder(建议生产)
使用本地Ollama嵌入模型来进行高质量的语义嵌入. 需要安装嵌入模型的运行中的 Ollama 实例 :
ollama pull nomic-embed-text # 274 MB — general purpose, fast
ollama pull mxbai-embed-large # 669 MB — higher accuracy
import { OllamaEmbedder, OLLAMA_EMBED_DEFAULT_HOST, OLLAMA_EMBED_DEFAULT_MODEL } from '@backendkit-labs/agent-enterprise';
const embedder = new OllamaEmbedder({
host: 'http://localhost:11434', // default: OLLAMA_EMBED_DEFAULT_HOST
model: 'nomic-embed-text', // default: OLLAMA_EMBED_DEFAULT_MODEL
});
const enterprise = createEnterpriseSetup({
vaultPath: '/vault',
providers,
defaultProvider: 'local',
embedder,
});
自定义嵌入器( OpenAI, Cohere, Hugging Face等)
import type { Embedder } from '@backendkit-labs/agent-enterprise';
class OpenAIEmbedder implements Embedder {
async embed(texts: string[]): Promise<number[][]> {
const res = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: texts,
});
return res.data.map(d => d.embedding);
}
}
const enterprise = createEnterpriseSetup({
...opts,
embedder: new OpenAIEmbedder(),
});
奥比多尼亚拉格普罗夫德
组合 VaultIndexer + 键 VectorStore 一个班级有搜索API和工具厂. 直接用于自定义的RAG配置.
import { ObsidianRAGProvider } from '@backendkit-labs/agent-enterprise';
const rag = new ObsidianRAGProvider({
vaultPath: '/shared/obsidian-vault',
indexPath: '/cache/support-index.json',
embedder: new OllamaEmbedder({ model: 'nomic-embed-text' }),
folders: ['Support', 'General'],
topK: 5, // return top 5 results
minScore: 0.15, // discard results below this similarity threshold
});
// Index the vault
await rag.index({ verbose: true });
// Search
const results = await rag.search('How do I reset my password?');
// [
// { content: "To reset your password...", score: 0.82, source: "Support/password-reset.md" },
// { content: "Users can request a reset...", score: 0.71, source: "General/user-guide.md" },
// ]
// Create a typed ToolDefinition for the engine
const searchTool = rag.createTool('search_support_kb');
// → ToolDefinition with name 'search_support_kb' that calls rag.search()
向量轴
低等同位素搜索引擎. 当你有自己的嵌入管时使用它.
import { VectorStore } from '@backendkit-labs/agent-enterprise';
import type { VectorChunk, SearchResult } from '@backendkit-labs/agent-enterprise';
const store = new VectorStore();
// Add pre-embedded chunks
store.add([
{ id: 'c1', content: 'Password reset procedure...', embedding: [...512 floats...], source: 'support.md' },
{ id: 'c2', content: 'Password policy requires...', embedding: [...512 floats...], source: 'policy.md' },
]);
// Search by query embedding
const queryEmbeddings = await embedder.embed(['reset password steps']);
const results: SearchResult[] = store.search(queryEmbeddings[0], { topK: 3, minScore: 0.1 });
// Persist index to disk
store.saveToFile('/cache/my-index.json');
// Load from disk (on restart)
const loaded = VectorStore.loadFromFile('/cache/my-index.json');
使用代理服务器的完整生产示例
由Ollama嵌入、DeepSeek供一般代理人、Ollama供人力资源/财务、Redis会话和JWT auuth提供完整的前期企业部署:
import { createEnterpriseSetup, OllamaEmbedder } from '@backendkit-labs/agent-enterprise';
import { ProviderRegistry } from '@backendkit-labs/agent-core';
import { AgentServer, JwtAuth, TriggerBus, RedisSessionMetaStore } from '@backendkit-labs/agent-web';
import Redis from 'ioredis';
// ── LLM Providers ─────────────────────────────────────────────────────────────
const providers = new ProviderRegistry();
// Cloud: general, support, sales, ops
providers.register('deepseek', new DeepSeekProvider({
apiKey: process.env.DEEPSEEK_API_KEY!,
model: 'deepseek-chat',
}));
// On-prem: HR and Finance (sensitive data)
providers.register('local', new OllamaProvider({
host: 'http://ollama.internal:11434',
model: 'llama3.2',
}));
// ── Enterprise Setup ───────────────────────────────────────────────────────────
const enterprise = createEnterpriseSetup({
vaultPath: process.env.VAULT_PATH!,
providers,
defaultProvider: 'deepseek',
embedder: new OllamaEmbedder({
host: 'http://ollama.internal:11434',
model: 'nomic-embed-text',
}),
indexDir: '/var/bk-agent/rag-indexes',
sessionsDir: '/var/bk-agent/sessions',
maxIterations: 20,
});
await enterprise.indexAll({ verbose: true });
// Re-index every night at 2 AM to pick up new vault notes
import { CronJob } from 'node-cron';
CronJob.schedule('0 2 * * *', () => enterprise.indexAll());
// ── Infrastructure ─────────────────────────────────────────────────────────────
const redis = new Redis(process.env.REDIS_URL!);
const jwt = new JwtAuth({ secret: process.env.JWT_SECRET!, sessionIdClaim: 'sub' });
const triggers = new TriggerBus(enterprise.engineFactory)
.addCron({
name: 'weekly-digest',
schedule: '0 9 * * 1',
buildPrompt: () => 'Summarize all knowledge base updates from the past week.',
onResult: (out) => intranet.post('/announcements', out),
});
// ── Server ─────────────────────────────────────────────────────────────────────
const server = new AgentServer({
port: 3000,
engineFactory: enterprise.engineFactory,
auth: jwt.hook(),
store: new RedisSessionMetaStore(redis),
cors: ['https://intranet.company.com'],
rateLimiting: { max: 30, timeWindow: '1 minute' },
metrics: { enabled: true, prefix: 'enterprise_' },
maxIdleMs: 30 * 60 * 1000,
triggers,
});
await server.start();
console.log('Enterprise agent server running on :3000');
process.on('SIGTERM', () => server.stop());
必要的金库文件夹结构
/obsidian-vault
├── General/ ← all agents can search here
├── Support/ ← Support agent
├── HR/ ← HR agent (on-prem LLM)
├── Sales/ ← Sales agent
├── Finance/ ← Finance agent (on-prem LLM)
└── Operations/ ← Ops agent
以 Obsidian 创建这些文件夹并添加 .md 文档。 索引器会递归地发现所有被标记下的文件.