What You Control
The SDK defines what developers control versus what Platform Core manages.
SDK Responsibilities
When using the SDK, you control:
1. Agent Definition Structure
Define task logic, workflows, and resource dependencies:
agent = (
AgentBuilder("invoice-processor")
.version("1.0.0")
.description("Extract line items from invoices")
.add_workflow(workflow)
.add_prompt(prompt)
.build()
)Developer Controls:
- Workflow structure (nodes and edges)
- Resource definitions (prompts, tools, modules)
- Input/output schemas
- Node dependencies and execution order
- Version numbers
Developer Does NOT Control:
- When execution occurs (user-initiated)
- Resource allocation (platform-managed)
- Retry logic (platform-managed)
- Billing calculation (usage-based)
2. Input/Output Contracts
Define what your agent accepts and returns:
# Input schema (optional, for documentation)
tool = (
ToolBuilder("data-validator")
.description("Validates input data")
.input_schema({
"type": "object",
"properties": {
"data": {"type": "string"},
"format": {"type": "string", "enum": ["json", "csv"]}
},
"required": ["data"]
})
.output_schema({
"type": "object",
"properties": {
"is_valid": {"type": "boolean"},
"errors": {"type": "array", "items": {"type": "string"}}
}
})
.build()
)Developer Controls:
- Expected input structure
- Output data format
- Validation rules
- Error message content
Developer Does NOT Control:
- Authentication (platform handles)
- Rate limiting (platform enforces)
- Request routing (platform manages)
3. Workflow Logic
Define processing steps and dependencies:
workflow = (
WorkflowBuilder("process")
.description("Process invoice data")
.add_node(
NodeBuilder("extract")
.description("Extract text from PDF")
.uses_tool("ocr-service")
.outputs("raw_text")
.next_nodes("parse")
.build()
)
.add_node(
NodeBuilder("parse")
.description("Parse invoice data")
.uses_prompt("invoice-parser")
.outputs("structured_data")
.build()
)
.entry_node("extract")
.build()
)Developer Controls:
- Node execution order
- Data flow between nodes
- Conditional branching logic
- Error handling strategy
Developer Does NOT Control:
- Node execution infrastructure
- Parallel execution scheduling
- Resource cleanup
- State persistence
4. Versioning
Manage agent versions using semantic versioning:
# Version 1.0.0 - Initial release
agent_v1 = (
AgentBuilder("processor")
.version("1.0.0")
.description("Basic processing")
.add_workflow(basic_workflow)
.build()
)
# Version 1.1.0 - Add new feature (backward compatible)
agent_v1_1 = (
AgentBuilder("processor")
.version("1.1.0")
.description("Enhanced processing")
.add_workflow(enhanced_workflow)
.build()
)
# Version 2.0.0 - Breaking change
agent_v2 = (
AgentBuilder("processor")
.version("2.0.0")
.description("Redesigned processing")
.add_workflow(new_workflow)
.build()
)Developer Controls:
- When to release new versions
- Version number assignment
- Feature additions
- Deprecation timeline
Platform Controls:
- Version migration for users
- Backward compatibility enforcement
- Default version selection
- Version availability
Platform Responsibilities
Platform Core handles execution and infrastructure:
| Platform Responsibility | Description |
|---|---|
| User Authentication | OAuth, API keys, session management |
| Execution Orchestration | Scheduling, queuing, resource allocation |
| Retry Logic | Automatic retries on transient failures |
| Billing Calculation | Usage tracking, cost calculation |
| State Management | Execution state, persistence |
| Monitoring | Logs, metrics, alerts |
| Security | Sandboxing, isolation, data encryption |
| Scaling | Auto-scaling based on demand |
Responsibility Matrix
| Aspect | SDK/Developer | Platform Core |
|---|---|---|
| Define workflow structure | Yes | No |
| Validate definition locally | Yes | No |
| Execute workflows | No | Yes |
| Handle authentication | No | Yes |
| Calculate costs | No | Yes |
| Retry failed operations | No | Yes |
| Manage infrastructure | No | Yes |
| Store execution results | No | Yes |
| Version agent definitions | Yes | No |
| Enforce version compatibility | No | Yes |
Code Comparison
What You Write (SDK)
from ainalyn import AgentBuilder, WorkflowBuilder, NodeBuilder, PromptBuilder
from ainalyn.api import compile_agent
from pathlib import Path
# Define resources
prompt = (
PromptBuilder("extract-data")
.description("Extract structured data")
.template("Extract data from: {{input}}")
.variables("input")
.build()
)
# Define workflow
workflow = (
WorkflowBuilder("main")
.description("Main processing workflow")
.add_node(
NodeBuilder("process")
.description("Process input")
.uses_prompt("extract-data")
.outputs("result")
.build()
)
.entry_node("process")
.build()
)
# Define agent
agent = (
AgentBuilder("data-processor")
.version("1.0.0")
.description("Process and extract data")
.add_prompt(prompt)
.add_workflow(workflow)
.build()
)
# Compile and export
result = compile_agent(agent, Path("agent.yaml"))Total: ~40 lines focused on task logic.
What You Don’t Write (Platform)
The platform handles (not your responsibility):
- User authentication flows
- Payment processing
- Execution scheduling
- Resource allocation
- Retry mechanisms
- State persistence
- Monitoring and logging
- Infrastructure scaling
- Security sandboxing
- Billing calculation
Estimated: 1000+ lines you don’t need to write or maintain.
Boundary Clarification
Why These Boundaries Exist
Platform boundaries ensure:
- Consistent execution behavior across all agents
- Fair resource allocation
- Accurate billing
- Security isolation
- Operational reliability
Example: Retry Logic
If developers controlled retries:
# Developer A
retries = 3
# Developer B
retries = 1000
# Developer C
while True: # Infinite retries
retry()Problem: Platform overload, unfair resource usage, billing chaos.
Solution: Platform enforces consistent retry policy.
Example: Billing
If developers controlled billing:
# Developer A
cost = 0.01 # Underpriced
# Developer B
cost = calculate_llm_tokens() # Forgot tool costs
# Developer C
cost = 100.00 # OverpricedProblem: Inconsistent pricing, user confusion, revenue issues.
Solution: Platform calculates actual resource usage.
Practical Implications
Agent Definition Lifecycle
1. Development (SDK)
# You build the definition
agent = AgentBuilder("test").version("1.0.0")...build()
# You validate locally
result = validate(agent)
# You export to YAML
yaml = export_yaml(agent)2. Submission (Platform)
- Upload YAML to platform
- Platform reviews definition
- Platform applies governance policies
- Platform approves or rejects
3. Execution (Platform)
- User requests execution
- Platform authenticates user
- Platform allocates resources
- Platform executes workflow
- Platform tracks usage
- Platform calculates cost
- Platform stores results
State Management
Agents are stateless by design:
# Each execution is independent
execution_1 = platform.execute(agent, input_1)
execution_2 = platform.execute(agent, input_2)
# No shared state between executionsDeveloper Perspective:
- Process inputs
- Return outputs
- No state management code
Platform Perspective:
- Manages execution state
- Persists results
- Provides execution history
Resource Requirements
Declare resource needs, platform provisions:
# You declare requirements
agent = (
AgentBuilder("processor")
.add_tool(
ToolBuilder("external-api")
.description("Requires external API access")
.build()
)
.build()
)
# Platform provisions:
# - API credentials
# - Network access
# - Request limits
# - MonitoringCommon Questions
Q: Can I test execution locally?
A: No. The SDK validates structure only. Execution requires platform infrastructure.
# SDK can do this
result = validate(agent) # Structure validation
# SDK cannot do this
# execute(agent, input) # No local executionFor testing, use platform’s test/sandbox environment.
Q: Can I customize retry behavior?
A: No. Platform enforces consistent retry policies for all agents.
Reason: Ensures fair resource usage and reliable billing.
Q: Can I store data between executions?
A: No. Agents are stateless. Each execution is independent.
Alternative: Use platform-provided state management services (if available).
Q: Can I control execution timing?
A: No. Users initiate execution. Platform schedules and orchestrates.
Developer Role: Define what happens, not when it happens.
Best Practices
1. Focus on Definition Quality
# Good: Clear, well-documented definition
agent = (
AgentBuilder("processor")
.version("1.0.0")
.description("Processes invoices and extracts line items")
.add_workflow(
WorkflowBuilder("process")
.description("Main processing workflow")
.add_node(...)
.build()
)
.build()
)2. Design for Statelessness
# Good: Each execution is self-contained
node = (
NodeBuilder("process")
.description("Process input and return result")
.uses_prompt("process-prompt")
.outputs("result")
.build()
)
# Avoid: Assuming state persists
# (Platform handles state if needed)3. Validate Thoroughly
# Always validate before submission
result = validate(agent)
if not result.is_valid:
for error in result.errors:
print(f"{error.code}: {error.message}")4. Version Appropriately
# Follow semantic versioning
# MAJOR.MINOR.PATCH
# 1.0.0 → 1.0.1 (bug fix)
# 1.0.0 → 1.1.0 (new feature, backward compatible)
# 1.0.0 → 2.0.0 (breaking change)Summary
| You Control | Platform Controls |
|---|---|
| Agent definition structure | Execution infrastructure |
| Workflow logic | Resource allocation |
| Input/output contracts | Authentication |
| Version numbers | Retry logic |
| Resource declarations | Billing calculation |
| Local validation | Execution orchestration |
Your Focus: Define task logic clearly and correctly.
Platform Focus: Execute reliably and fairly.
Next Steps
- Building Your Agent - Design patterns
- How the SDK Works - Compilation process
- API Reference - SDK functions