首页/新闻资讯/正文详情

AOS 的 aos-openai-compat 胶囊:把任意 OpenAI 兼容大模型接入 AOS 的“设备驱动”实现

发布时间:2026/9/25 3:21:51 来源:云帆数科 栏目:资讯中心
AOS 的 aos-openai-compat 胶囊:把任意 OpenAI 兼容大模型接入 AOS 的“设备驱动”实现
【免费下载链接】aos-ceAOS Community Edition: the open agent operating system.项目地址https://gitcode.com/gh_mirrors/ao/aos-ce点击查看免费下载在 AOSaos-ce的“操作系统”模型里每个能力都以 capsule胶囊形式挂载到运行时事件总线之上而aos-openai-compat就是其中的 LLM 设备驱动它把运行时的标准化 LLM 事件协议翻译成任意 OpenAI 兼容 Chat Completions API正如设备驱动在操作系统与硬件之间做翻译。读完本文你将掌握该胶囊的完整配置参数与aos init引导流程、base_url/model/api_key的取值规范本地端点与 SSRF 气闸airlock的豁免配置运行时模型选择的 CLI 与 HTTP API以及从消息转换、SSE 流解析到模型发现回退的源码级实现细节。一、定位一个 LLM 设备驱动aos-openai-compat 是 Unicity AOS 的 OpenAI 兼容 LLM 提供方胶囊。它不绑定任何特定云厂商只要对方实现 OpenAI Chat Completions 流式协议SSE就能通过base_url一个字段接入Providerbase_url备注OpenAIhttps://api.openai.comGroqhttps://api.groq.com/openaiTogetherhttps://api.together.aiMistralhttps://api.mistral.aiDeepSeekhttps://api.deepseek.comFireworkshttps://api.fireworks.ai/inferenceLM Studiohttp://localhost:1234需要操作员本地出网豁免见下文vLLMhttp://localhost:8000需要操作员本地出网豁免见下文llama.cpphttp://localhost:8080需要操作员本地出网豁免见下文base_url只填提供方源站origin——胶囊会自动拼接/v1/chat/completions生成请求与/v1/models模型发现不要带/v1后缀。从 lib.rs 可以看到这一点在源码中被显式保证拼 URL 前会先base_url.trim_end_matches(/)即用户即便误填尾斜杠也不会产生//v1/models。清单声明与能力模型从 Capsule.toml 可以确认这个胶囊在 OS 层面的身份组件openai-compat产物aos_openai_compat.wasm类型executable能力capabilities { net [*] }第 8–12 行导出astrid:llm1.0.0 接口第 14–15 行表明它是 LLM 提供方订阅llm.v1.request.describe处理器llm_describe与llm.v1.request.generate.openai-compat处理器handle_llm_request第 25–27 行发布llm.v1.stream.openai-compatWIT 类型unicity-astrid/wit/llm/stream-event与llm.v1.response.describe第 17–23 行。注释特别说明llm.v1.response.describe是 registry 扇出fan-out后的精确主题.*通配保留给将来需要按提供方做响应关联路由的调用方。二、工作原理从 IPC 请求到 SSE 事件流的四步链路README 给出的工作链路是四步源码中的对应实现一一对应订阅llm.v1.request.generate.openai-compatIPC 事件。入口是 lib.rs 的handle_llm_request拦截器解出request_id、model、messages、tools、system后交给execute_request。若执行失败它不会静默吞错而是把StreamEvent::Error发布到流主题上让上游调用方能感知失败。消息格式转换把运行时的Message格式转成 OpenAI Chat Completions JSON。convert_message 覆盖了四种内容形态Text映射为{role, content}的普通消息ToolCalls映射为role: assistant、content: null且带tool_calls数组函数名、参数原样透传参数若非字符串会序列化为字符串ToolResult映射为role: tool并携带tool_call_id与结果内容MultiPart映射为内容数组文本块是{type: text}图片块编码为data:media_type;base64,data的image_url即支持视觉输入。角色映射role_str第 603–611 行是恒等的system/user/assistant/tool四种角色与 OpenAI 协议一一对应。建立流式 HTTP 连接POST {base_url}/v1/chat/completions请求体固定stream: true且带stream_options: {include_usage: true}第 303–308 行以便最终 chunk 能带回 token 用量。环境变量的max_output_tokens与temperature只作为默认值注入请求中已指定则不覆盖第 310–328 行——源码注释明确写着 “env vars are defaults, not overrides”。工具定义则被包装成{type: function, function: {name, description, parameters}}结构附加到tools字段。HTTP 连接通过 SDK 的http::stream_start走宿主层的 HTTP 流式气闸建立第 353 行。实时解析 SSE 并回发标准事件parse_sse_stream_live 逐块读取、按行缓冲单行缓冲上限 1 MBMAX_LINE_BUFFER_SIZE防止服务端发送无换行的超长数据把流拖垮只处理data:前缀行遇到[DONE]即发布StreamEvent::Done并正常返回如果流在[DONE]之前结束无论缓冲为空还是存在半行都按错误处理——从源码结构看这里刻意拒绝了“流悄悄断掉”的静默成功。流事件覆盖完整生命周期process_chunk 把每个 chunk 拆成标准StreamEvent文本增量 →StreamEvent::TextDelta并行工具调用用active_tools向量按tc.index跟踪每个并行调用name首次出现时发ToolCallStart{id, name}参数分片追加时发ToolCallDelta{id, args_delta}finish_reason tool_calls时为所有活跃调用补发ToolCallEnd{id}并清空跟踪usageprompt_tokenscompletion_tokens结构定义见 schemas.rs→StreamEvent::Usage{input_tokens, output_tokens}流结束 →StreamEvent::Done出错 →StreamEvent::Error。所有事件都携带request_idUUID发布到llm.v1.stream.openai-compat调用方据此把异步流与原始请求关联。请求模型还有一个归一化细节registry 可能下发带前缀的openai-compat:gpt-5.4形式的 idprovider_model_id 只剥离本胶囊自己的openai-compat:前缀其余原样保留例如openai-compat:llama3.3:70b会变成llama3.3:70b冒号后的 Ollama 风格 tag 完整保留。测试provider_request_model_strips_registry_prefix_only与request_model_normalization_also_applies_to_env_default对这一行为做了四组断言包括确认other:gpt-5.4这类他方前缀绝不会被误剥离。三、模型发现describe 时查询、失败可回退、绝不虚构 idregistry 向各提供方胶囊广播llm.v1.request.describe扇出请求时本胶囊执行 llm_describe查询GET {base_url}/v1/models把每个发现的 model id 变成一个 provider entry 发布到llm.v1.response.describe。所有 entry 共享同一对request_topic/stream_topicentry 的 id 就是模型 id 本身。发现的时机与两个关键规则describe 时执行而非启动时只有当 registry 扇出 describe 请求时才真正发起/v1/models查询避免启动期对远端的强依赖。envmodel控制顺序若配置的默认模型出现在发现列表中它的 entry 会被稳定分区到entry[0]供 registry 按位置预选describe_providers 用两次iter().filter完成稳定分区其余模型保持上游返回顺序。若默认模型不在发现列表里上游没提供则保持发现顺序不变、entry[0]即为第一个可用模型。源码与测试describe_emits_env_model_first都确认entry 中没有default字段顺序本身就是唯一信号。离线回退/v1/models不可达或返回错误时只要配置了 envmodel就回退为广告单个 entry该模型 id保证既有 pinned 安装在上游短暂宕机时不回归。对应测试configured_default_survives_failed_discovery验证了resolve_model_ids(Err, Some(gpt-5.4)) [gpt-5.4]。双失败则什么都不广告发现失败且没有配置 env model 时胶囊返回空列表而不是编造一个unknownid——否则 registry 会把它绑定后原样发给上游。测试no_env_model_and_failed_discovery_yields_no_entries正是锁死这一行为。/v1/models的解析还有防御性处理extract_model_ids丢弃空 id 与纯空白 id对重复 id 做保持服务端顺序的稳定去重防恶意上游重复 id 导致同 id 双 entrydata为空、整体不可解析比如 404 的 HTML 页面一律视为发现失败。Ollama 风格带冒号的 id如llama3.3:70b逐字透传测试parse_models_body_yields_one_entry_per_id验证了它端到端保留。解析用的结构体在 schemas.rs 中定义ModelList/ModelEntry只消费data[].id字段其余字段object、created、owned_by等被 serde 忽略因此对不同厂商的附加字段是天然兼容的。四、配置六个 env 字段及其默认值以下字段在aos init期间被交互式询问在独立的 Astrid Runtime 安装中等价的发行版托管流程是astrid distro apply source。除api_key外所有字段都有默认值或可留空变量类型默认值说明api_keysecret--提供方 API key以Authorization: Bearer ...发送。无 key/本地端点LM Studio、llama.cpp留空。base_urlstringhttps://api.openai.com提供方源站不带/v1modelselectgpt-5.4默认模型onboarding 期间从{base_url}/v1/models实时填充context_windowinteger128000向 registry 广告的上下文窗口token 数max_output_tokensinteger8192作为每次请求的max_tokens发送temperaturestring(未设置)采样温度0.0–2.0留空则用提供方默认这些声明就写在 Capsule.toml 的[env]段。注意context_window与max_output_tokens不只是请求参数它们会被 llm_describe 读入并写进每个 provider entry 的context_window/max_output_tokens字段供 registry 调度参考解析失败时分别回退到 128000 与 8192。model是一个“活的” select 字段清单中model的声明是[env] model { type select, request Enter the default model ID, default gpt-5.4, options_from { http {base_url}/v1/models, bearer {api_key}, select data[].id, after [base_url, api_key] } }执行aos init时安装器用你输入的api_key去拉取{base_url}/v1/models呈现一个带编号的模型菜单配置中的默认模型预选。端点不可达时安装器回退为自由文本输入。after [base_url, api_key]约束意味着模型菜单只在base_url与api_key都确定之后才运行安装器只把 bearer 附加到发往所配置base_url主机的请求并把响应上限封顶在 5 MB。无 key 端点的处理对不需要鉴权的本地服务器LM Studio、llama.cpp、本地 vLLMapi_key留空即可。源码 bearer_header 定义了判定规则空白、纯空白或仅换行的 key 一律视为不存在不发送Authorization头——这会避免发出Authorization: Bearer空值这种请求许多宽松服务器反而会拒绝它。真实 key 则会先 trim 再发送剪掉粘贴引入的首尾空白。两个单元测试whitespace_only_api_key_is_treated_as_keyless与real_api_key_is_trimmed_and_sent把这四种输入、 、\n、 \t\r\n 及真实 key 带尾换行全部锁死。本地端点与 SSRF 气闸astrid:http宿主能力内置 SSRF 气闸默认拦截一切解析到回环、私有或链路本地地址段的出站请求——127.0.0.1、::1、192.168.x.x、10.x.x.x、169.254.x.x等——用于防御服务端请求伪造。这对本地 LLM 服务器很关键。如果base_url指向本地地址LM Studio 的http://localhost:1234、Ollama 的http://localhost:11434、llama.cpp 的http://localhost:8080或局域网里的http://192.168.1.50:11434胶囊运行期的 HTTP 调用会被气闸拦下/v1/models发现请求模型列表返回空与/v1/chat/completions生成请求prompt 静默失败或报连接错误都受影响远端云端点则不受影响。一个值得知道的细节onboarding 看起来成功了运行期却可能失败。安装器的实时模型选择器是原生拉取/v1/models的——它运行在沙箱胶囊之外、不经过气闸。于是aos init期间模型菜单能正常填充但胶囊真正跑起来后每次 prompt 都失败。修复方式是操作员级豁免而不是重试。授予本地出网豁免仅限操作员豁免配置在操作员的config.toml中位于[security.capsule_local_egress]之下。胶囊自己的Capsule.toml无法设置该项项目/工作区配置层也无法扩大它默认无任何豁免[security.capsule_local_egress] # host:port (或 host:*) —— 即使解析到本地地址该胶囊也可达的端点 aos-openai-compat [127.0.0.1:1234, 192.168.1.50:11434]豁免只对这些具体的host:port对解除气闸不会改动胶囊的net允许列表那已经是*。五、运行时模型选择按 principal 存储、随时可切模型选择是 per-principal 的存在 registry 胶囊的 KV 存储中随时可以改动而无需触碰胶囊配置。CLI# 列出所有已配置提供方上的可用模型 aos models list # 机器可读输出 aos models list --json # 查看当前 principal 的活跃模型 aos models current aos models current --json # 按裸 id 选择跨提供方无歧义时 aos models set gpt-5.4 aos models set llama3.3:70b # 两个提供方提供同名模型时消歧 aos models set openai-compat:gpt-5.4 # 清除选择回退到自动选中的默认值 aos models unsetaos models是aos capsule models的简写两者到达同一个 registry 胶囊动词。HTTP API网关# 列出当前已认证 principal 可用的模型 GET /api/models # 获取活跃模型 GET /api/models/active # 设置活跃模型 PUT /api/models/active Content-Type: application/json { id: gpt-5.4 }三个端点都作用域于已认证的 bearer principal。什么都没选时会发生未选择模型且没有配置任何提供方时prompt 失败并报清晰错误No LLM model is selected. Run aos models to choose one, or install/configure an LLM provider.react 胶囊从不捏造默认模型——缺失选择永远表现为错误而不是静默回退到某个任意模型。六、aos init引导流程执行aos init或安装包含本胶囊的发行版时安装器把全部group llm的胶囊作为一个多选呈现“你想配置哪些提供方”。对每个被选中的提供方按顺序执行引导序列输入base_url输入api_key从实时编号菜单来自{base_url}/v1/models中挑选模型这一序列对本胶囊与第一方openai胶囊见 capsules/capsule-openai同样适用。若运行本地服务器把base_url设为本地地址、api_key留空即可但记住 SSRF 气闸默认拦截本地地址prompt 要真正跑通还需要前文所述的操作员本地出网豁免。七、IPC 协议总览方向主题载荷订阅llm.v1.request.generate.openai-compatIpcPayload::LlmRequest订阅llm.v1.request.describedescribe 请求registry 扇出发布llm.v1.stream.openai-compatIpcPayload::LlmStreamEvent发布llm.v1.response.describeprovider descriptor 数组这四行与 Capsule.toml 的[publish]/[subscribe]段完全对应主题常量在 lib.rs 中定义为STREAM_TOPIC/REQUEST_TOPIC且测试advertised_topics_use_stable_provider_alias断言两者都以稳定的 provider 别名openai-compat结尾——它是路由别名与包名解耦。八、开发与构建该胶囊编译为cdylib见 Cargo.toml 的[lib] crate-type [cdylib]目标平台为 wasm依赖仅astrid-sdk、serde、serde_json、uuid四个全部走 workspace 版本源码头部声明#![deny(unsafe_code)]——整个驱动不含任何 unsafe。本地开发rustup target add wasm32-unknown-unknown cargo build单元测试直接嵌在 lib.rs 尾部覆盖了 SSE 线格式变体data: {...}、data:{...}、data:空载荷、:心跳注释行的取舍、[DONE]终结语义、错误 body 排水、描述顺序、去重与 keyless 判定等关键路径。九、许可本胶囊在 MIT 与 Apache 2.0 双许可下发布见 README 与 LICENSE-MIT。MSRV 为 Rust 1.94由徽章声明。小结aos-openai-compat用一个base_url字段换取了对整个 OpenAI 兼容生态的接入能力它的工程细节——按位置而非字段标记默认模型、发现失败时的“宁缺毋滥”回退、空白 key 判定为 keyless、SSE 行缓冲上限与[DONE]终结强校验——都可以在源码与内嵌测试中逐条找到证据这正是把它当作 OS 级设备驱动来设计的体现。赞分享【免费下载链接】aos-ceAOS Community Edition: the open agent operating system.项目地址https://gitcode.com/gh_mirrors/ao/aos-ce点击查看免费下载相关推荐aos-ce aos-memory 胶囊通过 Prompt-Builder 钩子实现 Agent 跨会话记忆注入aos ce aos memory 胶囊通过 Prompt Builder 钩子实现 Agent 跨会话记忆注入 本文以 capsules/capsule mUnicity AOS 胶囊开发快速入门用 aos-ce 的 capsule-forge 从零构建第一个 WASM 工具胶囊Unicity AOS 胶囊开发快速入门用 aos ce 的 capsule forge 从零构建第一个 WASM 工具胶囊 本文基于 aos ce 仓库中aos-ce 的 aos-meta-harness 胶囊为主机 Agent 注入私有的同轮自我反思上下文aos ce 的 aos meta harness 胶囊为主机 Agent 注入私有的同轮自我反思上下文 aos meta harness 是 AOS Com上一篇RPA-Python解放双手的Python自动化神器让重复工作成为历史下一篇laravel-mongodb数据变更审计字段级变更跟踪实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

