Tutorial: Organizing your code
Level 3 – Lesson 1 of 5 – Structure your Agent Studio code so it stays manageable as your project grows.
Organize Python functions into utility files, use standard imports for helpers, and use conv.functions for main functions – this keeps complex projects readable and maintainable.
This lesson assumes familiarity with Python and functions. Some examples reference flows, which are covered in the next lesson — you can follow along without understanding flows yet, or read Lesson 2 first if you prefer.
How Agent Studio organizes code
Each entry on the Tools page is a Python file, not just a single function. This means you can define multiple functions in one file – utility helpers, validation logic, formatters – alongside the main function that Agent Studio creates.
Key rules:
- Each file has one main function with the same name as the file – this is the one Agent Studio validates and constrains (it must accept
convas the first argument) - You can define additional functions above the main function – these are helpers that don’t need to follow Agent Studio’s signature rules
- Flow functions live in a subfolder named after the flow
Utility files
You don’t need 50 separate function entries for 50 helpers. Group related utilities in a single file:
The main function at the bottom is required by Agent Studio but can be a no-op. Set the LLM description to indicate this file is a utility collection, not an LLM-callable function.
Importing functions
There are two ways to use code from other files.
Method 1: Python imports
Standard Python import syntax works for any function in any file:
When using Python imports with main functions, you must pass conv (and flow for flow functions) as arguments:
Method 2: conv.functions and flow.functions
The platform-supported method for calling main functions:
Advantages:
- Autocomplete and type hints in the editor
- No need to pass
convorflow– they’re handled automatically - Officially supported by the platform
Limitation: You can only reference main functions this way. You cannot access utility helpers (like is_valid_tracking_number) through conv.functions.
Check your understanding
You have a utility function is_valid_email defined inside validationUtils.py (not the main function). How do you use it in another file?
You have a utility function is_valid_email defined inside validationUtils.py (not the main function). How do you use it in another file?
- conv.functions.validationUtils.is_valid_email()
- from functions.validationUtils import is_valid_email
- flow.functions.is_valid_email()
- import validationUtils; validationUtils.is_valid_email()
Answer: from functions.validationUtils import is_valid_email
conv.functions only works for main functions. To access a helper defined above the main function, use standard Python import syntax: from functions.fileName import functionName.
To import a helper function called is_valid_email from validationUtils.py, write: from functions.________ import is_valid_email
Answer: validationUtils
When to use which method
Python imports in Agent Studio may show squiggly underlines in the editor (“import could not be resolved”). These are false positives – the imports work at runtime.
Practical example: order tracking
Here’s how a real flow function uses both import methods:
Function types and their roles
As your project grows, distinguishing between different function types becomes critical. Here’s a reference for how to think about each type:
Never import flow functions into other flow functions or global functions. This creates “invisible dependencies” that are extremely difficult to debug – if a flow function is no longer referenced in any prompt, it disappears from the UI but may still be imported elsewhere.
Separation of concerns
Follow a “thin flows, fat services” approach:
- Keep LLM-facing flow functions focused on: collecting user input, writing state, and transitioning steps
- Put deterministic logic (validation, comparisons, branching rules, API formatting) in helper modules
- Do not import LLM-facing functions into unrelated helpers as a way to reuse business logic – reuse helper functions instead
Best practices
Common pitfalls
Try it yourself
Challenge: Refactor a monolithic function
You have a single function that validates a tracking number, calls an API, formats the result for TTS, and returns it. It’s 80 lines long.
Plan how you would split this into:
- A validation utility
- An API wrapper
- A TTS formatting utility
- A main function that composes them
Hint
Create a trackingUtils.py with the validation and formatting helpers. Create a getOrder.py for the API call. The main flow function imports from both and orchestrates the logic.
Example structure
trackingUtils.py:
is_valid_tracking_number(number)– regex validationtracking_number_to_words(number)– TTS formattingtracking_utils(conv)– no-op main function
getOrder.py:
getOrder(conv, tracking_number)– API call, returns order dict or None
Flow function (saveTrackingNumber):
Check your understanding
You need to update a tracking number format from '3 letters + 5 digits' to '4 letters + 5 digits'. The validation is used in 5 different flow functions. What's the best approach?
- Update the regex in all 5 flow functions
- Update it in the one utility file where the validation function is defined
- Create a new validation function and gradually migrate
- Use conv.functions to centralize the validation
Answer: Update it in the one utility file where the validation function is defined
If validation is defined once in a utility file and imported everywhere, you update it in one place. This is the core benefit of modular code – single source of truth.

