Ohhnews

分类导航

$ cd ..
foojay原文

BoxLang AI v3发布:引入多智能体编排、AI技能系统及工具链全面升级

#boxlang#人工智能#多智能体#软件开发#开发工具

目录

我们已经很久没有发布如此重大的更新了。BoxLang AI 3.0 对 BoxLang 生态系统中 AI Agent(智能体)、模型和工具的运作方式进行了彻底的重构,并一次性带来了十大核心功能。

最引人注目的是 AI 技能系统(AI Skills system):这是对 Anthropic Agent Skills 开放标准的一流实现,允许你定义可重用的知识块,如:编码风格、领域规则、语气策略、API 指南等。只需在 SKILL.md 文件中定义一次,即可在运行时将其注入到任意数量的 Agent 和模型中。告别到处复制粘贴相同的系统提示词模板。技能支持版本控制、可组合,并提供两种模式:常驻模式(每次调用均包含完整内容)和懒加载模式(仅包含名称+描述,直到 LLM 请求更多信息时才加载)。

这仅仅是个开始,以下是 3.0 版本的所有更新:

  • 🎯 AI 技能系统 --- 可组合、基于文件的知识块,可在运行时注入到任何 Agent 或模型中
  • 🔌 MCP 服务器注入 --- Agent 可自动发现并注册来自任何 MCP 服务器的工具
  • 🗄️ 全球 AI 工具注册表 --- 统一按名称注册工具,在任何地方以字符串形式引用
  • 🔧 工具系统大改版 --- 全新的 BaseTool / ClosureTool 架构,外加两个内置核心工具
  • 🛡️ 提供商能力系统 --- 类型安全的能力检测,并提供明确的 UnsupportedCapability 错误提示
  • 🌲 父子 Agent 层级结构 --- 支持循环检测和深度追踪的多 Agent 编排树
  • 🧵 中间件支持 --- 六个内置中间件类,用于日志记录、重试、护栏(Guardrails)等
  • 🏢 无状态 Agent + 逐次调用身份路由 --- 跨并发请求的安全多租户内存管理
  • 🤗 HuggingFace 嵌入 --- 用于 HuggingFace 推理 API 的新提供商
  • 🔀 自定义服务 URL --- 支持所有提供商的代理和自托管端点 查看完整更新日志:https://ai.ortusbooks.com/readme/release-history/3.0.0

如果你一直在使用 BoxLang 构建 AI 应用,这次发布将改变一切。如果你还没有开始,那么这个版本绝对值得你尝试。

让我们深入了解一下。🎉


🎯 核心亮点:AI 技能系统

3.0 中最重大的新增功能是 AI 技能系统,这是对 Anthropic Agent Skills 开放标准的一流实现。

可以将“技能”视为一个可移植、可重用的专业知识单元:SQL 编码风格指南、语气策略、领域特定规则、API 速查表等——即任何你的 AI 在开始回答之前应该“知道”的内容。只需在 SKILL.md 文件中定义一次,即可在运行时将其注入到任意数量的 Agent 和模型中。无需再在构建的每个 Agent 中复制粘贴相同的系统提示词模板。

$ node
// 从文件加载技能
apiSkill = aiSkill( ".ai/skills/api-guidelines/SKILL.md" )

// 加载目录树中的所有技能
allSkills = aiSkill( ".ai/skills/", recurse: true )

// 用于简短、独立指导的内联技能
sqlStyle = aiSkill(
    name        : "sql-style",
    description : "SQL 编码标准",
    content     : "始终使用 snake_case。优先使用 CTE。禁止使用 SELECT *。"
)

技能有两种注入模式:

  • 常驻模式(Always-on) --- 每次 LLM 调用都包含完整内容。零延迟。最适合语气和格式等简短、通用的规则。
  • 懒加载模式(Lazy) --- 系统消息中仅包含名称和一行描述。LLM 会调用内置的 loadSkill( name ) 工具来按需获取完整内容。非常适合大型技能库,当大多数技能与当前查询无关时,这能有效降低 token 消耗。

你甚至可以在会话中期将懒加载技能“升级”为常驻模式:

$ node
// 用户提到 SQL 工作后,在剩余对话中预加载该技能
agent.activateSkill( "sql-style" )

