ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

baml-swift:在 Swift 与 Xcode 项目中集成 BAML 运行时(SwiftPM + XCFramework 分发实战指南)

baml-swift:在 Swift 与 Xcode 项目中集成 BAML 运行时(SwiftPM + XCFramework 分发实战指南) 编程语言AI Agent编译器CLI人工智能【免费下载链接】bamlThe programming language for agents项目地址https://gitcode.com/gh_mirrors/ba/baml点击查看免费下载BAML 是为 Agent 打造的编程语言其 Swift 侧运行时通过独立的 SwiftPM 包baml-swift对外分发包内包含纯 Swift 的BamlBridge运行时层以及基于 Rustbridge_cffi编译而成的原生BamlBridgeFFIXCFramework覆盖 macOS arm64/x86_64、iOS 真机与模拟器。本文以仓库中 baml_language/sdks/swift/mirror/README.md 为主线讲解它的发布机制、在 SwiftPM / Xcode 中的接入方式、用bamlCLI 生成类型化 SDK 的完整流程并结合仓库源码剖析运行时桥接与版本握手原理读完即可在你的 Swift / iOS 工程中落地 BAML。一、包结构运行时与原生桥的分层baml-swift由两个协作的部分组成BamlBridge纯 Swift 运行时包负责参数编码、结果解码、回调分发、类型系统与流式 API是应用直接 import 的库BamlBridgeFFI原生 XCFramework由 Rust 侧bridge_cffi经 baml_language/sdks/swift/rust/bridge_swift/src/lib.rs 封装为 staticlib 后打包而成包含 macOS arm64/x86_64、iOS 真机与模拟器多个切片。从源码结构看Swift 运行时目录 Sources/BamlBridge 中的核心文件包括文件职责Runtime.swift进程级全局BamlRuntimeC ABI 入口封装、回调注册、同步/异步调用RuntimeIdentity.swift桥接身份信息语言名、工具链版本、运行时版本Stream.swiftBamlStream流式 APInext/finalHandle.swift引擎侧资源的句柄管理与释放媒体、$rust_type字段等Encode.swift/Decode.swiftBAML 值与 Swift 值之间的双向转换BamlUnions.swiftBamlUnionN联合类型封装Proto/SwiftProtobuf 生成的 wire 协议类型baml_inbound/baml_outbound等原生侧依赖的 C 头文件与 modulemap 位于 Sources/CBamlBridge/includeFFI 层通过baml_get_api_v1()解析出BamlApiV1函数表Swift 运行时所有原生调用都经由这张函数表完成——这是保证不同版本之间 ABI 兼容的关键设计。二、发行模型被动镜像与版本溯源该仓库是一个被动镜像passive mirror没有任何内容是手工编辑的。monorepo 的发布流水线构建出 XCFramework将其作为baml-language-version发布版的资产asset挂载并在每次发布时把整棵源码树源码 固定到该发布资产的Package.swift镜像到此处。真正的源source of truth是 monorepo 中的 baml_language/sdks/swift。这一机制的实现位于 scripts/assemble-swift-sdk-mirrorPython 脚本它做四件事把mirror/目录Package.swift模板、README、.gitignore与Sources/BamlBridge运行时源码复制到目标目录在Package.swift中替换四个占位符__ZIP_URL__XCFramework zip 的 release 资产 URL、__CHECKSUM__zip 的 SwiftPM sha256 校验和、__SOURCE_SHA__构建所用源码 commit、__VERSION__版本号写入SOURCE_SHA文件记录每个 release 构建所用的确切源码提交做防护检查镜像目录不允许出现符号链接与.build/.swiftpm/Binaries等构建产物。因此发布出去的每个baml-swift版本都不可变、可溯源Package.swift的 binary target 指向 monorepo 发布版上对应版本的 XCFramework 资产并通过 SwiftPM checksum 做完整性校验。要查证某个版本由哪个源码 commit 构建直接看该版本树根部的SOURCE_SHA文件即可。镜像版 Package.swift 解读mirror/Package.swiftswift-tools-version 6.1展示了发布形态的完整清单let package Package( name: baml-swift, platforms: [ .macOS(.v13), .iOS(.v16), ], products: [ .library(name: BamlBridge, targets: [BamlBridge]) ], dependencies: [ .package(url: https://github.com/apple/swift-protobuf.git, from: 1.38.0) ], targets: [ .binaryTarget( name: BamlBridgeFFI, url: __ZIP_URL__, checksum: __CHECKSUM__ ), .target( name: BamlBridge, dependencies: [ BamlBridgeFFI, .product(name: SwiftProtobuf, package: swift-protobuf), ], linkerSettings: [ .linkedFramework(CoreFoundation), .linkedFramework(Security), .linkedFramework(SystemConfiguration), .linkedLibrary(resolv), ] ), ] )值得注意的细节平台最低要求iOS 16 / macOS 13这是 README 明确给出的支持下限依赖swift-protobuffrom: 1.38.0用于 wire 层消息的编解码BamlBridgeFFI是远程 binary targetURL 与 checksum 由流水线注入三个linkedFramework与linkedLibrary(resolv)是 Rust staticlib 的系统级依赖TLS 根证书、DNS、CoreFoundation 桥接Swift 运行时包必须显式链接它们否则运行时会出现符号缺失。对比源仓库内的 Package.swift开发形态差异只在BamlBridgeFFI的获取方式本地路径path: Binaries/BamlBridgeFFI.xcframework并需要通过sdks/swift/scripts/build-xcframework.sh --host-only先行构建sdk_tests中的 Swift 测试 setup 会自动执行该步骤发布形态则替换为带 checksum 的远程 URL。三、消费在 SwiftPM 与 Xcode 中接入SwiftPM 依赖声明在应用的Package.swift中添加// Package.swift .package(url: https://github.com/BoundaryML/baml-swift, from: 0.15.0)其中from: 0.15.0表示接受0.15.0及同大版本内的更高版本README 同时强调生成的 SDK 与本包必须共享同一个 canonical 版本见下文「版本握手」因此实际使用的版本号应与你bamlCLI 的工具链版本对齐。当前仓库 RuntimeIdentity.swift 中记录的桥接身份为runtimeName baml-swift、toolchainVersion 0.20.1、bridgeRuntimeVersion 0.20.1。Xcode 图形化接入在 Xcode 中执行File → Add Package Dependencies粘贴上述仓库 URL选择一个版本并固定然后把BamlBridge产品添加到你的 app target 即可。体积与切片每个 release 都是不可变的vversiontagPackage.swift的 binary target 指向与 tag 匹配的 XCFramework 资产并附 checksum。应用最终只链接自己架构对应的切片——按 README 的说法约为26 MB不会把全部平台切片打进应用。四、生成你的类型化 SDKbamlCLI 工作流baml-swift只是运行时你在代码里调用的类型化Baml.*API 由bamlCLI 从你的.baml项目生成且生成物不会随包分发包内零生成代码。完整流程baml toolchain use nightly # 或使用与该包版本匹配的 release 工具链 baml generate --from /path/to/your-baml-project第一步指定工具链版本nightly 或与本包版本匹配的 release第二步根据.baml项目产出 Swift SDK。生成物落在生成包如baml_client的Sources/Baml/输出根下。生成器原理从 bytecode 到 Swift 源码生成逻辑在 baml_language/sdks/swift/rust/sdkgen_swift/src/lib.rs它消费SymbolPool符号表加 borsh 序列化的 BAML bytecode输出(relative_path, content)形式的 Swift 源码集合。几个关键设计内联 bytecode_InlinedBaml.swift将编译产物以 base64 形式内联为一个多行字符串字面量每 96 字符一行运行时通过.ignoreUnknownCharacters解码避免大 payload 下的类型检查爆炸每个生成的入口都会触发Baml._initialized一次性加载根命名空间BamlRoot.swift生成public enum Baml含sdkVersion常量与惰性初始化跳过清单无法翻译的类型不会静默消失而是记录进_BamlSkipped.swift清单递归类型装箱Swift struct 无法自包含递归类字段会以运行时BamlIndirectCoW 包装关键字转义BAML 标识符若撞上 Swift 关键字如class、enum生成时自动加反引号。与 Python运行时define_function绑定不同Swift 无法合成函数因此生成器会产出真实func体内部调用BamlRuntime.shared.callSync(...)/call(...)。register_bridge 版本握手生成 SDK 与本包必须共享 canonical 版本这个约束由运行时初始化时的register_bridge握手强制。见 Runtime.swiftBamlRuntime.initialize会把BamlBridgeIdentity中的工具链版本、运行时名与运行时版本通过BamlBridgeInfoV1注册进原生引擎同时用生成的 bytecode 调用initializeRuntimeFromBytecode或带嵌入baml.toml的initializeRuntimeFromBytecodeWithMetadata。若版本不匹配原生侧会返回错误并触发fatalError。初始化幂等guard !initialized并注册全局 completion 回调与atexit关闭钩子。五、运行时架构completion-callback 与调用形态从 Runtime.swift 的文档注释可以确认底层模型C ABI 是 completion-callback 驱动——call_function在解码完参数缓冲区后立即返回结果信封envelope由 Tokio worker 线程通过全局 completion 回调送达。两种调用形态都建立在这一模型上asyncwithCheckedThrowingContinuation挂起SwiftTask取消会转发为cancel_function_call引擎确认的取消最终以 Swift 原生CancellationError呈现与 Python 映射为asyncio.CancelledError一致sync信号量semaphorepark。由于 completion 一定由引擎线程而非调用方线程送达因此不会死锁但阻塞主线程在 DEBUG 下会告警可通过环境变量BAML_ALLOW_MAIN_THREAD_SYNC1静默建议优先使用异步形态。BamlRuntime内部以自增UInt32callback id 维护 pending 表回调中先把 Rust 侧持有的缓冲区拷贝为Data再分发completePending对未知 id已放弃调用的迟到送达直接丢弃。运行时还提供nativeVersion()、toolchainVersion()、bridgeRuntimeVersion()三个查询入口便于在应用里做版本自检。流式与句柄BamlStream与BamlHandle流式 API 复用普通调用路径而非专用原生接口Stream.swift 中BamlStream以ADT_TAGGED_HEAP_HANDLE携带引擎侧流状态next()/final()分别以句柄作为self接收者调用ai.stream.Stream.next/ai.stream.Stream.finalnext()通过检查ai.stream.Done哨兵区分「部分值」与「结束」——注意部分值本身可能为 null因此使用BamlStreamNext枚举而非Value?。Handle.swift 则管理引擎资源媒体、$rust_type字段等的生命周期wire 上只传引擎句柄表的 keySwift 对象在deinit时释放一次该 keyhost-value 类句柄除外避免与引擎表数值冲突编码时通过handleClone克隆新 key 供 wire 使用保证实例可独立释放。六、测试验证与限制说明仓库自带测试可验证完整链路Tests/BamlBridgeTests/FFISmokeTests.swift 中的testNativeVersionNonEmpty证明了「SwiftPM → BamlBridgeFFI.xcframework → Rust staticlib →version()C ABI含 Buffer 所有权拷贝后free_buffer」的完整链接链testProtoRoundTrip、testBigIntPreservesArbitraryPrecisionWireValues、testOutboundUnionResolvesSelectedTypeThroughSelfType等则覆盖 wire 协议、大整数精度、联合类型解析等关键路径。需要明确的限制iOS 切片编译并通过模拟器测试但尚未完成真机设备认证device-certified——README 明示此状态涉及真机发布前请自行验证从源码构建运行时需先执行sdks/swift/scripts/build-xcframework.sh --host-only测试环境由sdk_tests的 setup 自动完成版本匹配是硬约束生成 SDK 的baml工具链版本必须与所链接的baml-swift包版本一致否则初始化握手失败。七、快速上手清单在 Xcode 或Package.swift中引入baml-swift推荐from: 0.15.0起实际以你的工具链版本为准并把BamlBridge加入 target运行baml toolchain use nightly或与包版本匹配的 release与baml generate --from 你的 baml 项目生成类型化 SDK将生成的Baml.*代码加入工程——生成入口会自动完成register_bridge握手与 bytecode 加载调用生成的函数同步用BamlRuntime.shared.callSync异步用call流式用BamlStream.next()/final()发布前核对SOURCE_SHA与版本身份BamlRuntime.nativeVersion()并确认 iOS 真机认证状态。赞分享编程语言AI Agent编译器CLI人工智能【免费下载链接】bamlThe programming language for agents项目地址https://gitcode.com/gh_mirrors/ba/baml点击查看免费下载相关推荐RPCS3修复如龙见参启动崩溃ELF加载器只改了2处RPCS3修复如龙见参启动崩溃ELF加载器只改了2处 这个问题已经修好了更新模拟器就能正常启动《如龙见参》。根子就在ELF加载器算重定位偏移时发生了整数溢出虚拟化图形学调试器OpenCV macOS 官方 Swift 实战指南从零在 Xcode 中集成 opencv2 Framework 并运行 Hello WorldOpenCV macOS 官方 Swift 实战指南从零在 Xcode 中集成 opencv2 Framework 并运行 Hello World 本指南基于计算机视觉图像处理深度学习机器学习BAML C 运行时完全指南baml-bridge 的安装、代码生成、类型映射与发布实践BAML C 运行时完全指南baml bridge 的安装、代码生成、类型映射与发布实践 本文以 BAML 仓库中 C SDK 的官方运行时文档 bridg编程语言AI Agent编译器CLI人工智能上一篇终极指南如何快速构建基于High-Frequency-Trading-Model-with-IB的统计套利策略下一篇掌握Prisma Client Go复合键从定义到性能优化的全攻略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表