Hands-On Session #2: Building Custom Agents & Rules
Build Custom Agents or customize existing agent behavior with the 3 building blocks of agentic workflows: Context, Tools, Triggers.
In this session, you'll learn how to customize agentic behavior by creating both Rules (which enhance the context provided to your agents) and Agents (which replace or extend default behavior from system instructions, enabling you to test and refine your own agentic behavior).
Let's create a rule that applies when working with code files, ensuring consistent code quality across your project.
You can ask Otto to create this file for you by asking:
Create a new rule that applies when working with code files, ensuring consistent code quality across the project.
Or you can create the file manually:
Right-click on the otto/rules/ folder
Select New file
Name the file code-style-guide.md
Paste the following content:
--- otto: rule: alwaysApply:true description:"Code style guide for data engineering" globs:["*.py","*.sql"] keywords:[] --- # Code Style Guide When writing or reviewing code, follow these standards: ## Python Style ### Naming Conventions - Use `snake_case` for functions and variables - Use `PascalCase` for classes - Use `UPPER_CASE` for constants - Use descriptive names that explain intent (e.g., `calculate_discount` not `calc`) ### Code Structure - Keep functions focused on a single responsibility - Limit function length to 50 lines or less - Use type hints for function parameters and return values - Add docstrings to all functions and classes ### Best Practices - Avoid magic numbers — use named constants - Handle errors explicitly — never use bare `except:` clauses - Use list comprehensions for simple transformations - Prefer `is` and `is not` over `==` and `!=` for None comparisons ### Formatting - Use 4 spaces for indentation (no tabs) - Maximum line length: 100 characters - Add blank lines between functions and classes - Use trailing commas in multi-line structures ## SQL Style ### Naming Conventions - Use `snake_case` for table and column names - Use descriptive aliases (e.g., `customer_id AS cust_id` not `c AS id`) - Prefix temporary tables with `tmp_` or `temp_` ### Query Structure - Use CTEs for complex queries instead of nested subqueries - Avoid `SELECT *` — explicitly list columns - Use `WHERE` clauses to filter early in the query - Add comments for complex business logic ### Performance - Use appropriate indexes - Avoid functions in WHERE clauses when possible - Use `EXISTS` instead of `IN` for subqueries when checking existence - Consider partitioning for large tables ## General Principles -**Readability over cleverness**: Code should be easy to understand -**DRY (Don't Repeat Yourself)**: Extract common patterns into functions -**Document why, not what**: Comments should explain reasoning, not restate code
Create sql transform on the sales component by adding: sale_date/hour/day_of_week from timestamp, channel logic (Store/Vendor/Website based on store_id/vendor_id), and calculated totals (price * quantity, with tax)
Notice how Otto now references your style guide when working with code files! You can see all the rules Otto has applied by hovering over the icon above your last prompt.
Agents replace or extend Otto's default system instructions entirely. For this track, we'll create an agent that systematically reviews code and provides structured, actionable feedback.
warning
Creating a custom agent overrides Otto's system instructions unless you add extends: otto. Your agent won't have Otto's built-in behaviors unless you explicitly include them. This is an excellent opportunity to practice context engineering from scratch! See the Custom Agents reference for more details.
Please create a new agent that reviews code and provides structured, actionable feedback.
Or you can create the file manually:
Right-click on the otto/agents/ folder
Select New file
Name the file code_reviewer.md
Paste the following content:
--- otto: agent: name: code_reviewer extends: otto # tools: ["*"] # optionally restrict to a subset of tools --- # Code Reviewer Agent You are an expert code reviewer specializing in data engineering code. Your job is to systematically analyze code and provide comprehensive, structured reviews. ## Your Review Process When reviewing code, you must follow this exact workflow: 1.**Read and analyze** the code thoroughly - Understand what the code is trying to accomplish - Identify all files and functions being reviewed - Note the context and dependencies 2.**Check against style guide** - Reference any code style rules that apply - Verify naming conventions are followed - Check formatting and structure 3.**Identify issues systematically** - Style violations (naming, formatting, structure) - Best practice violations (error handling, efficiency, maintainability) - Potential bugs (logic errors, edge cases, type issues) - Performance concerns (inefficient queries, unnecessary operations) - Security issues (SQL injection risks, sensitive data exposure) 4.**Prioritize findings** -**Critical**: Bugs that will cause failures or data corruption -**High**: Performance issues or security concerns -**Medium**: Style violations that impact readability -**Low**: Minor improvements or suggestions 5.**Provide actionable feedback** - For each issue, explain what's wrong and why - Provide specific line numbers or code locations - Suggest concrete fixes with code examples ## Required Output Format Your review MUST follow this exact structure: ### 📊 Review Summary -**Files reviewed**: [list of files] -**Total issues found**: [number] - Critical: [count] - High: [count] - Medium: [count] - Low: [count] -**Overall assessment**: [1-2 sentence summary] ### 🔴 Critical Issues For each critical issue: -**Issue**: [brief description] -**Location**: [file:line or function name] -**Impact**: [what could go wrong] -**Fix**: [specific solution with code example] ### ⚠️ High Priority Issues [Same format as Critical Issues] ### 📝 Medium Priority Issues [Same format as Critical Issues] ### 💡 Low Priority / Suggestions [Same format as Critical Issues] ### ✅ Positive Observations - [What the code does well] ### 🔧 Recommended Next Steps 1. [Action item 1] 2. [Action item 2] 3. [Action item 3] ## Review Guidelines - Be thorough but constructive — focus on helping improve the code - Provide code examples for all suggested fixes - Explain the "why" behind each recommendation - Prioritize issues that could cause production problems - Acknowledge good practices when you see them - If reviewing multiple files, organize findings by file Remember: Your goal is to help write better, more maintainable code.
Review this Python code and suggest improvements: ```python # calculate the discount for custoemrs def calc(t,x,h,z): data = [] if t=="gold": d=0.2 elif t=="silver": d=0.1 elif t=="bronze": d=0.05 elif t=="platinum": d=0.25 else: d=0 if h==True: d=d+0.05 if z==True: if t=="gold" or t=="platinum": d=d+0.1 else: d=d+0.02 f=x*(1-d) # TODO: fix this later try: result = f / x * 100 except: pass return f ```
Notice how the agent provides a structured review with prioritized issues and specific fixes!
Before continuing
Switch back to the default Otto agent before proceeding with the lab. Click on your agent name at the bottom of the chat panel and select Otto to restore the default behavior.
Now that you have a code style guide rule and a code reviewer agent, let's create an automation that runs weekly to review all code changes and send you a comprehensive report.
Automations in Ascend enable automatic triggering of actions based on defined conditions. They combine triggers (sensors for time-based schedules or events for system events) with actions (like running Otto) to create intelligent workflows.
automation: name: weekly-code-review enabled:true triggers: sensors: -type: timer name: weekly-timer config: schedule: cron:'0 9 * * MON'# Every Monday at 9 AM UTC actions: -type: run_otto name: weekly-code-review config: agent_name: code_reviewer prompt:>- # Weekly Code Review Instructions You are being invoked as part of a weekly automated code review process. Your job is to analyze all code changes made in the past week and provide a comprehensive review. You cannot ask for help or clarification; you must complete this end-to-end based on your own analysis. ## Your Tasks 1. **Identify all code changes from the past week** - Review git history to find all commits from the last 7 days - Identify which files were modified, added, or deleted - Focus on Python (.py) and SQL files 2. **Review each changed file** - Apply the code style guide rules - Check for best practices violations - Identify potential bugs or performance issues - Look for security concerns 3. **Compile a comprehensive report** - Follow your standard review output format - Organize findings by file - Prioritize issues by severity - Include positive observations where code quality is good 4. **Flag items needing attention** - Highlight any critical issues that require immediate action - Note any patterns of recurring issues across files - Suggest areas for improvement in the codebase ## Report Structure Your report should include: ### Week Summary - Date range covered - Total files changed - Total lines added/removed - Overall code quality assessment ### Files Reviewed [List each file with a brief summary] ### Critical Issues Requiring Attention [Issues that must be addressed] ### Code Quality Trends [Patterns you notice across the week's changes] ### Recommendations [Actionable next steps] Be thorough, constructive, and focus on helping maintain high code quality standards across the project. You cannot ask the user for help. You must send the user an email.
Before deploying, let's test the automation manually:
Open Otto chat (Ctrl+I)
Make sure you're using the default Otto agent (not the Code Reviewer)
Ask Otto to execute the automation's prompt:
Please follow the exact instructions in the weekly-code-review automation and generate a weekly code review based on my Workspace activity from the past week. Provide the comprehensive report as specified.
This will show you what the automated review will look like when it runs!