跳转到内容

Hybrid Gene 开发指南

Hybrid Gene 将 Rotifer 的安全模型扩展到受控网络访问。与 Wrapped Gene(纯函数)和 Native Gene(仅 WASM)不同,Hybrid Gene 可以调用外部 API——但必须通过网络网关(Network Gateway),网关会强制执行域名白名单、速率限制、超时和响应大小上限。

本指南将带你完成 Hybrid Gene 的创建、测试和发布全流程。

保真度网络适用场景
Wrapped纯数据变换、文本处理
Hybrid网关控制LLM API、数据库查询、Embedding
NativeCPU 密集型 WASM 计算

当你的 Gene 需要调用外部服务(OpenAI、Anthropic、Supabase 等),同时仍需协议安全保障时,使用 Hybrid。


Terminal window
rotifer init my-hybrid-gene --fidelity Hybrid

这会创建一个包含 network 配置块的 phenotype.json

{
"name": "my-hybrid-gene",
"domain": "general",
"fidelity": "Hybrid",
"version": "0.1.0",
"inputSchema": { "type": "object" },
"outputSchema": { "type": "object" },
"network": {
"allowedDomains": ["api.example.com"],
"maxTimeoutMs": 30000,
"maxResponseBytes": 1048576,
"maxRequestsPerMin": 10
}
}

也可以将已有 Gene 转换为 Hybrid:

Terminal window
rotifer wrap my-gene --fidelity Hybrid --domain text.analyze

编辑 phenotype.json,声明你的 Gene 需要访问的域名:

{
"network": {
"allowedDomains": ["api.openai.com", "*.supabase.co"],
"maxTimeoutMs": 30000,
"maxResponseBytes": 1048576,
"maxRequestsPerMin": 10
}
}
参数类型默认值说明
allowedDomainsstring[][]Gene 可以访问的域名。支持精确匹配和 *.domain.com 通配符
maxTimeoutMsnumber30000单次请求超时(毫秒)
maxResponseBytesnumber1048576响应体最大大小(默认 1 MiB)
maxRequestsPerMinnumber10速率限制——60 秒滑动窗口内的最大请求数
  • 精确匹配api.openai.com 仅允许 api.openai.com
  • 通配符*.supabase.co 允许 abc.supabase.cosupabase.co
  • 禁止的域名(发布时拒绝):
    • localhost127.x.x.x0.0.0.0::1
    • 私有 IP:10.x.x.x172.16–31.x.x192.168.x.x

Hybrid Gene 通过第二个参数接收 gatewayFetch 函数。使用它代替全局 fetch

export async function express(
input: { query: string },
ctx?: { gatewayFetch?: typeof fetch }
): Promise<{ answer: string }> {
if (!ctx?.gatewayFetch) {
throw new Error("gatewayFetch is required for Hybrid genes");
}
const response = await ctx.gatewayFetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
},
body: JSON.stringify({
model: "gpt-4o-mini",
messages: [{ role: "user", content: input.query }],
}),
});
const data = await response.json();
return { answer: data.choices[0].message.content };
}

当你的 Gene 调用 gatewayFetch 时:

  1. 域名检查 — 验证 URL 的主机名是否在 allowedDomains 中。如果被拦截,立即抛出 DOMAIN_BLOCKED 错误。
  2. 速率检查 — 如果 Gene 在当前 60 秒窗口内超出 maxRequestsPerMin,抛出 RATE_LIMITED 错误。
  3. 超时 — 请求超过 maxTimeoutMs 后被中止,抛出 TIMEOUT 错误。
  4. 响应上限 — 如果响应体超过 maxResponseBytes,会被截断并设置 truncated: true 标志。
错误码含义
DOMAIN_BLOCKEDURL 主机名不在 allowedDomains
RATE_LIMITED超出 maxRequestsPerMin
TIMEOUT请求超过 maxTimeoutMs
RESPONSE_TOO_LARGE响应体超过 maxResponseBytes
NETWORK_ERROR其他 fetch 错误

Terminal window
rotifer compile my-hybrid-gene

对于 Hybrid Gene,编译器会保留 fidelity: "Hybrid" 标志,并将 network 配置嵌入 IR 自定义段。输出会显示允许的域名:

✓ Compiled to Rotifer IR
Fidelity: Hybrid
Network: api.openai.com, *.supabase.co
IR Hash: sha256-abc123...

Terminal window
rotifer publish my-hybrid-gene

发布命令在认证之前运行两项 Hybrid 专用验证:

如果 network.allowedDomains 为空或缺失:

✗ [E0055] Hybrid gene must declare at least one allowed domain
in network.allowedDomains
Fix: Add "network": { "allowedDomains": ["api.example.com"] }
to phenotype.json

如果任何域名解析为 localhost 或私有 IP:

✗ [E0056] Forbidden domain in network.allowedDomains: "localhost"
(localhost/private IP not allowed)
Fix: Remove private/localhost domains before publishing

创建包含 Hybrid Gene 的 Agent:

Terminal window
rotifer agent create my-agent --genes my-hybrid-gene
rotifer agent run my-agent --input '{"query": "What is Rotifer?"}'

Agent 运行时自动:

  1. 检测 Gene phenotype 中的 fidelity: "Hybrid"
  2. 用 Gene 的 network 配置创建 NetworkGateway
  3. gatewayFetch 注入 express() 调用
  4. 使用 --verbose 时输出网关统计信息

Rotifer 文档助手管道展示了 4-Gene Hybrid 组合:

query-parser (Wrapped)
doc-retrieval (Hybrid) → OpenAI Embeddings + Supabase pgvector
answer-synthesizer (Hybrid) → Claude / OpenAI LLM
source-linker (Wrapped)

每个 Hybrid Gene 仅声明它需要的域名:

Gene允许的域名
doc-retrievalapi.openai.com, *.supabase.co
answer-synthesizerapi.anthropic.com, api.openai.com

仅声明 Gene 实际调用的域名。allowedDomains 中的每个域名都是一个信任面——保持最小化。

"allowedDomains": ["api.openai.com"]

显式处理网关错误——不要让网络故障导致 Gene 崩溃:

try {
const res = await ctx.gatewayFetch(url, options);
// ...
} catch (err) {
if (err.code === "RATE_LIMITED") {
return { answer: "速率限制——请重试。", error: true };
}
throw err;
}

永远不要在 Gene 源码中硬编码 API Key。使用环境变量:

const apiKey = process.env.OPENAI_API_KEY;
if (!apiKey) throw new Error("OPENAI_API_KEY not set");

设计 Gene 支持多个 LLM 提供商,通过环境变量切换:

const provider = process.env.ROTIFER_LLM_PROVIDER || "openai";
const endpoint = provider === "claude"
? "https://api.anthropic.com/v1/messages"
: "https://api.openai.com/v1/chat/completions";

根据使用场景调整 maxTimeoutMsmaxResponseBytes

使用场景超时响应大小
LLM 聊天补全30s1 MiB
Embedding API10s256 KiB
数据库查询5s512 KiB