To manage complex agent definitions in Rust, use these patterns:
Type-Safe Tool Lists
Avoid string typos by defining tool sets as constants:
const READONLY_TOOLS: &[&str] = &["Read", "Grep", "Glob"];
Agent Builder Pattern
Implement a custom AgentBuilder struct to provide a fluent API for creating AgentDefinition objects. This encapsulates default values (like model: "sonnet") and provides helper methods for common tool configurations (e.g., .readonly_tools() or .editor_tools()).
Model Selection Strategy
Map task complexity to specific models to optimize cost and performance:
- Simple tasks:
haiku - Medium tasks:
sonnet - Complex tasks:
opus
// Example of an Agent Builder pattern
struct AgentBuilder {
name: String,
description: String,
prompt: String,
tools: Vec<String>,
model: String,
}
impl AgentBuilder {
fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
description: String::new(),
prompt: String::new(),
tools: Vec::new(),
model: "sonnet".to_string(),
}
}
fn readonly_tools(mut self) -> Self {
self.tools = vec!["Read".into(), "Grep".into(), "Glob".into()];
self
}
fn build(self) -> (String, AgentDefinition) {
(
self.name.clone(),
AgentDefinition {
description: self.description,
prompt: self.prompt,
tools: Some(self.tools),
model: Some(self.model)
}
)
}
}