Hybrid Gene 开发指南
Hybrid Gene 将 Rotifer 的安全模型扩展到受控网络访问。与 Wrapped Gene(纯函数)和 Native Gene(仅 WASM)不同,Hybrid Gene 可以调用外部 API——但必须通过网络网关(Network Gateway),网关会强制执行域名白名单、速率限制、超时和响应大小上限。
本指南将带你完成 Hybrid Gene 的创建、测试和发布全流程。
何时使用 Hybrid
Section titled “何时使用 Hybrid”| 保真度 | 网络 | 适用场景 |
|---|---|---|
| Wrapped | 无 | 纯数据变换、文本处理 |
| Hybrid | 网关控制 | LLM API、数据库查询、Embedding |
| Native | 无 | CPU 密集型 WASM 计算 |
当你的 Gene 需要调用外部服务(OpenAI、Anthropic、Supabase 等),同时仍需协议安全保障时,使用 Hybrid。
步骤 1:初始化 Hybrid 项目
Section titled “步骤 1:初始化 Hybrid 项目”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:
rotifer wrap my-gene --fidelity Hybrid --domain text.analyze步骤 2:配置网络访问
Section titled “步骤 2:配置网络访问”编辑 phenotype.json,声明你的 Gene 需要访问的域名:
{ "network": { "allowedDomains": ["api.openai.com", "*.supabase.co"], "maxTimeoutMs": 30000, "maxResponseBytes": 1048576, "maxRequestsPerMin": 10 }}网络配置参考
Section titled “网络配置参考”| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
allowedDomains | string[] | [] | Gene 可以访问的域名。支持精确匹配和 *.domain.com 通配符 |
maxTimeoutMs | number | 30000 | 单次请求超时(毫秒) |
maxResponseBytes | number | 1048576 | 响应体最大大小(默认 1 MiB) |
maxRequestsPerMin | number | 10 | 速率限制——60 秒滑动窗口内的最大请求数 |
- 精确匹配:
api.openai.com仅允许api.openai.com - 通配符:
*.supabase.co允许abc.supabase.co和supabase.co - 禁止的域名(发布时拒绝):
localhost、127.x.x.x、0.0.0.0、::1- 私有 IP:
10.x.x.x、172.16–31.x.x、192.168.x.x
步骤 3:编写 Express 函数
Section titled “步骤 3:编写 Express 函数”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 时:
- 域名检查 — 验证 URL 的主机名是否在
allowedDomains中。如果被拦截,立即抛出DOMAIN_BLOCKED错误。 - 速率检查 — 如果 Gene 在当前 60 秒窗口内超出
maxRequestsPerMin,抛出RATE_LIMITED错误。 - 超时 — 请求超过
maxTimeoutMs后被中止,抛出TIMEOUT错误。 - 响应上限 — 如果响应体超过
maxResponseBytes,会被截断并设置truncated: true标志。
| 错误码 | 含义 |
|---|---|
DOMAIN_BLOCKED | URL 主机名不在 allowedDomains 中 |
RATE_LIMITED | 超出 maxRequestsPerMin |
TIMEOUT | 请求超过 maxTimeoutMs |
RESPONSE_TOO_LARGE | 响应体超过 maxResponseBytes |
NETWORK_ERROR | 其他 fetch 错误 |
步骤 4:编译
Section titled “步骤 4:编译”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...步骤 5:发布
Section titled “步骤 5:发布”rotifer publish my-hybrid-gene发布命令在认证之前运行两项 Hybrid 专用验证:
E0055 — 缺少允许域名
Section titled “E0055 — 缺少允许域名”如果 network.allowedDomains 为空或缺失:
✗ [E0055] Hybrid gene must declare at least one allowed domain in network.allowedDomains
Fix: Add "network": { "allowedDomains": ["api.example.com"] } to phenotype.jsonE0056 — 禁止的域名
Section titled “E0056 — 禁止的域名”如果任何域名解析为 localhost 或私有 IP:
✗ [E0056] Forbidden domain in network.allowedDomains: "localhost" (localhost/private IP not allowed)
Fix: Remove private/localhost domains before publishing步骤 6:在 Agent 中运行
Section titled “步骤 6:在 Agent 中运行”创建包含 Hybrid Gene 的 Agent:
rotifer agent create my-agent --genes my-hybrid-generotifer agent run my-agent --input '{"query": "What is Rotifer?"}'Agent 运行时自动:
- 检测 Gene phenotype 中的
fidelity: "Hybrid" - 用 Gene 的
network配置创建NetworkGateway - 将
gatewayFetch注入express()调用 - 使用
--verbose时输出网关统计信息
实战示例:RAG 管道
Section titled “实战示例:RAG 管道”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-retrieval | api.openai.com, *.supabase.co |
answer-synthesizer | api.anthropic.com, api.openai.com |
最小域名暴露面
Section titled “最小域名暴露面”仅声明 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;}使用环境变量管理 API Key
Section titled “使用环境变量管理 API Key”永远不要在 Gene 源码中硬编码 API Key。使用环境变量:
const apiKey = process.env.OPENAI_API_KEY;if (!apiKey) throw new Error("OPENAI_API_KEY not set");LLM 提供商无关性
Section titled “LLM 提供商无关性”设计 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";合理的限制参数
Section titled “合理的限制参数”根据使用场景调整 maxTimeoutMs 和 maxResponseBytes:
| 使用场景 | 超时 | 响应大小 |
|---|---|---|
| LLM 聊天补全 | 30s | 1 MiB |
| Embedding API | 10s | 256 KiB |
| 数据库查询 | 5s | 512 KiB |