@ai-zen/代理人-sdk
AI-Zen SDK——共享商业逻辑层,为CLI和桌面提供统一的Agent运行时间. 工作在框外,有预配置的供应商设置,默认代理,以及默认的子代理.
真相来源
docs/sdk-design-v1.md 是这个软件包设计的唯一的真理来源。 所有执行都必须符合该文件。 (前置设计保留在 docs/sdk-design-v0.md. ) (中文(简体) )
建筑
CLI ──┐
├── @ai-zen/agents-sdk ──┐
Desktop ──┘ │
LLM API
模块层
types ← pure types, zero business dependencies (incl. ToolEnv)
config ← ConfigManager + constants: config.json read/write + directory setup + factory defaults
crud ← capability-entity CRUD (Agent definitions; conversations/drafts are persisted by each consumer)
runtime ← model factory + Agent assembly + task handoff/migration (cancellable via `AbortSignal`; createModel / createAgent / SdkAgent / HandoffService / HandoffGuardPlugin)
scope ← Scope orchestration container + ScopePlugin contract + PermissionEvaluator / disclosure + plugins/ (5 self-contained capability sources: discovery + tools + plugin)
agent-plugins ← Agent plugins (autoMigrate, autoRefreshTools, contextGuard, unknownToolHint)
shared ← content blocks (file → content block transport), entity repository, logging, errors
依赖方向 : agent-plugins → runtime → scope· ; runtime → scope / crud / shared / types, (中文(简体) ), scope → types / shared。上层依赖于下层.
核心概念
| 实体 | 说明 |
|---|---|
| 范围 | 管弦乐容器:全球背景config 编号 : cwd 编号 : agentsDir+ 三相能力管道(发现-过滤-即时)+插件注册. 通过下列方式明确组装 scope.use(...) |
| 范围宽度 | 能力插件(v1扩展点):自有一种能力源的发现状态,候选名称,以及即时(discover 编号 : candidates 编号 : instantiate 编号 : dispose. 5个标准插件船出箱,通过组装 allInOne() |
| 工具Env 系统 | 工具环境 { cwd, config }; 内置工具插件时注入(BuiltinToolsScopePlugin即时工具,作为相对路径分辨率和配置读取的基础 |
| SdkCallback 工具软件 | 内置工具摘要库 : env 建构器注射+子类 call() + 键 resolve() 相对路径分辨率 |
| Sdk代理代理商 | 扩展核心代理, 携带 SDK 元数据, 支持 use() 插件注册 |
| 代理缓冲 | 插件接口 (E)onInit, (中文(简体) ), onBeforeSend, (中文(简体) ), onAfterSend, (中文(简体) ), onInnerLoopStart, (中文(简体) ), onInnerLoopEnd, (中文(简体) ), onInnerLoopsStart, (中文(简体) ), onInnerLoopsEnd, (中文(简体) ), onToolCall, (中文(简体) ), onUnknownTool, (中文(简体) ), onSubAgentStart, (中文(简体) ), onSubAgentEnd(中文(简体) ) |
| 终点 | API 端点( baseUrl + apiKey) |
| 型号 | 模型配置, 绑定到终点 |
| 子代理 | 有个特工 function 字段,可被其他代理人调用为工具 |
权限模式
这四个维度是独立的;允许/拒绝是相互排斥的,没有匹配手段否认,允许是披露(被否定的项目是LLM完全看不见的).
Agent.permissions
├── tools: { allow: string[] } | { deny: string[] }
├── skills: { allow: string[] } | { deny: string[] }
├── mcps: { allow: string[] } | { deny: string[] }
└── subagents: { allow: string[] } | { deny: string[] }
消费
const scope = new Scope({
config,
cwd: "/path/to/workspace", // one working directory per Scope; parallel sessions don't interfere
agentsDir,
}).use(
...allInOne({ skillsPaths, toolsPaths, subAgentsPaths, mcpPaths }),
);
await scope.init();
const agent = await createAgent(scope, "my-agent");
const handoffService = new HandoffService({ handoffDir: "/work/.ai-zen/handoffs", skillDirs });
agent.use(new ContextGuardPlugin({ guardTokens, isSuspended: () => handoffService.busy }));
agent.use(new AutoMigratePlugin({ service: handoffService, handoffTokens }));
agent.use(new AutoRefreshToolsPlugin());
agent.use(new UnknownToolHintPlugin({ scope }));
await agent.init();
await agent.send("Hello");
await scope.dispose(); // disconnect MCP, release plugin resources
发展状况
| 模块 | 状态 |
|---|---|
types | 已执行——核心实体、许可模式、MCP类型完成 |
config | 已执行 – 配置管理器 + 工厂默认 + 一发的靴子 |
crud | * 已执行——代理公司CRUD等能力实体(每个消费者坚持谈判/草稿) |
scope | 已执行 — 范围 + 范围 Plugin + 5个标准插件( 已建入/ 用户工具 / 技能 / mcp/ 子代理) + 全部 InOne |
runtime | 已执行——创建代理、MCP连接管理、任务迁移 |
agent-plugins | QQ已执行 — AutoMigrate Plugin / Auto RefreshTools Plugin / ContextGuardPlugin / 未知的ToolsHintPlugin |
shared | 已执行 — SdkError + 可注射 Logger |
内建工具
所有内置工具都是类( 计划) SdkCallbackTool),由内置工具插件(BuiltinToolsScopePlugin带有 ToolEnv ——每条范围一组实例 cwd 注射和相对路径 Scope.cwd从不依赖于全球 process.cwd()。 。 。 .
| 工具 | 说明 |
|---|---|
cwd | 获取当前工作目录 |
read | 读取文件( 可选) range 用于行/行切;超大输出警告并提示分批读取) |
inspect_file | 检查文件的结构概览( 行数、列分布等); 流出扫描,不受300KB读取阈值的限制 |
write | 写入文件 |
exec | 执行命令( 支持) timeout; 超大小 stdout+sderr 被丢弃到 stdout.log 编号 : stderr.log(中文(简体) ) |
spawn | 同步执行命令, 立即返回而不等待 |
mkdir | 创建目录 |
rm | 删除文件或目录 |
glob | 使用 glob 模式扫描并查找文件( 过度的输出倾倒到 result.json(中文(简体) ) |
ls | 列出目录内容( 过度大小的输出倾销到 result.json(中文(简体) ) |
exist | 检查文件或目录是否存在 |
find_text | 在文件中搜索文本或正则ex( 过度的输出倾斜到 result.json(中文(简体) ) |
download_file | 从 URL 下载一个文件并在当地保存 |
rename | 重命名或移动文件/目录 |
copy | 复制文件或目录 |
batch_edit | 批量编辑文件文本( 只有未匹配的项目被回放; 成功的项目被计数) |
edit | 在文件中编辑文本 |
sleep | 等待指定数毫秒 |
基于活性模型/配置的有条件注入:
| 工具 | 注射条件 | 说明 |
|---|---|---|
generate_image | 只有当 defaultImageModel 已配置 | 从文本描述生成图像 |
view_image | 仅用于视觉模型(代理 modelId 决意以 vision: true(中文(简体) ) | 查看/分析一个图像: 本地图像通过文件 API 自动上载, 网络 URL 直接引用 |
工具输出保护 : AppConfig.maxToolOutput (以字符表示,默认为32768)是工具输出的统一上限. 每一个工具都自相残杀—— exec 垃圾场 stdout.log 编号 : stderr.log 单独(每流返回头/尾预览), find_text 编号 : glob 编号 : ls 倾出 result.json (返回头部预览),和 read 只有警告和建议分批读取 range垃圾倒进 <tmpdir>/ai-zen/tool-output/<tool>-<timestamp>-<random>/,每个呼叫一个目录,没有自我清理。 见 docs/sdk-design-v1.md 第12节。 。 。 .
中断策略存在于配置中 : AppConfig.abortedMessageStrategy (单位:千美元)keep 编号 : drop工厂 keep ——模型在中断后可以继续半句判决)并 AppConfig.abortedToolRoundStrategy (单位:千美元)fill 编号 : drop工厂 fill 整个回合进出,因为 tool_calls (b) 与结果挂钩. createAgent() 读取他们从 scope.config 当没有通过明确的选择时,应当保持一个单一的真理来源.
内置插件
| 插件 | 说明 |
|---|---|
AutoMigratePlugin | 自动触发任务迁移时 usage.prompt_tokens 超过 handoffTokens; 代表向注射者的实际迁移 HandoffService (处理历史 strategy默认 omit 保持可审计,可选 prune 丢掉它. resolveMode 让呼叫者选择交接执行人或者跳过回合. 边走边走 service.busy 避免交接 移相 接相 |
AutoRefreshToolsPlugin | 在每个文件系统之前重新扫描文件系统 send() 以刷新工具列表 |
ContextGuardPlugin | 上下文安全警卫——在每次请求之前投出 ContextOverflowError (中断谈话) 当前一轮 usage.prompt_tokens 超过 guardTokens (一个绝对值:没有乘数,没有更松散的分级),防止上下文读取过大的文件. isSuspended() 让警卫自己站到一边 交接/移民转身 |
UnknownToolHintPlugin | 更聪明的未知工具提示——当LLM调用一个不存在的工具时,引导它到 call_mcp_tool / 指出基于 MCP 配置的许可问题( opt- in通过 agent.use(中文(简体) ) |
语言
这个SDK是 仅英文:每个模型造型和用户造型的字符串——工具计划描述,工厂提示,运行时注入的指针,工具结果,出错信息,工厂目录数据——是一个固定的英文文字. 没有本地化字段, 没有消息目录, 没有运行时语言切换 。 UI语言完全属于每个消费者(CLI) i18n/,桌面语言设置).
这是一个性能界限,而不是一个方便的选择—— SDK 行为和性能不得因用户语言而异数字 :
- 门槛是绝对的.
Model.tokenThresholds.handoff编号 :guard财务报告和审定财务报表AppConfig.maxToolOutput是绝对符号 / 字符数。 一个本地化的工具计划是一个不同的符号计数,所以交接和上下文护卫会绊倒 不同数量的实际内容 相同项目config.json——每个语言都具有相同的配置,不同的行为. - 斯克马的费用每轮都要付. 描述文本在每次请求时都会重新得到同意,因此一个符号三角洲是请求大小,上下文使用和花费的常态成本,而不是一次性成本.
- 缓存前缀不再具有可比性 . 前缀上的快速缓存匹配;让语言进入 SDK 将一个代码路径的前缀形状相乘并去除基准所依赖的单个变量.
- 诊断需要一种形状. 性能数据,bug复制和工具调用成功率必须在用户之间进行比较;一旦行为与地语相去甚远,每个结论都需要"先使用什么语言"的修饰语.
按照用户的语言,由工厂系统的一个语言中性指示处理,即时—— Always reply in the same language the user writes in. 适应每名 消息 而不是每个安装, 不需要本地管道 在SDK。 充分理由: docs/sdk-design-v1.md 第1节。 。 。 .
设计原则
见项目总库 PRINCIPLES.md数字 :
- 逻辑一致性
- 首先设计文件作为真相的来源
- 对称性和统一性
- 没有过度工程
- 奥卡姆的剃刀
- 继续重排; 保持清洁层
- 测试是基础