跳转到内容

Components

Component 是一个可移植的 WebAssembly (WASM) 构建单元,实现了 Greentic 的 WIT 接口。Components 具有以下特性:

  • Sandboxed - 在隔离的 WASM 环境中执行
  • Portable - 可在任何带有 Wasmtime 的平台上运行
  • Composable - 可组合构建复杂工作流
  • Language-agnostic - 可使用 Rust、Go 或任何兼容 WASM 的语言编写
类型用途示例
NodeFlow 处理步骤LLM 调用器、模板渲染器
Provider外部服务桥接Telegram、Slack、SendGrid
ToolMCP tool 实现数据库查询、API 调用
Operator消息转换按钮处理、卡片渲染

使用组件编写 CLI:

Terminal window
# Create new component project
greentic-component new my-processor
cd my-processor

这会生成:

my-processor/
├── Cargo.toml
├── src/
│ └── lib.rs
├── wit/
│ └── component.wit
└── build.sh
Cargo.toml
[package]
name = "my-processor"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["cdylib"]
[dependencies]
wit-bindgen = "0.53"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[profile.release]
opt-level = "s"
lto = true

定义你的组件接口:

wit/component.wit
package greentic:my-processor;
interface types {
record input {
message: string,
context: option<string>,
}
record output {
result: string,
success: bool,
}
}
world processor {
import types;
export process: func(input: types.input) -> types.output;
}
src/lib.rs
use wit_bindgen::generate;
generate!({
world: "processor",
path: "wit",
});
struct MyProcessor;
impl Guest for MyProcessor {
fn process(input: Input) -> Output {
// Your processing logic here
let result = format!("Processed: {}", input.message);
Output {
result,
success: true,
}
}
}
export!(MyProcessor);
target/wasm32-wasip2/release/my_processor.wasm
# Build for WASM target
cargo build --target wasm32-wasip2 --release

Components 可以使用 WASI 接口执行异步操作:

use wit_bindgen::generate;
generate!({
world: "async-processor",
path: "wit",
async: true,
});
impl Guest for AsyncProcessor {
async fn process(input: Input) -> Output {
// Async HTTP call
let response = http_fetch(&input.url).await;
Output {
result: response.body,
success: response.status == 200,
}
}
}

在 components 中访问 session state:

impl Guest for StatefulProcessor {
fn process(input: Input, state: &mut State) -> Output {
// Read from state
let counter = state.get("counter").unwrap_or(0);
// Update state
state.set("counter", counter + 1);
Output {
result: format!("Processed {} times", counter + 1),
success: true,
}
}
}

使用 Result 类型进行错误处理:

impl Guest for SafeProcessor {
fn process(input: Input) -> Result<Output, Error> {
if input.message.is_empty() {
return Err(Error::InvalidInput("Message cannot be empty".into()));
}
Ok(Output {
result: process_message(&input.message)?,
success: true,
})
}
}

Greentic 提供了多个内置 components:

调用兼容 OpenAI 的 LLM:

- id: analyze
type: llm
config:
model: "gpt-4"
system_prompt: "You are a helpful assistant."
prompt: "{{message}}"

渲染 Handlebars 模板:

- id: format
type: template
config:
template: "Hello, {{name}}! Your order #{{order_id}} is ready."

执行 Rhai 脚本:

- id: calculate
type: script
config:
script: |
let total = 0;
for item in items {
total += item.price * item.quantity;
}
total

渲染并校验 Adaptive Cards:

- id: show_card
type: adaptive-card
config:
card: "cards/welcome.json"
data:
user_name: "{{user_name}}"
src/lib.rs
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_process() {
let input = Input {
message: "Hello".into(),
context: None,
};
let output = MyProcessor::process(input);
assert!(output.success);
assert!(output.result.contains("Processed"));
}
}
Terminal window
# Run with test harness
greentic-component test ./my-processor
# Test with sample input
echo '{"message": "test"}' | greentic-component run ./my-processor.wasm
  1. 保持组件聚焦 - 单一职责
  2. 处理所有错误 - 生产环境中绝不要 panic
  3. 尽量减少依赖 - 减小 WASM 二进制体积
  4. 使用强类型 - 利用 WIT 保证类型安全
  5. 记录接口文档 - 保持 WIT 定义清晰
  6. 充分测试 - 包含单元测试和集成测试
  7. 优化体积 - 使用 LTO 和体积优化
Terminal window
# Inspect component exports
wasm-tools component wit ./my-processor.wasm
# Validate component
wasm-tools validate ./my-processor.wasm

使用 WASI 日志接口:

use greentic_interfaces::log;
impl Guest for DebugProcessor {
fn process(input: Input) -> Output {
log::debug(&format!("Processing: {:?}", input));
// ... processing ...
log::info("Processing complete");
output
}
}