google/benchmark 随机交错(Random Interleaving)详解:降低微基准方差的原理、用法与源码实现
google/benchmark 随机交错(Random Interleaving)详解:降低微基准方差的原理、用法与源码实现

性能测试 【免费下载链接】benchmark A microbenchmark support library 项目地址: https://gitcode.com/gh_mirrors/benchmark5/benchmark 点击查看 免费下载 本文围绕 Google Benchmark(A microbenchmark support library)的 Random Inter… · 2026/9/25 3:21:51

RisingWave 实时流式写入 Cassandra / ScyllaDB 完整实战指南
RisingWave 实时流式写入 Cassandra / ScyllaDB 完整实战指南

数据库流处理后端数据工程 【免费下载链接】risingwave Event streaming platform for agentic AI. Continuously ingest, transform, and serve event streams in real time, at scale. 项目地址: https://gitcode.com/gh_mirrors/ri/risingwave 点击查看 免费下载… · 2026/9/25 3:21:51

如何把 ModelScope 的 AI 模型跑在自己电脑上:10 分钟从安装到出结果
如何把 ModelScope 的 AI 模型跑在自己电脑上:10 分钟从安装到出结果

如何把 ModelScope 的 AI 模型跑在自己电脑上:10 分钟从安装到出结果 【免费下载链接】modelscope ModelScope: bring the notion of Model-as-a-Service to life. 项目地址: https://gitcode.com/GitHub_Trending/mo/modelscope 想跳过云端、在自己的机器上… · 2026/9/25 3:21:51