如果你希望某些技能对应用中的 每个 Agent 都可用,无需显式传递:

$ node
// 在 Application.bx 中 --- 每个 Agent 都会自动继承这些技能
aiGlobalSkills().add( aiSkill( ".ai/skills/company-tone/SKILL.md" ) )
aiGlobalSkills().add( aiSkill( ".ai/skills/security-policy/SKILL.md" ) )

技能以纯 Markdown 文件形式存在,这意味着你的团队可以在 Pull Request 中审核、对比差异,并与代码库的其他部分保持同步。这是告别“提示词漂移”的终极方案。


📚 全新文档

整个文档已重新组织,助你从入门到精通。新增了大量章节,并提供了更直接的文档供你阅读:https://ai.ortusbooks.com/

🔌 MCP 服务器注入

现在可以将 Agent 直接指向一个或多个 MCP 服务器。这些服务器暴露的所有工具都会通过 listTools() 自动发现,并注册为 MCPTool 实例,无需手动构建工具。

$ node
agent = aiAgent(
    name       : "data-analyst",
    mcpServers : [
        { url: "http://localhost:3001", token: "secret" },
        "http://internal-tools-server:3002"
    ]
)

或使用流式写法:

$ node
agent = aiAgent( "analyst" )
    .withMCPServer( "http://localhost:3001", { token: "secret" } )
    .withMCPServer( mcpClientInstance )

Agent 的系统提示词会自动更新,以便 LLM 知道哪些工具来自哪个服务器。MCP 服务器也会呈现在 getConfig() 的输出中,以实现全面可观测性。


🗄️ 全球 AI 工具注册表

3.0 新增功能:可通过 aiToolRegistry() BIF 访问的模块级 全局工具注册表。在 Application.bxModuleConfig.bx 中按名称注册一次工具,即可在代码库的任何位置以纯字符串形式引用它们。

$ node
// 注册一次
aiToolRegistry().register( "searchProducts", productSearchTool )
aiToolRegistry().register( "getWeather@myapp", weatherTool )

// 在任何地方按名称引用 --- 无需实时对象引用
result = aiChat(
    "查找 50 美元以下的无线耳机",
    { tools: [ "searchProducts", "getWeather@myapp" ] }
)

模块命名空间(例如 now@bxai)确保了注册信息在不同模块间不会冲突。两个新的拦截点 —— onAIToolRegistryRegisteronAIToolRegistryUnregister —— 为审计和生命周期管理提供了钩子。


🔧 工具系统大改版

工具系统围绕全新的 BaseTool 抽象基类进行了重大重构。所有工具实现都扩展自该类,从而免费获得共享的调用生命周期、结果序列化和流畅的 describeArg() 注解语法。

旧的 Tool.bx 已被 ClosureTool 取代 —— 这是一个由任何闭包或 lambda 支持的 BaseTool 子类,它会自动内省可调用对象的参数元数据,以生成兼容 OpenAI 的函数模式。

$ node
searchTool = aiTool(
    "searchKB",
    "搜索知识库",
    function( required string query, numeric maxResults = 5 ) {
        return knowledgeBase.search( query, maxResults )
    }
)

模块内置了两个 核心工具

  • now@bxai --- 模块加载时自动注册,返回 ISO 8601 格式的当前日期/时间。每个 Agent 都能免费获得时间感知能力,无需配置。
  • httpGet --- 仅限选择性启用(出于安全考虑,不会自动注册),通过 HTTP GET 获取任何 URL 的内容。

now@bxai 的自动注册非常值得一提。目前没有任何主流 AI 框架开箱即用内置此类工具。这是一个真正的差异化优势 —— 你的 Agent 无需任何额外配置就能“知道现在的时间”。


🛡️ 提供商能力系统

全新的类型安全能力系统可防止在提供商上调用不支持的操作,并提供清晰、可操作的错误提示,而不是晦涩的运行时崩溃。

$ node
service = aiService( "voyage" )
println( service.getCapabilities() )          // [ "embeddings" ]
println( service.hasCapability( "chat" ) )    // false

aiChat()aiChatStream()aiEmbed() 现在会在调用前检查提供商能力,如果条件不满足,则会抛出清晰的 UnsupportedCapability 异常。告别排查神秘的提供商报错。


