Steps are the fundamental building blocks of NOMOS agents. Each step represents a discrete phase in your agent’s workflow with specific responsibilities, available tools, and transition logic. This step-based architecture is what makes NOMOS agents testable, maintainable, and reliable.
Steps = Focused ResponsibilitiesEach step has a single, well-defined purpose in your agent’s workflow. This decomposition makes complex agent behavior manageable and predictable.
Single Purpose
Each step handles one specific type of interaction or task
Controlled Tools
Steps only have access to tools they actually need
Clear Transitions
Explicit conditions determine when and where to move next
steps: - step_id: greet_customer # Can also use 'id' description: | # Can also use 'desc' Welcome the customer and understand their needs. Ask how you can help them today and listen for their response. available_tools: [] # Can also use 'tools' routes: # Can also use 'paths' - target: take_order # Can also use 'to' condition: Customer wants to place an order # Can also use 'when' - target: customer_support condition: Customer has questions or needs help - target: end condition: Customer wants to leave examples: # Can also use 'eg' - context: "New customer enters" decision: "Greet warmly and ask how to help" visibility: "always"
Field Naming FlexibilityNOMOS supports both compact (id, desc, tools, paths, to, when, eg) and descriptive (step_id, description, available_tools, routes, target, condition, examples) field names. You can use either convention or mix them in the same configuration file.
Answer models define the expected structure and format of your agent’s responses. They ensure consistent, parseable output that can be easily processed by downstream systems or validated for correctness.
Why Use Answer Models?Answer models provide type safety, validation, and structured data extraction from your agent’s responses. They’re especially valuable for:
API integrations
Data processing workflows
Multi-step processes requiring consistent data formats
Define simple answer models directly in your step configuration:
Copy
- step_id: collect_user_info description: | Ask for user's name and email address. answer_model: name: type: str description: User's full name email: type: str description: User's email address age: type: int description: User's age in years optional: true
# Reference main model from schemaanswer_model: user_profile# Reference specific model from Python schemaanswer_model: order_schema.Order# Reference nested modelanswer_model: order_schema.OrderItem
Add descriptions for complex or non-obvious fields
Copy
answer_model: processing_status: type: str description: | Current status of the order processing pipeline. Values: 'received', 'validated', 'processing', 'shipped', 'delivered' enum: ['received', 'validated', 'processing', 'shipped', 'delivered']
- step_id: optimized_lookup description: | Efficiently lookup customer information using cached data when possible. available_tools: - quick_customer_lookup # Fast, cached lookup - detailed_customer_fetch # Slower, comprehensive lookup - update_customer_cache # Update cache with new info routes: - target: serve_from_cache condition: Customer info found in cache and is recent - target: fetch_and_cache condition: Customer info not cached or outdated
# tests.agent.yamlunit: test_greeting_step: context: current_step_id: "greeting" input: "Hello, I'm looking for help with my order" expectation: "Greets customer and routes to support_request step" test_order_step_with_tools: context: current_step_id: "take_order" input: "I'd like a large latte with oat milk" expectation: "Uses menu tools and adds specific item to cart" test_error_handling: context: current_step_id: "payment_processing" input: "My card was declined" expectation: "Provides helpful error message and routes to payment_retry"
Only provide tools that are needed for the step’s purpose
Copy
- step_id: customer_greeting available_tools: [] # No tools needed for greeting- step_id: lookup_order available_tools: - search_orders # Only order search capability- step_id: process_refund available_tools: - search_orders # Need to find order - issue_refund # Need to process refund # No other payment tools
- step_id: api_dependent_step routes: - target: success_path condition: API call successful - target: retry_path condition: API call failed but retryable - target: fallback_path condition: API unavailable but alternative exists - target: failure_path condition: No alternatives available
Start Simple, Then RefineBegin with basic steps and gradually add complexity. It’s easier to split a step that’s doing too much than to combine steps that are too granular.
Here are well-designed steps from the NOMOS examples:
Copy
- step_id: start description: | Greet the customer and ask how can I help them. Use the get_available_coffee_options tool if they need menu information. available_tools: - get_available_coffee_options routes: - target: take_coffee_order condition: Customer is ready to place a new order- step_id: take_coffee_order description: | Ask for coffee preference and size. Manage cart operations based on customer requests. available_tools: - get_available_coffee_options - add_to_cart - remove_item - clear_cart routes: - target: finalize_order condition: User wants to finalize the order - target: end condition: Customer wants to cancel
Steps are the foundation of reliable AI agents. By designing them with clear purposes, appropriate tool access, and explicit transition logic, you create agents that are both powerful and predictable.