深入gnhf编排器架构:状态机如何让AI代理整夜循环不丢一行代码
深入gnhf编排器架构:状态机如何让AI代理整夜循环不丢一行代码

深入gnhf编排器架构:状态机如何让AI代理整夜循环不丢一行代码 【免费下载链接】gnhf Before I go to bed, I tell my agents: good night, have fun 项目地址: https://gitcode.com/gh_mirrors/gn/gnhf gnhf(good night, have fun)是一… · 2026/9/25 4:25:44

VirtualBox E_FAIL (0x80004005) 报错全解析:从驱动冲突到UUID修复
VirtualBox E_FAIL (0x80004005) 报错全解析:从驱动冲突到UUID修复

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 4:25:44

MIPI DSI转LVDS桥接方案:LT9211与N76E003配置实战
MIPI DSI转LVDS桥接方案:LT9211与N76E003配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 4:25:44

Windows 11锁屏机制深度解析与分版本禁用方案
Windows 11锁屏机制深度解析与分版本禁用方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 4:25:44

必应搜索出现Ref A/B/C标签?原因排查与解决指南
必应搜索出现Ref A/B/C标签?原因排查与解决指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 4:25:37

Cadence Sigrity TDR仿真实战:从原理到阻抗曲线分析
Cadence Sigrity TDR仿真实战:从原理到阻抗曲线分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 4:25:37

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码