LuBan.AIAgent
2026.11.9.1
dotnet add package LuBan.AIAgent --version 2026.11.9.1
NuGet\Install-Package LuBan.AIAgent -Version 2026.11.9.1
<PackageReference Include="LuBan.AIAgent" Version="2026.11.9.1" />
<PackageVersion Include="LuBan.AIAgent" Version="2026.11.9.1" />
<PackageReference Include="LuBan.AIAgent" />
paket add LuBan.AIAgent --version 2026.11.9.1
#r "nuget: LuBan.AIAgent, 2026.11.9.1"
#:package LuBan.AIAgent@2026.11.9.1
#addin nuget:?package=LuBan.AIAgent&version=2026.11.9.1
#tool nuget:?package=LuBan.AIAgent&version=2026.11.9.1
English | 中文
LuBan.AIAgent
作者: yswenli | 联系邮箱: yswenli@outlook.com | 代码仓库: https://github.com/yswenli/luban-framework
基于 Microsoft Agent Framework 的 AI Agent 库,让大模型具备思考、规划、调用工具和自主执行的能力。
Related Projects: LuBan.Framework | LuBan.DI | LuBan.AIFlow | LuBan.Web.Core
为什么需要它?
- 想让 LLM 调用工具完成任务,但 MCP / Function Calling 的实现细节令人头疼?
- Skill 管理、工具注册、会话持久化各自需要单独实现,维护成本高?
- 模型 Provider 切换困难——从 Provider A 换到 Provider B 需要重写大量代码?
- 缺少中间件机制——日志、策略控制、权限拦截难以扩展?
LuBan.AIAgent 提供完整的 AI Agent 基础设施,从 Agent 运行时、多模型路由、技能系统、工具系统、会话存储到中间件管道——开箱即用。
快速预览
方式一:开箱即用(推荐)
AddLuBanAgentDefaults 在 AddLuBanAgent 之上补齐会话上下文、本地记忆存储、会话管理的默认(内存)实现,最小宿主即可跑通:
// 注册服务(三行起飞)
services.AddLuBanAgentDefaults(configuration, sp => CreateChatClient());
// 创建 Agent
using var scope = serviceProvider.CreateScope();
var factory = scope.ServiceProvider.GetRequiredService<ILuBanAgentFactory>();
var agent = await factory.CreateAsync(
systemPrompt: "你是一个浏览器自动化助手",
toolGroups: new[] { "browser" });
// 执行任务
var response = await agent.RunAsync("打开百度并搜索 LuBan Framework");
Console.WriteLine(response.Text);
默认实现均为
TryAdd注册,宿主先注册自己的实现即可覆盖。 默认实现不持久化(进程退出即丢失),生产环境请自行注册ISessionManager、ILocalMemoryStore、ISessionContext等实现。
方式二:仅注册框架零件(宿主自行实现契约)
services.AddSingleton<IChatClient>(sp => CreateChatClient());
services.AddLuBanAgent(configuration);
此方式需宿主自行实现 ISessionContext(PathGuard / 全部工具组依赖)、ILocalMemoryStore
(localmemory 工具组依赖)等契约,否则在解析相关服务时会抛出 InvalidOperationException。
需要一个可用的多会话宿主(会话作用域、运行循环、附件编排、命令清单)但不想自己实现这些契约时, 再加一行
services.AddLuBanAgentHost();即可,详见「宿主层(Hosting,opt-in)」。
技术栈
| 组件 | 说明 |
|---|---|
| Microsoft.Agents.AI.Foundry | Agent 运行时框架 |
| Microsoft.Extensions.AI | 统一聊天客户端抽象 |
| Microsoft.Playwright | 浏览器自动化引擎 |
| LuBan.DI | 依赖注入集成 |
| LuBan.Common | 基础接口与工具定义 |
安装
dotnet add package LuBan.AIAgent
安装 Playwright 浏览器(使用浏览器工具时需要):首次运行会由 PlaywrightDriverResolver 按运行时 Microsoft.Playwright 版本自动下载驱动到 ~/.luban-agent/playwright-driver/{version};如需手动兜底,执行由 PlaywrightDriverResolver.GetInstallBrowsersHint() 生成的命令(形如 npx playwright@<运行时版本> install chromium),不要手写固定版本号。
功能总览
核心引擎
| 组件 | 说明 |
|---|---|
LuBanAgent |
Agent 实例,封装 ChatClientAgent,支持同步/流式运行 |
ILuBanAgentFactory / LuBanAgentFactory |
Agent 工厂,按配置创建 Agent 并注入工具 |
IAppConfigReader |
应用配置只读接口(Provider / Skill / 规则 / MCP / 连接器声明) |
IProviderRouter |
Provider 路由接口 |
TextUtils |
文本处理工具 |
WildcardMatcher |
通配符匹配 |
SkillMdParser |
SKILL.md 解析器 |
组件注册表架构
Skills、MCPs、Rules 采用统一的三级优先级注册表模式:
| 优先级 | 来源 | 行为 |
|---|---|---|
| 最高 | 硬编码(DI 注册) | 始终存在,可通过 DisabledBuiltin 配置禁用 |
| 中 | 工作区文件 | 添加新项,同名项被忽略 |
| 最低 | config.json | 添加新项,同名项被忽略 |
加载时机:
- 启动时:加载硬编码组件 + config.json 全局配置
- 工作区切换时:加载工作区文件,自动合并
工作区目录结构:
.luban-agent/
├── skills/ # 工作区级 Skill
│ └── my-skill/
│ └── SKILL.md
├── mcps/ # 工作区级 MCP 服务器
│ └── my-mcp.json
└── rules/ # 工作区级规则
└── my-rule.json
工具系统
| 组件 | 说明 |
|---|---|
ILuBanToolPlugin |
工具插件接口,定义工具分组和提供工具函数 |
ToolPluginRegistry |
工具插件注册表,管理插件的启用/禁用和分组筛选 |
ToolAttribute |
工具标注特性 |
内置工具
| 工具组 | 分组名 | 核心能力 |
|---|---|---|
| 浏览器工具 | browser |
导航、点击、输入、截图、获取内容、等待元素、获取 URL(基于 Playwright) |
| 文件系统工具 | filesystem |
读取文本文件(按行分页,自动识别 UTF-8/GBK 等编码并原样回写)、读取表格(ReadSpreadsheet:.xlsx/.csv/.tsv 转 markdown、按工作表与行分页)、写入文件、编辑文件(精确字符串替换,支持单处/多处/全部替换)、列出目录、删除文件、删除目录、搜索文件(glob)、内容搜索(regex,跳过项显式提示)、创建目录、复制文件、移动文件、获取文件信息;工作区内直接放行,工作区外路径经用户确认后放行 |
| 脚本执行工具 | script |
执行 Shell(运行环境自适应)、Lua(内嵌沙箱,无外部解释器依赖)、Python 脚本 |
| Git 工具 | git |
状态/差异/日志/分支/暂存/提交/合并/变基/推送等 26 个 Git 工具 + 4 个 worktree 工具(EnterWorktreeAsync / FinishWorktreeAsync / AbandonWorktreeAsync / WorktreeStatus),共 30 个;工作区内免确认,越界逐次确认;冲突时返回文件清单交回 agent 处理 |
| Web 工具 | web |
发送 HTTP 请求获取网页内容 |
| 语义检索工具 | retrieval |
索引本地代码/文档,按语义搜索相关片段 |
| 上下文压缩工具 | context |
压缩当前会话的对话历史,释放 token 预算(LLM 可见、可主动调用) |
| 本地记忆工具 | localmemory |
长期记忆的存储、查询和管理 |
| MCP 外部工具 | mcp |
将已连接 MCP 客户端(内置文件系统客户端 + 外部服务器热加载)的工具并入 Agent 工具注册表 |
| 编排工具 | orchestration |
向模型暴露 plan_task / run_orchestration,由模型自行判定复合任务并调度 SubAgent 执行 DAG(opt-in,需 Orchestration.Enabled=true) |
| Wiki 知识库工具 | wiki |
读取/写入/删除 wiki 页面、向量搜索、健康检查(opt-in,需在 ToolGroups 中显式点名) |
| 大日志分析工具 | log |
大日志文件聚合概览、正则检索(级别/时间/行区间过滤)、按行切片,恒定内存(默认启用,非 opt-in) |
| Skill 消费工具 | skill |
列出可用 Skill(支持关键词搜索)、加载并使用 Skill 模板指令;工作区根路径内免确认(默认启用) |
| Skill 管理工具 | skillmanage |
创建/覆盖/删除工作区级 Skill;内置 Skill 不可覆盖删除;写/删操作需用户确认(默认启用) |
| MCP 管理工具 | mcpmanage |
创建/覆盖/删除工作区级 MCP 配置、测试 MCP 连接;内置 MCP 不可覆盖删除;写/删操作需用户确认(默认启用) |
| 连接器管理工具 | connectormanage |
列出连接器状态(已声明/已启用/提供方可用性)、创建或覆盖、删除工作区级连接器声明;提供方须已注册,凭据参数必须是 $credential: 引用;写/删操作需用户确认(默认启用) |
脚本执行说明:Shell 工具会自动探测运行环境(Windows 优先
pwsh>powershell>cmd,类 Unix 优先bash>sh),并按解释器自动适配参数风格与引用方式,执行结果中回传实际使用的shell/shellPath/platform。Lua 工具基于内嵌 MoonSharp 软沙箱执行,无需外部lua解释器,沙箱不具备文件系统与系统命令能力,结果通过
LLM Wiki 知识库(opt-in)
wiki 是 opt-in 工具组:ToolGroups 为 null(表示全部)时不包含本组,只有在 ToolGroups 中显式点名 "wiki" 时才注入。
| 工具 | 说明 | 需要确认 |
|---|---|---|
ReadIndexAsync |
读取 index.md,了解已有页面清单 |
否 |
ReadPageAsync |
读取指定页面正文(相对 wiki 根的路径) | 否 |
SavePageAsync |
写入/更新页面,自动维护 index.md、log.md 与向量索引 |
是 |
DeletePageAsync |
删除页面,同步移除 index 条目与向量索引 | 是 |
SearchAsync |
在 wiki 中做向量搜索,可回落到 raw 工作区文件 | 否 |
LintAsync |
检查孤儿页、死链、未收录、来源缺失、来源过期 | 否 |
目录布局:
wiki/
├── SCHEMA.md # 维护规范(承载 LLM 创作约定)
├── index.md # 页面清单(由服务维护,勿手写)
├── log.md # 变更日志(由服务维护,勿手写)
├── overview.md # 总览
├── sources/ # 来源摘要,一源一页
├── entities/ # 实体
├── concepts/ # 概念
└── queries/ # 问答沉淀
frontmatter 约定:每个页面以 YAML frontmatter 开头,包含 title、type(source | entity | concept | overview | query)、tags、sources(相对工作区根的来源路径)、created、updated。
源格式支持:
| 扩展名 | 处理方式 |
|---|---|
.txt .log .ini .cfg .toml .properties |
纯文本直读 |
.md .markdown |
Markdown 解析 |
.json .jsonc .jsonl .ndjson |
JSON 美化 / 分行美化 |
.csv .tsv |
分隔符表格解析 |
.xml .xaml .svg |
XML 结构化提取 |
.html .htm |
正则去标签降级为纯文本(不引入 HtmlAgilityPack,不保证完整 Markdown 结构) |
.xlsx |
完整支持(按 sheet 读取,MiniExcel;表头按列序号读取,空白表头回落为「列A」,缺失表头不会丢列) |
.xls |
不支持:MiniExcel 无 BIFF 支持,已不再注册该扩展名(不会被索引,避免必然失败) |
| 其他未注册扩展名 | 内容为文本时回落纯文本直读;检测到二进制(含 NUL 字节)则拒绝提取并抛出 NotSupportedException,避免乱码进入上下文 |
表格单元格内的 | 会转义为 \|,换行转为 <br>,保证生成的 Markdown 表格不被破坏。
配置(LuBanAgent:Tools:Wiki):Enabled(默认 true)、TopK(默认 8)、IncludeRawDefault(默认 false)、MaxResultChars(默认 8000)。
后台索引与工作区显式指定:
IRetrievalService.IndexDirectoryAsync(path, glob, force, IProgress<IndexProgress>? progress, cancellationToken, workspaceId):索引过程不再占用方法级写锁(写锁仅包裹存储写入),嵌入调用串行化(内部信号量),并通过IndexProgress上报IndexStage.Scanning / Embedding / Deleting / Done,调用方可放到后台任务执行并展示进度。- 检索与 wiki 的全部方法新增可选参数
string? workspaceId = null:显式指定目标工作区(由IWikiContext.WorkspaceRootFor(workspaceId)解析根目录),不传时沿用IWikiContext.WorkspaceRoot。 - 语义搜索改为在全部候选(不再抽样)上计算余弦相似度,并以
Score降序、ChunkId升序排序,保证同分结果可复现。 - 破坏性变更:
IVectorStore的 8 个方法均新增string? workspaceId = null,IRetrievalService.IndexDirectoryAsync第 4 个参数由force之后的布尔/无变为IProgress<IndexProgress>?。自定义实现者需同步签名(不传workspaceId时行为保持为默认工作区)。 - 索引文件白名单(行为变更):
ChunkerFactory.ShouldIndex只按扩展名判断,白名单 = 各ICodeChunker已注册扩展名 +.txt/.csv/.tsv/.log/.properties/.xlsx;.xlsx在读取时经ExcelExtractor(MiniExcel)提取为 Markdown 后再切块/嵌入(提取结果为「## sheet 名+ markdown 表格」,按 sheet 分节切块,语言标识excel);无专用切块器的纯文本(.txt/.csv/.tsv/.log/.properties)走滑动窗口兜底。白名单之外的扩展名(.docx/.pdf/.ps1/.exe等)与无扩展名文件一律不索引;单文件索引IndexFileAsync同样受白名单与大小上限约束。白名单内但内容含 NUL 字节或全空白的内容在读取阶段跳过。扫描阶段不再预读文件内容(二进制判断移到读取阶段),并剪枝排除目录(.git/bin/obj/node_modules/dist/packages/.vs/.idea/target)与重解析点,避免在云盘/网络目录上因文件水合与杀软扫描长时间卡顿。 ChunkerFactory.EnumerateFiles(root, pattern)为公开的逐层安全枚举(剪枝排除目录与重解析点、单层不可访问时跳过该层、跨 pattern 去重),索引、wiki 页面枚举(WikiService.EnumeratePages)与 CLI/桌面端预扫共用,保证各处统计口径一致。- 表格提取上限与截断告警:
ExcelExtractor.ExtractAsync(filePath, maxChars, cancellationToken)可指定单文件字符上限;索引侧使用ExcelExtractor.IndexingMaxChars(200 万字符,远宽于摄入侧的TextExtractor.MaxChars= 20 万),超出时截断并写入IndexReport.Warnings(不再静默丢数据)。提取在线程池执行,等待期间可响应取消。 IndexDirectoryAsync在枚举阶段即按目录上报IndexStage.Scanning(IndexProgress.CurrentFile为当前目录,Total为已发现的可索引文件数),调用方无需额外预扫即可显示「正在扫描:<目录>(已发现 N 个)…」。
Skill 系统
| 组件 | 说明 |
|---|---|
ISkill |
Skill 接口定义,包含 PromptTemplate 属性用于对话内激活 |
SkillBase |
Skill 基类,提供日志、状态更新、Agent 调用等通用功能 |
SkillRegistry |
Skill 注册表,管理内置、文件级和自定义 Skill |
SkillLoader |
Skill 文件加载器,从 SKILL.md 文件加载 Skill 定义 |
FileSkill |
文件级 Skill 适配器,将 SKILL.md 文件包装为 ISkill |
CustomSkill |
自定义 Skill 适配器,将 CustomSkillConfig 包装为 ISkill |
内置 Skill
| Skill ID | 名称 | 分类 | 说明 |
|---|---|---|---|
brainstorming |
头脑风暴 | creative | 实现功能前探索需求和设计 |
code-review |
代码审查 | development | 审查代码、发现问题、提供改进建议 |
documentation |
文档生成 | productivity | 生成代码注释、README、API 文档等 |
code-refactor |
代码重构 | development | 重构代码,提升代码质量 |
test-generation |
测试生成 | development | 自动生成单元测试 |
code-explain |
代码解释 | development | 解释复杂代码逻辑 |
debug-assistant |
调试助手 | development | 辅助调试问题 |
git-commit |
Git 提交 | productivity | 生成规范的 Git 提交信息 |
find-skills |
技能发现 | meta | 自动发现和推荐合适的技能 |
agents-md-generator |
Agents.md 规约生成器 | productivity | 生成工作区 AGENTS.md 元描述文档 |
文件化 Skill
支持通过 SKILL.md 文件定义自定义 Skill,兼容 OpenCode 格式:
---
name: my-skill
description: "技能描述"
category: custom
---
# Skill 指令内容
这里是 Skill 的提示词模板...
存储位置(按优先级):
- 项目级:
<workspace>/.luban-agent/skills/<skill-id>/SKILL.md - 用户级:
%LocalAppData%/LuBan/AIAgent/skills/<skill-id>/SKILL.md
优先级:硬编码(DI)> 工作区文件 > config.json
对话式 Skill/MCP 管理
通过自然语言对话直接创建、使用和管理 Skill 与 MCP 服务器,无需手动编辑配置文件。
核心能力:
| 功能 | 工具 | 说明 |
|---|---|---|
| 列出 Skill | ListSkillsAsync |
列出所有可用 Skill,支持关键词搜索,返回按 Id 排序的列表 |
| 使用 Skill | UseSkillAsync |
加载指定 Skill 的提示词模板,自动注入到当前对话 |
| 创建 Skill | WriteSkillAsync |
创建或覆盖工作区级 Skill,生成 SKILL.md 文件 |
| 删除 Skill | DeleteSkillAsync |
删除工作区级 Skill |
| 创建 MCP | WriteMcpServerAsync |
创建或覆盖工作区级 MCP 服务器配置,生成 JSON 配置文件 |
| 删除 MCP | DeleteMcpServerAsync |
删除工作区级 MCP 配置 |
| 测试 MCP | TestMcpServerAsync |
测试 MCP 服务器连接,不持久化配置 |
| 列出连接器 | ListConnectors |
列出已声明连接器的提供方与「可用 / 启用 / 未声明」状态 |
| 创建连接器 | WriteConnectorAsync |
创建或覆盖工作区级连接器声明(.luban-agent/connectors/<name>.json);提供方必须已注册 |
| 删除连接器 | DeleteConnectorAsync |
删除工作区级连接器声明 |
使用示例(自然语言对话):
用户: "列出所有可用的 Skill"
AI: [调用 ListSkillsAsync] 当前有 10 个内置 Skill...
用户: "创建一个名为 code-review-v2 的 Skill,描述是代码质量审查助手"
AI: [调用 WriteSkillAsync] 已创建 Skill 'code-review-v2',下一轮对话即可使用
用户: "添加一个 MCP 服务器,名称是 weather-api,命令是 node,参数是 weather-server.js"
AI: [调用 WriteMcpServerAsync] 已创建 MCP 配置,正在连接...
用户: "启用 myVendor 连接器,接口地址 https://api.example.com"
AI: [调用 WriteConnectorAsync] 已创建连接器声明,凭据请到设置页保存(配置里只写 $credential: 引用)
两个 MCP 工具组在写配置时都会做明文凭据门禁:
mcps/*.json与connectors/*.json里疑似令牌的字段必须写$credential:<键>,否则直接拒写。
安全保护:
- 内置 Skill/MCP 不可覆盖或删除
- Skill ID 必须符合
^[a-z0-9][a-z0-9_-]{0,63}$格式 - 单个 SKILL.md 文件大小限制 256KB
- MCP / 连接器配置拒绝明文凭据(须写
$credential:<键>引用) - 连接器提供方必须已由宿主 / 产品 / 插件注册,工具组只做「配置驱动」,不含厂商硬编码
- 写入/删除操作需用户确认(Plan 模式下记录为计划项)
- 修改后下一轮对话生效(延迟重载机制)
存储位置:
- Skill:
<workspace>/.luban-agent/skills/<skill-id>/SKILL.md - MCP:
<workspace>/.luban-agent/mcps/<mcp-name>.json - Connector:
<workspace>/.luban-agent/connectors/<name>.json
配置选项:
{
"LuBanAgent": {
"Tools": {
"Skill": {
"Enabled": true,
"CatalogEnabled": true,
"CatalogMaxEntries": 50
},
"SkillManage": {
"Enabled": true,
"MaxSkillFileBytes": 262144
},
"McpManage": {
"Enabled": true
},
"ConnectorManage": {
"Enabled": true
}
},
"Mcp": {
"ConnectTimeoutSeconds": 10
}
}
}
自动连接:Agent 启动时自动连接所有外部 MCP(跳过内置 filesystem),配置修改后在回合结束时自动重建 Agent,使新配置立即生效。
Rule 系统
| 组件 | 说明 |
|---|---|
IRule |
规则接口,定义执行条件和行为 |
RuleBase |
规则基类 |
RuleEngine |
规则引擎,按优先级评估规则 |
ContextInjectBuilder |
上下文注入构建器,把规则引擎产出的 Inject 文本装配为可注入对话/系统提示词的上下文 |
PathAccessRule |
内置路径访问规则,限制文件系统访问范围 |
MCP 系统
| 组件 | 说明 |
|---|---|
IMCPClient |
MCP 客户端接口,与 MCP 服务器交互 |
McpServerConfig |
外部 MCP 服务器配置:transport / command / args / url / headers / environment / enabled |
StdioMCPClient |
基于 stdio JSON-RPC 的外部 MCP 客户端(启动前经值解析器注入 environment) |
HttpMCPClient |
HTTP 外部 MCP 客户端:sse 走 SSE 事件流 + /message 回传,http 走 Streamable HTTP(直连 url) |
MCPClientFactory |
按 McpServerConfig.Transport 创建外部客户端(stdio / http / sse 分派收敛于一处) |
IMcpConfigValueResolver / CredentialValueResolver |
配置值解析契约与默认实现:把 $credential:<键> 内联替换为 ICredentialStore 中的凭据(键读到空白符为止),可用于 url / headers / environment / args |
McpConfigSecurityValidator |
外部 MCP 配置写入门禁:疑似令牌必须走 $credential: 引用,拒绝明文落盘 |
MCPRegistry |
MCP 注册表,管理内置和外部客户端(工作区文件 / config.json / 进程内三层合并) |
MCPToolPlugin |
MCP 工具插件,将 MCP 工具暴露给 Agent |
FileSystemMCPClient |
内置文件系统 MCP 客户端 |
配置驱动的外部 MCP(含 Streamable HTTP 与
$credential:引用)是「带凭据地连接外部系统」的通用手段,与「连接器」互补:MCP 直接暴露远端工具,连接器则把外部系统读写收敛为宿主内的可配置单元。示例:docs/examples/mcps/(产品仓库)。
会话系统
| 组件 | 说明 |
|---|---|
ISessionManager |
会话管理接口,支持创建、切换、清除会话 |
SessionChatHistoryProvider |
会话历史提供者,自动持久化对话历史 |
SessionOptions |
会话配置,支持压缩阈值设置 |
附件系统
| 组件 | 说明 |
|---|---|
IAttachmentProcessor |
附件处理器接口,判定可支持类型/媒体类型并按需生成缩略图 |
DefaultAttachmentProcessor |
默认实现:图片(PNG/JPEG/GIF/WebP/BMP;TIFF/HEIC 需先转换)与文本文件;图片解码校验并缩放,文本读取内容 |
AttachmentInfo |
附件元数据(文件名、MIME、大小、类型、源路径) |
AttachmentKind |
附件类型枚举(Image / TextFile) |
ProcessedAttachment |
处理结果(元数据 + 文本内容 / 缩略图路径 + 像素尺寸) |
AttachmentMessageBuilder |
把附件装配为 ChatMessage(图片 → base64 DataContent;≤50KB 文本内联;>50KB 仅注入路径指引) |
AttachmentRecord |
会话持久化记录(仅存路径与元数据,不存 base64),供历史回放重建 |
IAgentAttachmentSourceResolver / DefaultAttachmentSourceResolver |
把调用方给的来源解析成本地文件:http(s) URL 下载落盘、本机绝对路径就地读取(Windows 盘符 / UNC / Linux /)、file:// 转换、相对路径先查工作区再查站点内容根;不设主机白名单 |
AttachmentSourceFailure |
单个来源取不到的原因(Source + Reason);解析失败只记录,不中断本轮 |
AttachmentEventProjector |
把处理结果投影成 AttachmentAddedEvent / AttachmentSkippedEvent:>50KB 文本在有工具时给 ReadFileAsync 指引,无工具时按跳过处理 |
规则拦截
| 组件 | 说明 |
|---|---|
RuleCheckedAIFunction |
规则检查装饰器,工具执行前自动拦截检查 |
CustomRule |
自定义规则适配器,支持通配符匹配 |
安全与确认
| 组件 | 说明 |
|---|---|
ToolConfirmationService |
工具执行确认服务:工作区内直接放行,工作区外路径经用户确认后放行,危险操作前要求用户确认 |
ToolConfirmationContext |
确认上下文:承载本轮/本会话三档授权(按路径所在根记忆),AllowThisTurn/IsAllowedThisTurn、AllowThisSession/IsAllowedThisSession |
ConfirmResult |
用户确认结果:Allow(本次)/ AllowAll(本轮全部)/ AllowSession(本会话全部)/ Deny(拒绝) |
PathGuard |
路径安全守卫,工作区根快捷放行(不再作为工作区外访问的硬门) |
RuleEngine |
规则引擎,工具执行前进行权限检查和参数修改 |
多 Agent 编排系统
主 Agent 解析复合任务 → 拆解 DAG 任务图谱 → 分发 SubAgent 执行(串行 / 并行混合编排)。
| 组件 | 说明 |
|---|---|
IOrchestrator / Orchestrator |
编排器入口,串联规划、调度与结果聚合 |
ITaskPlanner |
任务规划器接口,将自然语言任务转换为 TaskGraph |
LlmTaskPlanner |
基于 LLM 的规划器,通过提示词引导模型生成 DAG |
GraphPlanStore |
任务图谱暂存(plan_task 生成、run_orchestration 取用),带 TTL 与容量淘汰 |
IOrchestrationProgressSink |
编排进度出口,默认 no-op,宿主可注册实现(如 TUI 实时渲染) |
DagScheduler |
DAG 调度器,基于拓扑分层实现同层并行、跨层串行 |
SubAgentFactory |
SubAgent 工厂,封装 LuBanAgentFactory 的子 Agent 创建 |
SubAgentRoleRegistry |
SubAgent 角色注册表,管理内置角色与自定义角色 |
SubAgentRole |
SubAgent 角色定义,包含名称、系统提示词模板、默认工具组 |
ContextStore |
跨节点上下文存储,按图谱 ID 隔离,线程安全 |
TaskGraph / TaskNode |
DAG 数据模型,支持依赖声明、占位符引用、关键节点、角色指定;TaskGraph.SharedContext 承载工作区记忆/规则上下文 |
SubAgentSpec |
SubAgent 规格(提示词、工具组、工作区根等),其 SharedContext 会追加到子代理系统提示词 |
OrchestrationToolPlugin |
工具插件,将编排能力暴露给主 Agent 自动调用 |
OrchestrationProgress / OrchestrationProgressContent |
编排进度事件与流式内容载体(AIContent),供 UI 在规划/节点执行期间实时渲染 |
ReflectionResult / ReplanContext |
动态重规划数据模型,关键节点失败后 LLM 分析并生成修正图谱 |
插件体系
插件是应用级的安装单元(plugins/<id>/ 目录 + plugin.json 清单),宿主在运行期用可回收 AssemblyLoadContext 加载,禁用/卸载时按固定顺序断开引用并做 GC 弱引用验证。
| 组件 | 说明 |
|---|---|
IPlugin |
插件契约:Id / Name / Version / Description / InitializeAsync / ShutdownAsync / ContributeSkills |
PluginBase |
插件基类(命名空间 LuBan.AIAgent.Plugins.Base),提供 Host / SafeLog / PostToUi(失效令牌包装,禁止插件直调 UI 线程)与 OnInitializeAsync / OnShutdownAsync 钩子 |
IPluginHost |
宿主能力契约:注册/注销侧栏条目与面板、RegisterCommand、注册/注销 Skill 与 MCP、RegisterConnector / UnregisterConnector、PostToUi、GetConfig、插件日志 |
PluginManager |
单例管理器:ScanAsync / RestoreEnabledAsync / GetPlugins / EnableAsync / DisableAsync / InstallAsync / UpgradeAsync / UninstallAsync 与 Changed 事件 |
PluginLoader / ManifestValidator |
清单读取与校验:必填项、id 与版本正则、入口程序集存在性、minHostVersion / targetApp、重复项、transport、依赖自引用;ValidatePermissions 可单独做权限 / 凭据声明覆盖校验(供加载前门禁调用,与会判 Error 的整单校验分离) |
PluginDependencyResolver |
依赖拓扑与环检测(仅校验依赖存在性,不做自动启用) |
PluginLocation |
目录约定:<AppContext.BaseDirectory>/plugins/<id>/{plugin.json, lib/, assets/} |
IPluginStateRepository / PluginStateRepository |
状态持久化契约 + 默认 JSON 文件实现(id / version / state / installedAt / lastError / requiresRestart) |
BuiltinPluginCatalog |
内置插件目录:登记宿主随包发布的进程内 IPlugin(必须注册为 Singleton) |
PluginHostScope / PluginDescriptor / PluginChangedEventArgs |
插件身份回填与贡献记账、管理器界面用的只读描述、状态变更事件载荷 |
目录语义:插件只有应用级(<AppContext.BaseDirectory>/plugins/<plugin-id>/);插件贡献的 Skill / MCP 则落工作区级(.luban-agent/skills、.luban-agent/mcps),随卸载被显式删除。插件还可贡献连接器工厂(经 IPluginHost.RegisterConnector),框架在 ALC 卸载前自动反注册。
插件权限与凭据安全
插件是第三方代码,宿主以「目录白名单 + 默认拒绝」约束其访问(PRD §3.7):声明期要求清单里的每处权限范围都落在白名单目录内,否则加载前直接判 Disabled;运行期在真正的出口(网络 / 进程 / 凭据 / Git)再按声明拦截越界访问。
| 组件 | 说明 |
|---|---|
PluginSecurityOptions |
白名单策略(NetworkWhitelist / ProcessWhitelist / GitWhitelist / FilesystemWhitelist / CredentialCatalog / ConnectorWhitelist / EnforceAtRuntime / AuditDenials / MaxAuditRecords),可从配置节点 LuBanAgent:Plugins:Security 覆盖(集合项为追加语义)。框架不含任何厂商知识:NetworkWhitelist / CredentialCatalog / ConnectorWhitelist 默认空(默认拒绝),厂商域名、凭据键与连接器提供方键一律由宿主配置补齐;进程白名单为 dotnet / git,Git 能力白名单为能力组 clone_push(clone / push)/ commit(add / commit)/ inspect(rev-parse / status / diff / branch / config / checkout),文件系统白名单为 workspace |
PluginPermissionEvaluator |
判定引擎:ValidateDeclaration 做声明期覆盖校验(具体范围越界写入 ManifestValidationResult.Errors,通配 * 写入 Warnings);IsNetworkAllowed / IsProcessAllowed / IsCredentialAllowed / IsGitAllowed / IsFilesystemAllowed / IsConnectorAllowed 做运行期越界判定(通配声明以宿主白名单为上限;只读、不抛异常) |
PluginScopeContext |
权限环境(AsyncLocal):Enter(pluginId, permissions) 声明「当前调用以哪个插件身份发起」,可嵌套;Current == null 表示宿主自身调用,一律放行 |
PluginPermissionGuard |
运行期出口门禁:RequireNetwork / RequireProcess / RequireCredential / RequireGit 越界即抛 PluginPermissionDeniedException 并写入有界的 RecentDenials 审计;PluginPermissionGuard.Default 为无 DI 场景的兜底实例 |
ICredentialStore / ConfigurationCredentialStore |
凭据读写契约 + 默认「配置节点 LuBanAgent:Credentials:<key> + 环境变量兜底」只读实现(SetAsync 抛 NotSupportedException);桌面宿主宜注册自己的可写实现替换它。规范键含冒号(connector:<实例名>:token)在 IConfiguration 中是三层嵌套节点,Keys 按路径展平还原,勿依赖子节点短名 |
CredentialKeys |
凭据键目录与归一化:连接器令牌统一为 connector:<实例名>:token(如 connector:my-vendor:token,见 ForConnectorToken);Normalize 只做「去首尾空白 + 转小写」(Norm),不做任何厂商历史拼写映射 |
ICredentialKeyAliases |
由宿主提供的别名表(Resolve / GetLegacyAliases / GetLegacyEnvironmentVariableName):把任意写法的键(如厂商历史键 myvendor_pat)归一化为规范键,并给出规范键对应的历史拼写与环境变量名,供 ConfigurationCredentialStore、CredentialValueResolver 与凭据目录白名单做回退读取;未注册别名时使用 NullCredentialKeyAliases(仅做通用归一化,无别名回退) |
要点:
- 白名单是「覆盖」语义,不是「包含」语义:插件写明的每个具体范围都必须被白名单里的某条规则覆盖。通配
*(含数组简写的裸维度,如["filesystem", "network"])表示「声明该维度、具体范围由宿主白名单决定」——声明期放行并记警告,运行期以白名单为上限判定,因此不会绕过白名单;*.example.com覆盖api.example.com,但不覆盖裸域example.com。 - Git 能力按「组」声明、按「操作名」判定:白名单项是能力组,声明组即获得其全部子操作——
clone_push→clone/push(远端读写)、commit→add/commit(本地暂存与提交)、inspect→rev-parse/status/diff/branch/config/checkout(本地只读检查与切分支);也可直接声明具体操作名(如git:push,被clone_push覆盖后声明亦合规)。宿主出口按操作名判定,插件自行拉起 git 进程时传子命令名(如add)——只声明clone_push的插件执行本地add/commit会被判越界。 Disabled与Error的语义区别:权限 / 凭据声明不合规 = 宿主策略不允许启用 →Disabled;清单格式问题(缺id、id非法、入口程序集缺失等)= 插件自身不可用 → 激活阶段判Error。管家界面因此仍能列出格式有问题的插件并给出可诊断错误。PluginSecurityOptions.EnforceAtRuntime = false时只审计不拦截,仅供排查兼容性问题;生产应保持true。- 凭据绝不入 DB 明文;框架只提供「配置 + 环境变量」兜底实现,实际落盘基线由宿主决定(桌面宿主与 LLM ApiKey 同基线)。
连接器体系(Connectors)
连接器把「外部系统读写 + 权限门禁 + MCP 暴露面」收敛为一个可配置单元:框架只提供抽象基类与连接器管理,不含任何厂商实现;厂商连接器(如云效)一律由产品程序集或插件提供并按配置装配——不按名称硬编码 switch(PRD §3.10)。
| 组件 | 说明 |
|---|---|
IConnector |
连接器契约:Key / Name / DisplayName / McpExposures / InitializeAsync,实现 IAsyncDisposable |
ConnectorBase |
连接器抽象基类(厂商无关):提供幂等初始化(每个实例只成功初始化一次、失败不置位可重试)、释放与实例名的通用骨架;派生类只给 Key 与 McpExposures |
ConnectorMcpExposure |
连接器暴露的 MCP 面:Name / Description / CreateClient(services, scope)(进程内客户端只借用连接器,Dispose 不释放连接器) |
ConnectorBuildContext / ConnectorSettings |
工厂入参(实例名 / 提供方键 / 服务 / 设置 / IConfiguration)与设置袋子 |
AddConnector<T> / AddBuiltinConnectors |
注册连接器工厂(只注册不启用);框架的 AddBuiltinConnectors 只注册基础设施,厂商连接器由产品 / 插件显式注册 |
ConnectorFactoryRegistry / ConnectorInstanceHost |
工厂表(线程安全,支持插件运行期增删)+ 宿主级单例实例缓存(连接器由 DI 持有,会话级 MCP 客户端按名派生) |
ConnectorRegistry(scoped) |
解析器:LoadFromWorkspace / GetStates(五态目录:Available / Declared / Enabled / Unavailable / Error)/ ApplyEnabledAsync / CreateMcpClient(mcpName, scope) / UnregisterAll |
ConnectorConfig |
config.json 的 connectors[] 项:name / provider / enabled / settings |
ConnectorWorkspaceEntry |
工作区 .luban-agent/connectors/<name>.json 的对象模型:name / provider / settings / enabled(兼容只写 { "enabled": true } 的旧格式) |
IConnectorConfigWriter / WorkspaceConnectorConfigWriter |
连接器声明写入契约 + 框架默认实现(写工作区文件、拒明文凭据、文件名防穿越);产品 / 桌面宿主可注册自己的实现以统一缓存失效与通知链路 |
ConnectorSettingsSecurityValidator |
写入门禁:疑似令牌键(token / secret / password / pat / apiKey / accessKey / credential 等)必须写 $credential:<键> 引用,拒绝明文落盘 |
可用性三级(配置驱动):
| 级别 | 来源 | 作用 |
|---|---|---|
| 声明 | config.json:connectors(经 IAppConfigReader.Connectors)+ 工作区完整声明 |
该提供方是否可用(未声明/未注册 = Unavailable,只告警跳过,不 fail-fast) |
| 启用 | .luban-agent/connectors/<name>.json |
该连接器在本工作区是否启用;文件可只写 enabled,也可自带 provider / settings 作完整声明(工作区覆盖 config.json,settings 逐键合并,未在 config.json 声明者按工作区声明补齐) |
| 暴露 | 插件清单 mcpServers: ["<name>"] / 插件贡献的连接器 |
按名解析连接器的 MCP 暴露面,注入插件权限环境 |
// config.json(宿主 per-user 文件)—— 宿主声明「有哪些提供方可用」;框架不内置任何厂商项
{ "connectors": [ { "name": "my-vendor", "provider": "myVendor", "enabled": false } ] }
// appsettings.json(非敏感参数覆盖;PAT 等凭据绝不落此节点)
{ "LuBanAgent": { "Connectors": { "MyVendor": { "Endpoint": "https://api.example.com" } } } }
插件贡献连接器:插件可在 plugin.json 声明 connectors: [{ "providerKey": "myVendor" }](或字符串数组简写),并在 InitializeAsync 里经 IPluginHost.RegisterConnector(registration) 把工厂登记进 ConnectorFactoryRegistry;宿主在卸载插件时会在 ALC Unload() 之前自动调用 UnregisterConnector 反注册,避免工厂委托钉住插件 ALC。清单声明必须被 permissions.connectors 覆盖,且其具体范围须落在宿主 PluginSecurityOptions.ConnectorWhitelist 内(默认空 = 默认拒绝)。
凭据键按实例名泛化为
connector:<实例名>:token(见CredentialKeys),PAT 只经ICredentialStore流转,绝不明文写入.luban-agent/mcps/*.json或.luban-agent/connectors/*.json;需要在配置里引用凭据时写$credential:<键>,由IMcpConfigValueResolver/CredentialValueResolver在装配时内联替换。
厂商连接器怎么写(宿主侧,不在框架内):一个 ConnectorBase 派生类 + 一行注册扩展即可,框架代码里不出现任何厂商名:
// 产品程序集或插件内(ProviderKey = "myVendor",默认实例名 "myVendor")
public sealed class MyVendorConnector : ConnectorBase
{
public MyVendorConnector(ConnectorBuildContext ctx) => Name = ctx.Name;
public override string Key => "myVendor";
public override IReadOnlyList<ConnectorMcpExposure> McpExposures => [ /* 暴露面(可选) */ ];
}
// 装配(宿主 appsettings 里补 Plugins:Security:NetworkWhitelist / CredentialCatalog / ConnectorWhitelist)
services.AddConnector<MyVendorConnector>("myVendor", ctx => new MyVendorConnector(ctx));
宿主层(Hosting,opt-in)
把「会话作用域 + 运行循环 + Profile + 附件编排 + 能力门禁 + 命令清单」收进框架,宿主(TUI / 桌面 / Web / A2A)只负责 UI 与产品配置。IAgentHost 输出 UI 无关 的 AgentStreamEvent 序列,框架不引用任何 UI 类型。
| 组件 | 说明 |
|---|---|
AddLuBanAgentHost() |
注册宿主与默认接缝(全部 TryAdd):SessionRuntimeManager(Singleton)、IAgentHost(Scoped)、Profile / 工作区 / 用户 / 模型选择解析、附件编排、能力门禁、会话初始化与 ICommandCatalog(Singleton) |
AddLuBanAgentOpenAI(configuration) |
按 LuBanAgent:Models 数组(Provider / Model / ApiKey / BaseUrl)为每个 Provider 建客户端,注册 IChatClient + IProviderRouter;同一 Provider 多条模型必须凭据一致;配置不全时只登记 ChatClientFactoryWarning,不注册也不抛 |
IAgentHost |
宿主入口:InitializeAsync / Reset / RunStreamingAsync(AgentRunRequest);必须以 Scoped 解析,自身不持有会话状态。Reset 在该会话有回合运行中时只登记延迟重载(不打断回合),回合收尾后释放 Agent,下一次对话按最新配置重建 |
AgentRunRequest |
一轮对话入参:Input / AttachmentPaths / Attachments(URL 或路径,由框架解析)/ SystemPrompt(按轮人设覆盖)/ EnableTools / ReasoningEffort(按轮推理强度覆盖,设为 None 关闭思考)/ SessionId / PermissionMode / ConfirmHandler / ConfirmHandlerAsync / OnPlannedAction / OnUserDenied |
AgentStreamEvent |
UI 无关输出事件:TextDeltaEvent / ThinkingDeltaEvent / ToolCallStartedEvent / ToolCallCompletedEvent / ToolCallFailedEvent / ToolConfirmationRequestedEvent / ErrorEvent / OrchestrationProgressEvent / AttachmentAddedEvent / AttachmentSkippedEvent |
AgentBuildOverrides |
按轮构建覆盖项(SystemPrompt + EnableTools):与缓存 Agent 比对,变化即在该会话的串行区间内重建 |
AgentEventProtocol / AgentEventFrame |
宿主事件 → 传输帧的统一映射(text.delta / tool.* / attachment.* 等),Web / CLI / Codex 共用一套事件名 |
IToolConfirmationBroker / DefaultToolConfirmationBroker |
跨请求确认登记簿(Singleton):SSE 推 tool.confirm,另一个 HTTP 请求回结果,超时按拒绝 |
SessionRuntimeManager / SessionRuntime |
按会话维护独立 DI scope 与串行运行循环(EnqueueAsync)、重载标记(RequestReload)、活动时间与释放 |
IAgentProfile / AgentProfileBase |
Agent 配置(系统提示词、工具组、检索模式)与建 Agent 流程;DefaultAgentProfile 为通用助手 |
IAgentWorkspaceResolver / WorkspaceDescriptor |
按会话解析工作区(Id / Name / RootPath / Type);默认读 LuBanAgent:WorkspaceRoot,缺省为进程当前目录(Web 宿主经 LuBan.Web.Core 归一化:相对值按站点 ContentRootPath) |
IAgentProfileResolver / IAgentUserResolver / IAgentModelSelection |
Profile 选择、用户标识(默认读 IUserContext.UserId,回落 local)、模型限定名(默认读 LuBanAgent:DefaultModel) |
IAgentAttachmentOrchestrator / AgentAttachmentResolver |
@引用 解析、附件处理与能力门禁、UI 路径与引用合并去重;解析规则由编排器提供,因此 CLI / 桌面 / Web / A2A 行为一致 |
IModelCapabilityGate / IModelCapabilityProbe |
模型对附件的能力判定与单轮视觉能力探测(默认一律放行、不探测) |
ISessionRuntimeInitializer / IAgentSessionExtension |
会话 scope 创建后的初始化扩展点、建 Agent 前的会话扩展点(插件贡献、连接器启用等) |
ICommandCatalog / SlashCommandDefinition |
两端共享的斜杠命令清单(名称 / 别名 / 描述 / 分类 / 用法 / 可用客户端),避免 CLI 与桌面端漂移 |
ToolConfirmationContextExtensions |
每轮确认上下文装配(权限模式、取消令牌、确认回调、计划项与拒绝回调) |
services.AddLuBanAgent(configuration);
services.AddLuBanAgentHost();
services.AddLuBanAgentOpenAI(configuration); // 或由宿主自行注册 IChatClient
using var scope = serviceProvider.CreateScope();
var host = scope.ServiceProvider.GetRequiredService<IAgentHost>();
await host.InitializeAsync(sessionId);
await foreach (var e in host.RunStreamingAsync(new AgentRunRequest { Input = "你好", SessionId = sessionId }))
{
if (e is TextDeltaEvent d) Console.Write(d.Delta);
}
宿主层是 opt-in:不调用
AddLuBanAgentHost时,AddLuBanAgent/AddLuBanAgentDefaults+ILuBanAgentFactory的既有用法完全不变。 需要产品行为(多工作区、持久化会话、厂商连接器、自定义 Profile)时,在AddLuBanAgentHost()之后注册自己的实现覆盖默认接缝即可(全部TryAdd)。
Web 端事件流
AgentEventProtocol 把 AgentStreamEvent 映射成传输帧;首帧 session 与末帧 done 由传输层自己构造(它们描述的是连接而不是模型输出)。Web 侧用 LuBan.Web.Core 的 SseEventWriter + SseEventPump 写出(命名事件 + 注释心跳),CLI / Codex 可复用同一套事件名做本地渲染。
| 事件名 | 载荷(camelCase) | 来源 |
|---|---|---|
session |
{ sessionId, created } |
传输层 |
think.delta |
{ delta, llmRound } |
ThinkingDeltaEvent |
text.delta |
{ delta, llmRound } |
TextDeltaEvent |
tool.started |
{ callId, name, arguments, llmRound } |
ToolCallStartedEvent |
tool.completed |
{ callId, resultSummary, llmRound } |
ToolCallCompletedEvent |
tool.failed |
{ callId, error, llmRound } |
ToolCallFailedEvent |
tool.confirm |
{ confirmationId, toolName, arguments, timeoutSeconds } |
ToolConfirmationRequestedEvent |
attachment.added |
{ fileName, mediaType, fileSize, source } |
AttachmentAddedEvent |
attachment.skipped |
{ source, reason } |
AttachmentSkippedEvent |
error |
{ message } |
ErrorEvent |
done |
{ sessionId, elapsedMs } |
传输层 |
OrchestrationProgressEvent 不映射(返回 null,调用方忽略)。
使用指南
1. 配置与注册
{
"LuBanAgent": {
// 绝对路径或相对路径;Web.Core 宿主按站点 ContentRootPath 解析相对值
"WorkspaceRoot": ".",
// 可省略;省略时取 Models 第一项
"DefaultModel": "openai:gpt-4o",
"SystemPrompt": "你是一个智能助手。",
"MaxToolLoopIterations": 10,
// 数组:每项一个 provider:model 组合;同一 Provider 多条时 ApiKey/BaseUrl 必须一致
// BaseUrl 可省略,但仅当 Provider 有内置地址时安全(deepseek/openai/kimi 等);
// 自建网关、代理或内置表外的 Provider 必须显式配置,否则会落到 OpenAI 默认端点 https://api.openai.com/v1/
"Models": [
{ "Provider": "openai", "Model": "gpt-4o", "ApiKey": "sk-***", "BaseUrl": "https://api.openai.com/v1/" },
{ "Provider": "deepseek", "Model": "deepseek-v4-pro", "ApiKey": "sk-***", "BaseUrl": "https://api.deepseek.com/v1/" }
],
"Session": {
"CompactTargetMessages": 20,
"CompactThreshold": 10
},
// 每个登录用户一个工作区:<WorkspaceRoot>/users/<userId>;默认 false(CLI / 桌面端保持单工作区)
"IsolateWorkspaceByUser": false,
// 附件来源解析:URL 下载落 <工作区>/.luban-agent/attachments/<sessionId>/<yyyyMMdd>/
"Attachments": {
"Enabled": true,
"MaxCount": 5,
"MaxFileBytes": 26214400, // 25MB,单文件硬上限
"TimeoutSeconds": 30, // 单个 URL 下载超时
"RootDirectory": ".luban-agent/attachments",
"ContentRoot": null // 相对路径第二基准;Web 宿主由 LuBan.Web.Core 归一化为绝对路径
},
// 工具确认:跨请求登记簿;超时按拒绝
"Confirmation": {
"TimeoutSeconds": 60,
"BrokerEnabled": true
}
}
}
// 注册服务
services.AddSingleton<IAppConfigReader>(myConfigManager);
services.AddSingleton<IProviderRouter>(myProviderRouter);
services.AddLuBanAgent(configuration); // 已内置 AddBuiltinConnectors:只注册连接器基础设施(不注册任何厂商连接器)
连接器是否可用由
IAppConfigReader.Connectors(config.json:connectors)声明,是否启用由工作区.luban-agent/connectors/<name>.json决定,详见「连接器体系」。
2. 多模型路由
// 使用 provider:model 格式路由到不同模型
// IProviderRouter 根据 ModelId 中的 provider 前缀自动分发
var agent = await factory.CreateAsync(modelName: "qwen:qwen-plus");
// 切换 Provider 只需更改前缀
var agent2 = await factory.CreateAsync(modelName: "openai:gpt-4o");
3. 工具注册与使用
// 创建 Agent 时指定工具组
var agent = await factory.CreateAsync(
toolGroups: new[] { "browser", "filesystem" });
// Agent 自动选择并调用工具
var response = await agent.RunAsync("列出 src 目录下所有 .cs 文件并统计代码行数");
// 流式运行
await foreach (var update in agent.RunStreamingAsync("帮我分析这段代码"))
{
Console.Write(update.Text);
}
4. Skill 管理
// 获取 Skill 注册表
var skillRegistry = serviceProvider.GetRequiredService<SkillRegistry>();
// 列出所有 Skill
var skills = skillRegistry.GetAll();
// 执行 Skill
var context = new SkillContext
{
Agent = agent,
UpdateStatus = status => Console.WriteLine($"状态: {status}")
};
var result = await skillRegistry.Get("brainstorming")
.ExecuteAsync(context, "我想实现一个用户登录功能");
5. 自定义工具插件
public class MyToolPlugin : ILuBanToolPlugin
{
public string GroupName => "my-tools";
public string? Description => "自定义工具集";
public IReadOnlyList<AIFunction> GetTools(DiContainer sp, ToolGroupOptions? toolsOptions = null)
{
// 返回自定义工具函数
return new List<AIFunction> { /* ... */ };
}
public bool IsEnabled(LuBanAgentOptions options) => true;
}
// 注册
services.AddSingleton<ILuBanToolPlugin, MyToolPlugin>();
6. 自定义 Skill
方式一:文件化 Skill(推荐)
在项目级或用户级目录创建 SKILL.md 文件:
# 项目级目录
<workspace>/.luban-agent/skills/my-skill/SKILL.md
# 用户级目录
%LocalAppData%/LuBan/AIAgent/skills/my-skill/SKILL.md
SKILL.md 格式:
---
name: my-translator
description: "将文本翻译成英文"
category: custom
---
# 翻译助手
请将用户提供的内容翻译成英文。
## 要求
- 保持原文的语气和风格
- 使用地道的英文表达
方式二:代码定义 Skill
public class MyCustomSkill : SkillBase
{
public override string Id => "my-custom-skill";
public override string Name => "我的自定义 Skill";
public override string Description => "自定义 Skill 示例";
public override string Category => "custom";
public override string? PromptTemplate => "自定义提示词模板...";
public override async Task<SkillResult> ExecuteAsync(SkillContext context, string input)
{
context.UpdateStatus?.Invoke("正在处理...");
var result = await context.Agent!.RunAsync(input, context.CancellationToken);
return SkillResult.Ok(result.Text ?? "");
}
}
// 注册
services.AddSingleton<ISkill, MyCustomSkill>();
7. 自定义规则
public class MyRule : RuleBase
{
public override string Id => "my-rule";
public override string Name => "我的规则";
public override string Description => "自定义规则示例";
public override int Priority => 50;
public override bool IsApplicable(RuleContext context)
=> context.ActionType == "file-write";
public override Task<RuleResult> ExecuteAsync(RuleContext context)
{
var path = context.Arguments.GetValueOrDefault("path")?.ToString();
if (path?.Contains("secret") == true)
return Task.FromResult(RuleResult.DenyResult("禁止访问包含 secret 的路径"));
return Task.FromResult(RuleResult.AllowResult());
}
}
// 注册
services.AddSingleton<IRule, MyRule>();
8. 外部插件加载
{
"LuBanAgent": {
"ExternalPlugins": ["MyCompany.AgentPlugins", "ThirdParty.Tools"]
}
}
通过配置 ExternalPlugins 指定程序集名称,框架会自动扫描并注册其中实现了 ILuBanToolPlugin 的类型。
9. 多 Agent 任务编排
{
"LuBanAgent": {
"Orchestration": {
"Enabled": true,
"PlannerReasoningEffort": "none",
"MaxNodes": 10,
"MaxParallelism": 5,
"DefaultNodeTimeoutSeconds": 0,
"MaxReplanAttempts": 3,
"ReflectionTimeoutSeconds": 0,
"DefaultToolGroups": []
}
}
}
Enabled:启用后向模型暴露两个编排工具——plan_task(由模型自行判定复合任务并生成任务图谱)与run_orchestration(按plan_task返回的graphId执行)。是否编排完全交由模型决策,框架不再做启发式或自动判定。- 规划固定使用 LLM 规划器;
PlannerModel为null时继承主模型,PlannerReasoningEffort建议设为none以关闭推理模型的思考输出、显著缩短规划耗时。
SubAgent 角色系统:规划器可为每个节点指定角色(analyst/researcher/coder/writer),角色提供专业系统提示词和默认工具组。内置 4 个角色,支持通过工作区扩展自定义角色。
工作区编排扩展
进入 /agi 工作区时自动加载以下目录:
.luban-agent/roles/*.json:自定义 SubAgent 角色,同名覆盖内置角色。格式:{ "name": "...", "systemPromptTemplate": "... {prompt} ...", "defaultToolGroups": [...] }。
多模型路由
注册 IProviderRouter 后,TaskNode.ModelName(格式 provider:model)与 OrchestrationOptions.PlannerModel 会路由到对应 Provider;路由失败自动回退默认模型并记录警告。未注册路由时行为不变。
编排判定
是否编排完全由模型决定:框架向模型暴露 plan_task 与 run_orchestration 两个工具,模型自行判断输入是否为复合任务并生成/执行图谱,框架不再做启发式预过滤或自动判定。
动态重规划:当关键节点失败导致整体状态为 failed 时,编排器自动触发反思阶段:
- 反思:LLM 分析失败节点及其直接依赖的输出,判断是否可修复
- 重规划:LLM 生成修正节点(
fix_{attempt}_前缀);指向已成功节点的依赖会被解析并内联为 prompt 文本,避免引用不在修正图谱中的节点 - 重试:执行修正图谱,最多尝试
MaxReplanAttempts次(默认 3)
// 直接调用编排器
var orchestrator = serviceProvider.GetRequiredService<IOrchestrator>();
var result = await orchestrator.RunAsync("调研 LuBan 框架并生成对比报告");
Console.WriteLine($"整体状态: {result.OverallStatus}");
Console.WriteLine($"重规划次数: {result.ReplanningAttempts}");
Console.WriteLine($"最终输出:\n{result.FinalOutput}");
// 带进度回调执行(不丢最终结果):规划/节点级事件实时回调,返回值仍是完整编排结果
var result2 = await orchestrator.RunAsync(
graph,
onProgress: p => Console.WriteLine($"{p.EventType}: {p.Message}"),
cancellationToken: default);
编排由模型调用 plan_task / run_orchestration 两个工具触发,执行发生在工具调用内部,
进度不再随对话流产出。框架通过 IOrchestrationProgressSink(默认注册 no-op 实现)广播
OrchestrationProgress(EventType / NodeId / Message / NodeResult / Activity / ElapsedMs),
宿主可注册自定义 Sink(如 CLI 的 TuiOrchestrationProgressSink)在规划与节点执行期间逐条渲染进度。
进度事件类型包含:PlanningStarted、PlanningCompleted、NodeStarted、NodeCompleted、
NodeFailed、NodeSkipped(关键前驱失败导致后继被跳过,逐节点上报)、ReflectionStarted、
NodeActivity(节点内部思考/工具调用明细)。
编排执行流程:
- 规划阶段:
ITaskPlanner将自然语言任务拆解为 DAG 任务图谱(模板优先,LLM 回退) - 校验阶段:
TaskGraph.Validate检查无环、依赖存在、无重复 ID - 调度阶段:
DagScheduler基于 Kahn 拓扑排序分层执行,同层节点并行 - 上下文传递:节点 prompt 中的
{dep:xxx}占位符由ContextStore替换为前驱输出 - 错误处理:关键节点失败时跳过后继节点;非关键节点失败时继续执行
- 结果聚合:终点节点(无后继)的输出聚合为
FinalOutput
记忆上下文注入:编排入口(Orchestrator.ExecuteGraphAsync)会通过 ContextInjectBuilder 构建工作区长期记忆与规则上下文,
一次性写入 TaskGraph.SharedContext(仅填充一次,重规划生成的修正图谱继承同一份),再由 SubAgentFactory 追加到每个
SubAgent 的系统提示词,使子代理与主 Agent 对话共享同一份工作区记忆。常规对话路径则由 SessionChatHistoryProvider
直接把召回结果作为 System 消息注入,两条路径共用同一个 ContextInjectBuilder。
关键概念:
- 关键节点(
IsCritical = true):失败时阻止后继节点执行,整体状态为failed - 非关键节点:失败时后继节点继续执行,整体状态为
partial - 占位符:
{dep:节点id}引用前驱节点输出,运行时自动替换 - 并行度:
MaxParallelism限制同层最大并行节点数,0 表示不限制 - 共享上下文(
SharedContext):工作区记忆/规则上下文,由编排入口构建并注入所有子代理
10. 错误处理与自动重试
框架对所有 LLM/API 调用做统一错误分类(结构化优先:HTTP 状态码 + error.code),最终失败抛出 AgentApiException,宿主渲染 Error.FriendlyMessage 即可:
| 类别 | 典型错误 | 是否自动重试 |
|---|---|---|
| 认证/权限/余额 | 401 / 402 / 403 | 否,终止并提示 |
| 模型不存在 | 404 / 410 | 否,终止并给出排查清单 |
| 参数错误 / 上下文超长 / 能力不支持 | 400 / 413 / 422 | 否,终止并提示 |
| 内容风控 | content_filter |
否,终止并建议改措辞 |
| 限流 | 429 rate_limit_exceeded |
是(默认 3 次尝试,1s/2s 指数退避 + 抖动,遵循 Retry-After,单次等待上限 30s) |
| 服务端错误 / 网络错误 / 超时 | 5xx / DNS/TLS / 超时 | 是(同上) |
| 配额耗尽 | 429 insufficient_quota |
否,终止并在文案中带上服务端给出的重置时间 |
| 流式中断 | 已输出内容后连接断开 | 否,保留已输出并提示响应中断 |
配置(appsettings.json 的 LuBanAgent 节):
"ApiRetry": {
"Enabled": true,
"MaxAttempts": 3,
"BaseDelayMs": 1000,
"BackoffFactor": 2,
"MaxDelayMs": 30000
}
重试进度回调(由宿主在启动时设置,回调在调用线程执行):
options.Value.OnApiRetry = notice =>
Console.WriteLine($"{notice.Category} 将在 {notice.Delay.TotalSeconds:F0}s 后重试(第 {notice.Attempt} 次)");
说明:
- 流式调用仅在首个 token 产出前重试;已产出内容后中断不会重试,避免内容重复。
- 容错中间件包裹在
FunctionInvokingChatClient之内,每个工具轮次的 API 调用独立重试。 - OpenAI SDK 的内置重试(
ClientRetryPolicy.Default,默认再重试 3 次)已在宿主侧禁用,重试次数与进度提示以本配置为准。 - 编排规划期的可识别 API 故障不再静默降级为常规对话,而是按分类结果透出。
- 会话摘要压缩失败会降级为「跳过压缩」继续对话,不再打断主对话。
11. 工具确认与终止语义
- 拒绝即终止:用户在工具确认中选择「拒绝」时,宿主立即终止当前对话回合(保留已输出内容)。CLI 与 Codex 均显示「已拒绝,本轮终止」;CLI 被拒工具块显示「已被用户拒绝」,Codex 确认卡显示「已拒绝」、工具卡显示框架中性结果「工具调用被拒绝或已取消」。
- 等待无限期:工具确认与工作区授权均无限期等待用户响应,无超时兜底;Esc 可随时取消本轮(CLI 显示「任务已取消」,Codex 显示「已取消」)。
- 工作区内免确认:文件系统工具目标路径落在工作区根(或本轮/本会话已授权的根)内时直接放行,不再要求确认。
- 工作区外经确认放行:工作区外路径不再被硬性拦截,改为弹出确认;用户可选「允许(本次)/ 本轮全部允许 / 本会话全部允许 / 拒绝」。授权按路径所在根记忆(文件取父目录、目录取自身);授权根落到盘符根(如
D:\)时不记忆,避免一次放行整盘。 - 授权档位记忆:
Allow仅放行本次;AllowAll记入本轮;AllowSession记入本会话(进程存活期)。每轮开始Reset()清空本轮集合,本会话集合跨轮保留;ResetSession()可显式清空本会话集合。 - 只读免确认(仅 Plan):Plan 模式下只读工具(
ReadFileAsync/ReadSpreadsheetAsync/ListDirectoryAsync/GetWorkspaceOverviewAsync/SearchFilesAsync/GrepAsync/GetFileInfoAsync)在已授权范围内直接放行,便于读取上下文产出计划;越界只读记录为计划项而非放行。 - 删除类硬确认:
AlwaysConfirmTools(默认DeleteFileAsync/DeleteDirectoryAsync/DeletePageAsync)无论路径是否在工作区内都必须确认,且「本轮/本会话全部允许」对删除类不记忆,每次必确认。 - 子代理代确认:编排子代理不会向用户弹确认;其工具调用在需要人工确认时,由主代码按「本轮/本会话已允许集合」代判——命中放行,否则返回子代理专用拒绝结果(不代表用户拒绝)。
- 本轮/本会话允许集合:
ToolConfirmationContext.AllowedThisTurn不再公开;宿主使用AllowThisTurn(toolName)/AllowThisSession(toolName)写入、框架使用IsAllowedThisTurn(toolName)/IsAllowedThisSession(toolName)读取。 - 子代理等待无限期:
Orchestration.DefaultNodeTimeoutSeconds与ReflectionTimeoutSeconds默认 0(无限期);显式配置大于 0 时才限时,节点仍可用TimeoutSeconds单独覆盖。 - 规划不再「长时间无响应」:
Orchestration.PlannerReasoningEffort控制规划/反思调用的推理强度,推理模型(如 glm-5)默认开思考时会在规划阶段输出大量 reasoning 内容,单次规划耗时可达 1 分钟以上;建议设为"none"关闭(默认null表示不传递该参数,兼容不支持reasoning_effort的非推理模型)。
12. 插件体系
插件 = 清单(plugin.json)+ 程序集(lib/)+ 静态资源(assets/)三件套,装到 <AppContext.BaseDirectory>/plugins/<plugin-id>/,宿主在运行期加载并允许禁用/卸载。
写第一个插件(随宿主发布的内置插件)
using LuBan.AIAgent.Plugins;
using LuBan.AIAgent.Plugins.Base; // PluginBase 在子命名空间,需显式 using
public sealed class HelloPlugin : PluginBase
{
public override string Id => "com.tjc.hello";
public override string Name => "Hello 插件";
public override string Version => "1.0.0";
protected override Task OnInitializeAsync(IPluginHost host, CancellationToken cancellationToken)
{
host.RegisterSidebarEntry(new PluginSidebarEntry
{
Id = "hello-entry",
Label = "Hello",
PanelType = "hello-panel"
});
host.RegisterMcpServer("hello-mcp");
return Task.CompletedTask;
}
public override IEnumerable<SkillDefinition> ContributeSkills()
{
yield return new SkillDefinition { Id = "hello-skill", Name = "Hello 技能" };
}
}
注册到 DI —— 必须 AddSingleton(PluginManager 的构造链只允许单例服务,宿主若开启 ValidateScopes 会直接抛错):
services.AddSingleton<IPlugin, HelloPlugin>();
services.AddLuBanAgent(configuration); // 内部注册 PluginManager / PluginLoader / 状态仓储
services.AddSingleton<IPluginHost, MyPluginHost>(); // 宿主自己实现:落到真实 UI 与注册表
写一个列表插件(plugin.json)
{
"id": "com.tjc.demo",
"name": "Demo 插件",
"version": "1.0.0",
"author": "TJC",
"description": "示例插件",
"entryAssembly": "Tjc.Demo.Plugin.dll",
"targetApp": "codex",
"minHostVersion": "2026.10.15",
"uiContributions": [{ "id": "demo-entry", "label": "Demo", "panelType": "demo-panel" }],
"skills": [{ "id": "demo-skill", "name": "Demo 技能" }],
"mcpServers": [{ "name": "demo-mcp", "transport": "inproc", "enabled": true }],
"connectors": [{ "providerKey": "myVendor" }],
"permissions": { "filesystem": ["workspace"], "network": ["api.example.com"], "credential": ["connector:my-vendor:token"], "connectors": ["myVendor"] },
"dependencies": ["com.tjc.base"]
}
清单约定:
| 字段 | 约定 |
|---|---|
id |
必填,^[a-zA-Z][a-zA-Z0-9._\-]{1,127}$ |
name / version / entryAssembly |
必填;版本形如 1.0.0 或 1.0.0-beta.1 |
skills[].id |
不含点号(与 Skill 注册表约定一致) |
mcpServers[].transport |
目前仅支持 inproc(进程内 MCP 客户端) |
connectors[] |
可选。插件贡献的连接器提供方:{ "providerKey": "myVendor", "displayName": "..." } 或字符串简写 "myVendor";providerKey 必填且不得重复,且必须被 permissions.connectors 覆盖、落在宿主 ConnectorWhitelist 内 |
permissions |
7 个维度 filesystem / network / git / database / process / credential / connectors;可写数组简写 ["filesystem:workspace"](裸维度如 "network" 等价于该维度通配 "*"),未声明的维度等价于不声明,"permissions": null 归一化为空权限。具体范围须被宿主白名单覆盖,越界即 Disabled;通配 * 声明期放行、运行期以白名单为上限(见下方「权限声明如何生效」) |
dependencies |
仅校验依赖插件是否存在且已启用,不允许自引用 |
plugin.json 的 JSON Schema 随包发布(Plugins/Schemas/plugin.schema.json),编辑器可据此补全与校验。
权限声明如何生效
清单里的 permissions 不是「告知」,而是一份受宿主白名单审核的申请(PRD §3.7:目录白名单 + 默认拒绝):
- 声明期:
EnableAsync先调PluginLoader.ValidatePermissions(插件级 + 技能级),逐维度检查具体范围是否被PluginSecurityOptions白名单覆盖;任一越界即判Disabled(LastError写明越界项)。通配*(含数组简写的裸维度,如["filesystem", "network"])不算越界,计入警告,运行期以白名单为上限;*.example.com覆盖api.example.com,但不覆盖裸域example.com。清单里的connectors[].providerKey同样要过这一关(维度connectors,上限是ConnectorWhitelist)。 - 运行期:宿主 / 产品 / 插件提供的连接器与内置出口组件在真正发起网络 / 进程 / 凭据 / Git 访问前调用
PluginPermissionGuard判定。宿主在调用插件代码前用PluginScopeContext.Enter(pluginId, permissions)包裹;插件在宿主包裹不到的回调(UI 事件)里可自行PluginBase.EnterPermissionScope()。未声明即拒绝;声明为通配*的维度以宿主白名单为上限判定;权限环境为空表示宿主自身调用,一律放行。 - 凭据取用:插件不能直接读凭据,须声明
credential后由宿主经ICredentialStore代取;EnforceAtRuntime = false时只审计不拦截(仅供排查兼容性问题,生产应保持true)。
生命周期与卸载语义
- 状态:
Installed→Enabled→Disabled(Error为异常分支),持久化后跨重启恢复:ScanAsync恢复记忆(上次Enabled的插件标记为待启用),RestoreEnabledAsync再实际启用它们。 - 禁用/卸载严格按 7 步:①
ShutdownAsync→ ② 注销 UI 贡献 → ③ 注销 Skill / MCP / 连接器工厂(必须先于 ALC 卸载,否则注册表里的实例与工厂委托会变成残留强引用、卸载必然失败)→ ④ 删除落盘的工作区文件式 Skill / MCP → ⑤AssemblyLoadContext.Unload()→ ⑥ 多轮GC.Collect+ 弱引用验证 → ⑦ 未通过则降级为Disabled并置RequiresRestart = true,提示用户重启、同时把引用链路写进诊断日志。 - 插件在
InitializeAsync中自行注册(而非清单声明)的侧栏条目 / Skill / MCP / 连接器工厂同样被记账,卸载时一并精确注销,避免"插件已卸载、入口仍在"的幽灵状态。 UpgradeAsync热替换:先对旧版本走完整卸载流程,卸载验证通过才复制新包并重新启用;验证未通过则中止升级(否则每升级一次就多泄漏一份程序集)。IPluginHost注册的 Skill / MCP 落到工作区级文件,因此卸载必须显式删除,否则宿主的LoadFromWorkspace()会把它们重新加载回来。- 插件内的 JSON 读写不得走反射式序列化器:
JsonSerializer.Deserialize<T>/Serialize<T>(T为插件自身类型)会在默认 ALC 里按「插件类型」缓存反射元数据(JsonTypeInfo/ 成员访问委托),把插件 ALC 永久钉住,使第 ⑥ 步的弱引用验证必然失败。请改用System.Text.Json源生成(JsonSerializerContext+[JsonSerializable])或 DOM API(JsonDocument/Utf8JsonWriter);插件内自建JsonSerializerOptions同样应避免(实测:反射路径钉住 ALC,源生成与 DOM 均可回收)。
支持的 AI Provider
| Provider | 显示名称 | 支持的模型 |
|---|---|---|
| openai | OpenAI | gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, gpt-4o, gpt-4o-mini, o1, o1-mini, o1-pro, o3, o3-mini, o3-pro, o4-mini |
| azure | Azure OpenAI | gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-4, gpt-35-turbo |
| deepseek | DeepSeek | deepseek-flash, deepseek-v4-pro |
| kimi | Kimi | kimi-k3, kimi-k2.7-code, kimi-k2.7-code-highspeed, kimi-k2.6 |
| glm | 智谱 GLM | glm-5.3, glm-5.3-flash, glm-5.2, glm-5.1, glm-5, glm-5-turbo, glm-4.7, glm-4.7-flash, glm-4.6, glm-4.5-air 等 |
| qwen | 通义千问 | qwen3.8-max, qwen3.8-flash, qwen3.7-plus, qwen3.6-plus, qwen3.5-omni-plus, qwen3-vl-plus, qvq-max 等 |
| doubao | 豆包 | doubao-1.5-vision-pro, doubao-1.5-vision-lite, doubao-vision-pro, doubao-vision-lite, Seed-Evolving, deepseek-v4.1-flash |
| claude | Claude | claude-opus-4-20250514, claude-sonnet-4-20250514, claude-3-7-sonnet-20250219, claude-3-5-sonnet-20241022, claude-3-5-haiku-20241022, claude-3-haiku-20240307 |
| gemini | Google Gemini | gemini-2.5-pro, gemini-2.5-flash, gemini-2.0-flash, gemini-2.0-flash-lite, gemini-1.5-pro, gemini-1.5-flash |
| ollama | Ollama (本地) | llama3.1, llama3.2, qwen2.5, deepseek-coder-v2, codellama |
| ernie | 百度文心一言 | ernie-4.5, ernie-4.0-turbo, ernie-4.0-vision, ernie-3.5-8k, ernie-speed-pro, ernie-lite-pro |
| minimax | MiniMax | MiniMax-M3, MiniMax-M2.7, MiniMax-M2.7-highspeed, MiniMax-M2.5, MiniMax-M2.5-highspeed, MiniMax-H3 |
| ark | 字节方舟 (火山引擎) | 无内置默认端点与默认模型(ProviderDefaults 未收录),须在配置中显式给出 BaseUrl 与 Model |
| bailian | 阿里百炼 | 无内置默认端点与默认模型(ProviderDefaults 未收录),须在配置中显式给出 BaseUrl 与 Model |
| hunyuan | 腾讯混元 | hunyuan-turbos-vision, hunyuan-t1-vision, hunyuan-turbos-vision-video, hunyuan-turbo, hunyuan-pro, hunyuan-standard, hunyuan-lite |
| mimo | 小米 MiMo | mimo-v2.5-pro |
| xai | xAI Grok | grok-4, grok-3, grok-3-mini, grok-3-fast, grok-2-vision |
| qianfan | 百度智能云千帆 | ernie-4.5, ernie-4.0-turbo, ernie-4.0-vision, ernie-3.5-8k, ernie-speed-pro, ernie-lite-pro |
| tencent-ti | 腾讯云 TI 平台 | hunyuan-turbos-vision, hunyuan-t1-vision, hunyuan-turbo, hunyuan-pro, hunyuan-standard, hunyuan-lite |
| huawei-pangu | 华为云盘古 | pangu-7b, pangu-13b, pangu-52b |
| bedrock | AWS Bedrock | anthropic.claude-opus-4-20250515-v1:0, anthropic.claude-sonnet-4-20250515-v1:0, anthropic.claude-3-5-sonnet-20241022-v1:0, meta.llama4-maverick-v1:0 等 |
| openrouter | OpenRouter | deepseek/deepseek-v4.1-flash, openai/gpt-4.1, openai/o3, anthropic/claude-opus-4, google/gemini-2.5-pro, meta/llama-4-maverick 等 |
项目结构
LuBan.AIAgent/
├── Abstractions/
│ ├── ILuBanToolPlugin.cs # 工具插件接口
│ ├── ToolPluginRegistry.cs # 插件注册表
│ ├── ToolConfirmationService.cs # 工具执行确认服务
│ ├── ToolAttribute.cs # 工具标注特性
│ ├── ToolResult.cs # 工具结果
│ └── IIdentifiable.cs # 可标识组件接口
├── Configuration/
│ ├── IAppConfigReader.cs # 应用配置只读接口
│ ├── IProviderRouter.cs # Provider 路由接口
│ ├── CustomSkillConfig.cs # 自定义 Skill 配置
│ ├── CustomRuleConfig.cs # 自定义规则配置
│ ├── McpServerConfig.cs # 外部 MCP 服务器配置(stdio/http/sse + url/headers/environment)
│ ├── McpManageToolOptions.cs # MCP 管理工具组选项
│ ├── ConnectorConfig.cs # 连接器声明配置(config.json connectors[])
│ ├── ConnectorManageToolOptions.cs # 连接器管理工具组选项
│ ├── PluginAssemblySharing.cs # 插件 ALC 共享程序集配置(必备集只读 + 追加列表)
│ ├── LuBanAgentOptions.cs # Agent 配置选项
│ ├── BrowserToolOptions.cs # 浏览器工具选项
│ ├── FileSystemToolOptions.cs # 文件系统工具选项
│ ├── ScriptToolOptions.cs # 脚本工具选项
│ ├── WebToolOptions.cs # Web 工具选项
│ ├── GitToolOptions.cs # Git 工具选项
│ ├── RetrievalToolOptions.cs # 检索工具选项
│ ├── LocalMemoryOptions.cs # 本地记忆选项
│ ├── ModelEndpointOptions.cs # 模型端点选项
│ ├── OrchestrationOptions.cs # 编排选项
│ ├── WikiToolOptions.cs # Wiki 工具选项
│ └── ToolGroupOptions.cs # 工具组配置
├── Infrastructure/
│ ├── PlaywrightSession.cs # Playwright 会话管理
│ ├── ProcessRunner.cs # 进程执行器
│ ├── LuaScriptRunner.cs # 内嵌 MoonSharp Lua 沙箱执行器
│ ├── ShellEnvironmentDetector.cs # Shell 运行环境探测与命令构造
│ └── PathGuard.cs # 路径安全守卫
├── Tools/
│ ├── Browser/BrowserToolPlugin.cs # 浏览器工具
│ ├── FileSystem/FileSystemToolPlugin.cs # 文件系统工具
│ ├── FileSystem/EditOperation.cs # 文件编辑操作模型
│ ├── Script/ScriptToolPlugin.cs # 脚本执行工具
│ ├── Git/ # Git 版本控制工具
│ │ └── GitToolPlugin.cs # Git 工具插件与工具组
│ ├── Web/WebToolPlugin.cs # Web 工具
│ ├── Context/
│ │ └── CompactContextToolPlugin.cs # 上下文压缩工具
│ ├── LocalMemory/LocalMemoryToolPlugin.cs # 本地记忆工具
│ ├── Retrieval/RetrievalToolPlugin.cs # 语义检索工具
│ ├── Wiki/ # LLM Wiki 知识库工具
│ │ ├── WikiToolPlugin.cs # wiki 工具插件(opt-in)
│ │ └── WikiToolGroup.cs # wiki 工具实现
│ ├── Orchestration/ # 编排工具
│ │ ├── OrchestrationToolPlugin.cs # 编排工具插件
│ │ └── OrchestrationToolGroup.cs # 编排工具组
│ └── ConnectorManage/ # 连接器管理工具(配置驱动,厂商无关)
│ ├── ConnectorManageToolPlugin.cs # 连接器管理工具组插件
│ └── ConnectorManageToolGroup.cs # 列表/新增/删除连接器声明
├── Skills/
│ ├── ISkill.cs # Skill 接口(含 PromptTemplate)
│ ├── SkillBase.cs # Skill 基类
│ ├── SkillRegistry.cs # Skill 注册表(合并多来源)
│ ├── SkillLoader.cs # SKILL.md 文件加载器
│ ├── SkillMdParser.cs # SKILL.md 解析器
│ ├── FileSkill.cs # 文件级 Skill 适配器
│ ├── CustomSkill.cs # 自定义 Skill 适配器
│ └── BuiltIn/
│ ├── BrainstormingSkill.cs # 头脑风暴
│ ├── CodeReviewSkill.cs # 代码审查
│ ├── DocumentationSkill.cs # 文档生成
│ ├── CodeRefactorSkill.cs # 代码重构
│ ├── TestGenerationSkill.cs # 测试生成
│ ├── CodeExplainSkill.cs # 代码解释
│ ├── DebugAssistantSkill.cs # 调试助手
│ ├── GitCommitSkill.cs # Git 提交
│ └── FindSkillsSkill.cs # 技能发现
├── Rules/
│ ├── IRule.cs # 规则接口
│ ├── RuleBase.cs # 规则基类
│ ├── RuleEngine.cs # 规则引擎
│ ├── RuleCheckedAIFunction.cs # 规则检查装饰器
│ ├── CustomRule.cs # 自定义规则适配器
│ └── BuiltIn/
│ └── PathAccessRule.cs # 路径访问规则
├── MCP/
│ ├── IMCPClient.cs # MCP 客户端接口
│ ├── MCPClientBase.cs # 客户端基类
│ ├── StdioMCPClient.cs # stdio JSON-RPC 客户端(启动前注入 environment)
│ ├── HttpMCPClient.cs # http(Streamable HTTP) / sse 客户端
│ ├── MCPClientFactory.cs # 外部客户端工厂(stdio/http/sse 分派收敛)
│ ├── IMcpConfigValueResolver.cs # 配置值解析契约($credential: 引用替换)
│ ├── CredentialValueResolver.cs # 默认解析实现(内联替换凭据引用)
│ ├── McpConfigSecurityValidator.cs # 外部 MCP 配置明文凭据门禁
│ ├── MCPRegistry.cs # MCP 注册表
│ ├── MCPToolPlugin.cs # MCP 工具插件
│ └── BuiltIn/
│ └── FileSystemMCPClient.cs # 文件系统 MCP 客户端
├── Connectors/ # 连接器体系(框架只含抽象与管理;厂商实现由产品/插件提供)
│ ├── IConnector.cs # 连接器契约 + MCP 暴露面 + 工厂入参/设置
│ ├── ConnectorBase.cs # 连接器抽象基类(幂等初始化 + 释放骨架,厂商无关)
│ ├── ConnectorFactoryRegistry.cs # 连接器工厂表(线程安全)+ 宿主级单例实例缓存
│ ├── ConnectorRegistry.cs # 会话级解析:声明/启用/五态目录/MCP 派生/工作区完整声明合并
│ ├── ConnectorWorkspaceEntry.cs # 工作区连接器条目(name/provider/settings/enabled,兼容旧 {enabled})
│ ├── IConnectorConfigWriter.cs # 连接器声明写入契约
│ ├── WorkspaceConnectorConfigWriter.cs # 默认写入实现(工作区文件 + 防穿越 + 凭据门禁)
│ ├── ConnectorSettingsSecurityValidator.cs # 写入明文凭据门禁($credential: 引用)
│ └── ConnectorServiceCollectionExtensions.cs # AddConnector / AddBuiltinConnectors
├── Attachments/
│ ├── IAttachmentProcessor.cs # 附件处理器接口
│ ├── DefaultAttachmentProcessor.cs # 默认实现(图片/文本)
│ ├── AttachmentInfo.cs # 附件元数据
│ ├── AttachmentKind.cs # 附件类型枚举
│ ├── ProcessedAttachment.cs # 处理结果
│ └── AttachmentMessageBuilder.cs # 附件 → ChatMessage 装配
├── Sessions/
│ ├── ISessionManager.cs # 会话管理接口
│ ├── AttachmentRecord.cs # 附件持久化记录
│ └── SessionChatHistoryProvider.cs # 会话历史提供者
├── Retrieval/
│ ├── IRetrievalService.cs # 语义检索接口
│ ├── RetrievalService.cs # 检索服务实现
│ ├── IndexProgress.cs # 索引进度模型(阶段/已完成/总数/当前文件)
│ └── Chunkers/ # 代码切块器
├── Wiki/ # LLM Wiki 知识库服务
│ ├── IWikiService.cs # wiki 服务接口
│ ├── IWikiContext.cs # 工作区上下文接口
│ ├── WikiService.cs # wiki 服务实现(index/log/索引维护)
│ ├── WikiDefaults.cs # 默认 schema 文案
│ ├── WikiFrontmatter.cs # YAML frontmatter 解析/渲染
│ ├── WikiPageSerializer.cs # 页面序列化
│ ├── WikiSlug.cs # 文件名 slug 生成
│ ├── Models.cs # 页面/索引/lint 模型
│ └── Extractors/ # 源文件提取器(txt/md/json/csv/xml/html/xlsx)
├── LocalMemory/
│ ├── ILocalMemoryService.cs # 本地记忆服务接口
│ ├── ILocalMemoryStore.cs # 本地记忆存储接口
│ ├── IWorkspaceContextProvider.cs # 工作区上下文提供者接口
│ ├── LocalMemoryService.cs # 本地记忆服务
│ ├── MemoryCategories.cs # 记忆分类
│ └── MemoryEntry.cs # 记忆条目模型
├── Utils/Text/
│ ├── TextUtils.cs # 文本处理工具
│ ├── NGramExtractor.cs # N-Gram 提取器
│ └── WildcardMatcher.cs # 通配符匹配
├── Orchestration/ # 多 Agent 编排子系统
│ ├── IOrchestrator.cs # 编排器接口
│ ├── Orchestrator.cs # 编排器默认实现
│ ├── DagScheduler.cs # DAG 调度器(拓扑分层并行)
│ ├── SubAgentFactory.cs # SubAgent 工厂
│ ├── SubAgentRoleRegistry.cs # SubAgent 角色注册表
│ ├── ContextStore.cs # 跨节点上下文存储
│ ├── Models/ # 数据模型
│ │ ├── TaskGraph.cs # 任务图谱
│ │ ├── TaskNode.cs # 任务节点
│ │ ├── TaskNodeStatus.cs # 节点状态枚举
│ │ ├── SubAgentSpec.cs # SubAgent 规格
│ │ ├── SubAgentRole.cs # SubAgent 角色定义
│ │ ├── NodeResult.cs # 节点结果
│ │ ├── OrchestrationResult.cs # 编排结果
│ │ ├── OrchestrationProgress.cs # 进度事件
│ │ ├── ProgressEventType.cs # 进度事件类型
│ │ └── ReflectionResult.cs # 反思结果与重规划上下文
│ ├── Planner/ # 任务规划器
│ │ ├── ITaskPlanner.cs # 规划器接口
│ │ └── LlmTaskPlanner.cs # LLM 规划器
│ ├── GraphPlanStore.cs # 任务图谱暂存
│ ├── IOrchestrationProgressSink.cs # 编排进度出口
│ └── Exceptions/ # 异常定义
│ ├── TaskPlanningException.cs # 规划异常
│ └── NodeExecutionException.cs # 节点执行异常
├── Plugins/ # 插件体系(应用级插件:清单 + 可回收 ALC 生命周期)
│ ├── Base/
│ │ ├── PluginBase.cs # 插件基类(Host/SafeLog/PostToUi + 初始化与关闭钩子)
│ │ └── BuiltinPluginCatalog.cs # 内置插件目录(随宿主发布)
│ ├── Contracts/ # 契约:IPlugin / IPluginHost / IPluginPanel / 状态仓储
│ │ ├── IPlugin.cs # 插件契约
│ │ ├── IPluginHost.cs # 宿主能力契约(侧栏/面板/Skill/MCP/日志/UI 回调)
│ │ ├── IPluginPanel.cs # 插件面板契约(UI 无关)
│ │ ├── IPluginStateRepository.cs # 状态持久化契约
│ │ ├── PluginManifest.cs # plugin.json 清单模型
│ │ ├── PluginPermissions.cs # 权限声明(7 维度含 connectors + 数组/对象双形态 JSON 转换器)
│ │ ├── PluginSidebarEntry.cs # 侧栏条目声明
│ │ ├── PluginCommandDescriptor.cs # 命令声明
│ │ ├── SkillDefinition.cs # 插件贡献的 Skill 声明
│ │ └── PluginState.cs # 生命周期状态枚举(4 态)
│ ├── Loading/
│ │ ├── PluginLoader.cs # 加载入口(清单 + 入口程序集 + IPlugin 实例)
│ │ ├── PluginFactory.cs # IPlugin 反射实例化(带 IL2067 抑制)
│ │ ├── PluginLocation.cs # 目录约定与解析(仅应用级)
│ │ ├── ManifestValidator.cs # 清单校验
│ │ └── PluginDependencyResolver.cs# 依赖拓扑与环检测
│ ├── Lifecycle/
│ │ ├── PluginManager.cs # 扫描/启用/禁用/安装/升级/卸载编排 + 7 步卸载与 GC 验证
│ │ ├── PluginLoadContext.cs # 可回收 AssemblyLoadContext(lib/ 优先,根部回退;共享集可配置)
│ │ ├── PluginHostScope.cs # 宿主能力代理 + 贡献记账
│ │ └── PluginStateRepository.cs # 状态仓储 JSON 默认实现
│ ├── Security/
│ │ ├── PluginSecurityOptions.cs # 权限白名单策略(网络/进程/Git/文件系统/凭据目录/连接器提供方)
│ │ ├── PluginPermissionEvaluator.cs # 声明期覆盖校验 + 运行期越界判定
│ │ ├── PluginPermissionGuard.cs # 运行期出口门禁 + 有界越界审计
│ │ ├── PluginScopeContext.cs # 权限环境(AsyncLocal)传递
│ │ ├── CredentialKeys.cs # 凭据键归一化(框架无厂商拼写表)
│ │ ├── ICredentialKeyAliases.cs # 宿主提供的厂商键别名表(规范键/环境变量名)
│ │ ├── ICredentialStore.cs # 凭据存储契约
│ │ └── ConfigurationCredentialStore.cs # 默认「配置 + 环境变量」只读实现
│ └── Schemas/
│ └── plugin.schema.json # plugin.json 的 JSON Schema(随包发布)
├── Hosting/ # 宿主层(会话作用域 / 运行循环 / Profile / 附件编排 / 命令清单)
│ ├── IAgentHost.cs # 宿主入口(按会话路由流式对话)
│ ├── AgentHost.cs # 宿主默认实现(无状态路由器)
│ ├── AgentRunRequest.cs # 一轮对话入参
│ ├── AgentStreamEvent.cs # UI 无关流式事件(文本/思考/工具/错误/编排/附件)
│ ├── SessionRuntimeManager.cs # 会话运行时表(每会话独立 DI scope)
│ ├── SessionRuntime.cs # 会话运行时(串行运行循环 + 重载标记)
│ ├── SessionRuntimeSeed.cs # 会话初始化种子(用户/工作区)
│ ├── IAgentProfile.cs # Agent 配置契约
│ ├── AgentProfileBase.cs # Agent 配置基类(系统提示词 + 建 Agent 流程)
│ ├── DefaultAgentProfile.cs # 默认通用助手 Profile
│ ├── IAgentProfileResolver.cs # Profile 解析契约
│ ├── IAgentWorkspaceResolver.cs # 工作区解析契约
│ ├── WorkspaceDescriptor.cs # 工作区描述(Id/Name/RootPath/Type)
│ ├── IAgentUserResolver.cs # 用户标识解析契约
│ ├── IAgentModelSelection.cs # 模型选择契约
│ ├── DefaultSeams.cs # 工作区/Profile/用户/模型选择的默认实现
│ ├── IAgentAttachmentOrchestrator.cs # 附件编排契约(引用解析/处理/门禁/探测)
│ ├── DefaultAgentAttachmentOrchestrator.cs # 默认附件编排
│ ├── AgentAttachmentResolver.cs # UI 路径与 @引用 合并去重
│ ├── IModelCapabilityGate.cs # 附件能力门禁 + 单轮视觉探针
│ ├── ISessionRuntimeInitializer.cs # 会话 scope 初始化扩展点(含空实现)
│ ├── IAgentSessionExtension.cs # 建 Agent 前的会话扩展点
│ ├── ToolConfirmationContextExtensions.cs # 每轮确认上下文装配
│ └── Commands/ # 两端共享的斜杠命令清单
│ ├── ICommandCatalog.cs # 命令查询契约(全部/前缀匹配/精确查找)
│ ├── CommandCatalog.cs # 默认清单
│ └── SlashCommandDefinition.cs # 命令元数据 + 客户端标记
├── LuBanAgent.cs # Agent 实例
├── LuBanAgentFactory.cs # Agent 工厂
├── LuBanAgentExtensions.cs # DI 扩展方法
├── LuBanAgentHostExtensions.cs # 宿主注册扩展(AddLuBanAgentHost)
├── LuBanAgentOpenAIExtensions.cs # OpenAI 兼容 Provider 注册扩展(AddLuBanAgentOpenAI)
├── SanitizingChatClient.cs # 聊天客户端消毒器
├── AIFunctionFactoryHelper.cs # AI 函数工厂辅助类
└── ILuBanAgentFactory.cs # Agent 工厂接口
小贴士
- 模型路由使用
provider:model格式,新增 Provider 只需通过IAppConfigReader/ 宿主实现添加 - 16 大内置工具组覆盖浏览器自动化、文件操作、脚本执行、Git 版本控制、Web 请求、语义检索、上下文压缩、本地记忆、MCP、多 Agent 编排、LLM Wiki 知识库(opt-in)、大日志分析、Skill 消费、Skill 管理、MCP 管理、连接器管理
ToolConfirmationService对工作区外路径访问、写入、删除、执行等敏感操作要求用户确认;工作区内直接放行- 授权三档记忆(本次 / 本轮 / 本会话),按路径所在根粒度生效;删除类工具(
AlwaysConfirmTools)不记忆、每次必确认 FileSystemToolOptions.AllowedRoots与工作区根共同构成可信范围,范围内的操作免确认- 会话历史自动持久化,支持长对话压缩(SummarizingChatReducer),上下文永不丢失;启动对话时显示最近历史,快速了解上下文
- 自定义 Skill/Rule/MCP 持久化,配置保存到本地文件,重启后自动加载
- 文件化 Skill:支持通过 SKILL.md 文件定义 Skill,兼容 OpenCode 格式,项目级/用户级目录自动加载
- 规则拦截在工具执行前自动检查,支持 deny/allow/modify
- MCP 工具集成,外部 MCP 服务器工具自动暴露给 Agent
- 通过
ExternalPlugins配置可热加载外部工具插件程序集 - 插件体系:应用级插件(
plugins/<id>/+plugin.json)走可回收 ALC,支持启用/禁用/升级/卸载;卸载按 7 步顺序断引用并做 GC 弱引用验证,未通过则降级Disabled并提示重启 - 结合 LuBan.AIFlow 可对接 RagFlow / Dify / Coze 等 AI 平台
- 多 Agent 编排:复合任务自动拆解为 DAG,SubAgent 串行/并行混合执行,支持关键节点失败跳过、超时控制、上下文传递
- 附件支持:
IAttachmentProcessor统一处理图片与文本文件;图片本地缩放后以 base64DataContent发送,大文本仅注入路径指引;会话仅持久化路径与元数据
许可证
Copyright (c) yswenli.
Licensed under the Apache License 2.0.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- LuBan.Common (>= 2026.11.9.1)
- LuBan.DI (>= 2026.11.9.1)
- LuBan.Threading (>= 2026.11.9.1)
- Microsoft.Agents.AI.Foundry (>= 1.5.0)
- Microsoft.Extensions.AI (>= 10.11.0)
- Microsoft.Extensions.AI.OpenAI (>= 10.11.0)
- Microsoft.Playwright (>= 1.64.1)
- MiniExcel (>= 1.46.0)
- MoonSharp (>= 2.0.0)
- OpenAI (>= 2.14.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on LuBan.AIAgent:
| Package | Downloads |
|---|---|
|
LuBan.Web.Core
LuBan Framework中api核心功能项目,基于aspnetcore集成di、jwt、swagger、codefirtst、支持多种常见数据库、nacos配置中心、统一接口回复参数、全局异常捕获、全局接口日志、防重放攻击、图形验证码、快捷上下文对象、上传下载、数据导入导出等功能 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.11.9.1 | 109 | 11/9/2026 |
| 2026.11.2.1 | 156 | 11/2/2026 |
| 2026.10.27.1 | 106 | 10/27/2026 |
| 2026.10.23.1 | 98 | 10/23/2026 |
| 2026.10.20.1 | 110 | 10/20/2026 |
| 2026.10.9.1 | 111 | 10/9/2026 |
| 2026.10.8.1 | 106 | 10/8/2026 |
| 2026.9.22.1 | 128 | 9/22/2026 |
| 2026.9.21.1 | 130 | 9/21/2026 |
| 2026.9.20.1 | 134 | 9/20/2026 |
| 2026.9.18.1 | 125 | 9/18/2026 |
| 2026.9.16.1 | 128 | 9/16/2026 |
| 2026.9.11.1 | 131 | 9/11/2026 |
| 2026.9.10.2 | 147 | 9/10/2026 |
| 2026.9.10.1 | 127 | 9/10/2026 |
| 2026.9.8.2 | 136 | 9/8/2026 |
| 2026.9.8.1 | 144 | 9/8/2026 |
| 2026.9.7.1 | 132 | 9/7/2026 |
| 2026.9.4.2 | 125 | 9/4/2026 |
| 2026.9.4.1 | 138 | 9/4/2026 |