🌲 父子 Agent 层级结构

多 Agent 编排现在是一等公民。AiAgent 会跟踪其在 Agent 树中的位置,并支持完整的内省、循环检测和深度追踪。

$ node
coordinator = aiAgent( name: "coordinator" )
    .addSubAgent( aiAgent( name: "researcher" ) )
    .addSubAgent( aiAgent( name: "writer" ) )

println( coordinator.isRootAgent() )         // true
println( researcherAgent.getAgentDepth() )   // 1
println( writerAgent.getAgentPath() )        // /coordinator/writer
println( researcherAgent.getAncestors() )    // [ coordinator ]

addSubAgent() 会自动关联父子关系。getConfig() 会暴露 parentAgentagentDepthagentPath 以实现全面可观测性。


🧵 中间件支持

AiModelAiAgent 现在都支持可组合的 中间件,用于处理横切关注点——日志记录、重试、护栏、人工审核等。在执行链中,Agent 中间件位于模型中间件之前。

3.0 内置了 六个中间件类

中间件功能描述
LoggingMiddleware审计每次 LLM 调用和工具执行
RetryMiddleware针对速率限制和瞬态错误的指数退避重试
GuardrailMiddleware拦截危险工具并使用正则表达式验证参数
MaxToolCallsMiddleware限制单次运行的工具调用次数,防止 Agent 失控
HumanInTheLoopMiddleware在敏感工具执行前要求人工明确批准
FlightRecorderMiddleware将真实运行记录为 JSON 固定装置(fixtures),以便在 CI 中离线回放

FlightRecorderMiddleware 特别值得一提 —— 它是一个测试利器。记录一次真实的 Agent 运行,提交该固定装置,即可在 CI 中进行确定性回放,无需进行任何实时调用。

$ node
// 记录真实运行
agent = aiAgent( "weather-bot", middleware: new FlightRecorderMiddleware( mode: "record" ) )
agent.run( "伦敦天气怎么样?" )
// → 写入:.ai/flight-recorder/weather-bot-<timestamp>.json

// 在 CI 中回放 --- 无实时调用,完全确定性
agent = aiAgent(
    "weather-bot",
    middleware: new FlightRecorderMiddleware(
        mode        : "replay",
        fixturePath : "tests/fixtures/weather-bot.json"
    )
)

🏢 无状态 Agent + 逐次调用身份路由

AiAgent 现在是 完全无状态的userIdconversationId 会从 options 参数中按次解析,消除了多用户部署中的共享状态并发错误。

每种内存类型(IAiMemoryIVectorMemory)现在在 add()getAll()clear() 等方法上都接受可选的 userIdconversationId —— 因此单个内存实例可以安全地为多个租户服务:

$ node
sharedMemory = aiMemory( "cache" )

sharedMemory.add( message, userId: "alice", conversationId: "conv-1" )
sharedMemory.add( message, userId: "bob",   conversationId: "conv-2" )
sharedMemory.getAll( userId: "alice", conversationId: "conv-1" )

其他更新

  • 🤗 HuggingFace 嵌入 --- 新增用于 HuggingFace 推理 API 的 huggingface 提供商
  • 🔀 自定义服务 URL --- 所有发送端现在都接受 baseUrl 覆盖,支持代理、自托管端点和兼容 OpenAI 的 API
  • 🏗️ BaseServiceOpenAIService 拆分 --- BaseService 现在真正实现了与提供商无关,使得自定义提供商的实现更加清晰
  • 🐛 流式事件修复 --- 修复了 beforeAIModelInvoke/afterAIModelInvoke 事件在流式传输时未触发的问题
  • 🐛 MCP requestId 为空导致崩溃 --- 修复了在故意省略 id 的 JSON-RPC 通知时导致的崩溃

无破坏性变更

3.0 是一个重大版本,但你现有的代码将继续运行。aiChat()aiEmbed()aiAgent() 的 BIF 签名保持不变。升级、运行测试,然后开始探索新的 API 吧。


快速入门

$ bash
# 通过 BoxLang 安装或升级模块
install-bx-module bx-ai

# 通过 CommandBox 安装或升级
install bx-ai

📖 完整文档

🛠️ 更新日志

🐛 报告问题

💬 社区 Slack