Functions are Python scripts that handle complex logic, API integrations, and custom workflows. This page covers how to maintain functions as your agent evolves.
Quick reference
| I need to… | Action | Time estimate |
|---|
| Update function code | Edit in Function Editor → Save | 5-15 min |
| Debug a function error | Conversation Review → Diagnosis → Check logs | 10 min |
| Update API credentials | Secrets → Edit secret → Save | 3 min |
| Add logging to function | Use conv.log.info() in code | 2 min |
| Test function changes | Agent Chat → Trigger function | 5 min |
| Update function description | Edit description field → Save | 2 min |
| Fix function not triggering | Review KB action or rules → Clarify prompt | 10 min |
| Update API integration | API Integrations → Edit endpoint | 5 min |
When to update functions
Update your functions when:
- API endpoints change - External services update their URLs or parameters
- Business logic evolves - New requirements or edge cases emerge
- Credentials expire - API keys or tokens need rotation
- Performance issues - Functions are too slow or timing out
- Error patterns emerge - Logs show repeated failures
- New features needed - You want to add capabilities
How to update function code
Basic update workflow
- Go to Functions in the Build tab
- Select the function you want to update
- Edit the Python code in the Function Editor
- Click Save
- Test in Agent Chat
- Review logs in Conversation Review → Diagnosis
- Publish when satisfied
Always test function changes in Sandbox before promoting to Live.
Using version control
While Agent Studio doesn’t have built-in version control for functions:
- Document changes - Add comments explaining what changed and why
- Use version descriptions - When publishing, note function updates
- Keep backups - Copy function code to external files before major changes
- Test incrementally - Make small changes and test frequently
Example: Updating a booking function
Before:
def book_reservation(date, time, party_size):
# Old API endpoint
response = requests.post(
"https://api.example.com/v1/bookings",
json={"date": date, "time": time, "guests": party_size}
)
return {"utterance": "Your reservation is confirmed."}
After:
def book_reservation(date, time, party_size, special_requests=None):
# Updated to v2 API with new parameters
conv.log.info(f"Booking for {party_size} guests on {date} at {time}")
payload = {
"date": date,
"time": time,
"guests": party_size,
"special_requests": special_requests or ""
}
response = requests.post(
"https://api.example.com/v2/bookings",
json=payload,
headers={"Authorization": f"Bearer {secret_vault('booking_api_key')}"}
)
if response.status_code == 200:
conv.log.info("Booking successful")
return {"utterance": "Your reservation is confirmed."}
else:
conv.log.error(f"Booking failed: {response.text}")
return {"utterance": "I'm having trouble completing your reservation. Let me transfer you to someone who can help."}
Debugging function errors
Using conv.log for debugging
Add structured logging to your functions:
# Info level - general flow tracking
conv.log.info("Starting payment processing")
# Warning level - potential issues
conv.log.warning("Customer account has low balance")
# Error level - failures
conv.log.error(f"Payment API returned error: {error_message}")
# Mark as PII if logging sensitive data
conv.log.info("Processing order for customer", pii=True)
Logs appear in:
- Conversation Review → Diagnosis (after calls)
- Agent Chat (during testing)
- Conversations API (for programmatic access)
Common debugging steps
-
Identify the issue
- Review Conversation Review → Diagnosis
- Check function input/output in logs
- Look for error messages
-
Reproduce in Agent Chat
- Test the exact scenario that failed
- Watch logs in real-time
- Try variations to isolate the problem
-
Check function inputs
- Are parameters being passed correctly?
- Is the LLM extracting the right values?
- Are there type mismatches?
-
Validate external calls
- Test API endpoints directly (Postman, curl)
- Verify credentials are current
- Check for rate limiting or timeouts
-
Review function description
- Is it clear when the function should trigger?
- Are parameter descriptions accurate?
- Does the LLM understand the purpose?
Common function errors
| Error | Likely cause | Solution |
|---|
| Function not triggering | Unclear description or KB action | Simplify function description; clarify when to call it |
| Wrong parameters passed | LLM misunderstanding | Improve parameter names and descriptions |
| Timeout errors | Slow API or complex logic | Add delay controls; optimize code; use async |
| Authentication failures | Expired credentials | Update secrets; check API key permissions |
| Import errors | Missing library | Add library to imports; check availability |
| Type errors | Unexpected data format | Add validation; handle edge cases |
| Rate limit errors | Too many API calls | Add caching; implement retry logic |
Managing secrets and credentials
Updating secrets
When API keys or credentials change:
- Go to Secrets in the left navigation
- Find the secret you need to update
- Click Edit
- Enter the new value
- Save
Updating a secret affects all functions using it. Test thoroughly after updating.
Using secrets in functions
Access secrets securely:
from poly import secret_vault
# Retrieve a secret
api_key = secret_vault("my_api_key")
# Use in API calls
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get("https://api.example.com/data", headers=headers)
Secret management best practices
- Rotate regularly - Update credentials every 90 days
- Use descriptive names -
stripe_live_api_key not key1
- Document dependencies - Note which functions use which secrets
- Test after rotation - Verify all functions still work
- Limit permissions - Use least-privilege API keys
Checking secret access
To see which secrets a function can access:
- Open the function in the Function Editor
- Look at the Secrets box in the top right
- Click to see available secrets and copy code snippets
If a secret is missing, check Access Control for Secrets to grant permissions.
Managing API integrations
Updating API integrations
The API Integrations feature lets you configure endpoints per environment:
- Go to API Integrations
- Select the integration to update
- Update base URLs, authentication, or parameters
- Configure per environment (Sandbox, Pre-release, Live)
- Save and test
Supported authentication types:
- No Auth
- Basic Auth
- API Key
- OAuth 2.0
Using API integrations in functions
Call configured APIs using conv.api:
# Call a configured API integration
result = conv.api.booking_system.create_reservation(
date="2025-03-15",
time="19:00",
guests=4
)
# Log the response for debugging
conv.log.info(f"API response: {result}")
Environment-specific configurations
Configure different endpoints per environment:
- Sandbox - Use test/staging API endpoints
- Pre-release - Use UAT endpoints
- Live - Use production endpoints
This ensures you don’t accidentally call production APIs during testing.
Reducing latency
If functions are slow:
- Use delay controls - Add filler phrases for long-running functions
- Cache results - Store frequently-accessed data
- Optimize API calls - Reduce unnecessary requests
- Use async operations - Don’t block on slow operations
- Simplify logic - Remove unnecessary processing
Delay controls
For functions that take time, use delay controls to keep the conversation flowing:
from poly import DelayControl
def slow_function():
delay = DelayControl(
delay_seconds=1.0,
filler_utterances=["Let me check that for you.", "One moment please."]
)
# Long-running operation
result = call_slow_api()
return {"utterance": f"Here's what I found: {result}"}
Delay timing starts when the function begins executing, not when the user stops speaking. Account for LLM and ASR latency.
Track function performance:
- Review call logs - Check function execution times
- Monitor API latency - Identify slow external services
- Use conv.log - Log timing information
- Analyze patterns - Look for performance degradation over time
Improving function triggering
When functions don’t trigger
If the agent isn’t calling your function when expected:
- Simplify the description - Make it crystal clear when to call
- Update KB actions - Ensure topics reference the function correctly
- Review agent rules - Add explicit instructions about when to use the function
- Test parameter extraction - Verify the LLM can extract required values
- Check for conflicts - Ensure other functions aren’t being called instead
Function description best practices
Bad:
# Description: "Handles reservations"
Good:
# Description: "Call this function when the user wants to book a table.
# Required: date, time, party_size.
# Only call after confirming all three parameters with the user."
Using stop keywords
Prevent unwanted function triggers with stop keywords:
- Go to Response Control → Stop Keywords
- Add patterns that should halt the response
- Optionally trigger a function when matched
Example: Stop the agent from saying “Let me transfer you” and trigger a handoff function instead.
Testing function changes
Test in Agent Chat
- Open Agent Chat
- Select the Sandbox environment
- Trigger the function with realistic scenarios
- Review logs in the Diagnosis panel
- Verify outputs are correct
Use Test Cases and Test Sets
Create automated tests for functions:
- Go to Test Cases
- Create scenarios that trigger your function
- Add to a Test Set
- Run automatically on publish/promote
Manual testing checklist
Common workflows
Updating an API endpoint
- Identify which function uses the endpoint
- Update the URL in the function code or API Integration
- Test in Sandbox with Agent Chat
- Review logs to verify success
- Publish and promote to Pre-release
- Run Test Set to validate
- Promote to Live
Rotating API credentials
- Generate new credentials in the external service
- Update the secret in Agent Studio
- Test all functions using that secret
- Monitor for authentication errors
- Deactivate old credentials after confirming new ones work
Adding error handling
- Identify common failure modes from logs
- Add try/except blocks to function code
- Use conv.log.error() to track failures
- Return graceful fallback responses
- Test error scenarios in Agent Chat
- Monitor error rates after deployment
Debugging a production issue
- Review recent calls in Conversation Review
- Filter for calls with errors
- Check Diagnosis logs for the failing function
- Reproduce in Sandbox
- Fix the issue
- Test thoroughly
- Publish and promote urgently if critical
Best practices
Code quality
- Use descriptive names -
book_restaurant_reservation not func1
- Add comments - Explain complex logic
- Handle errors gracefully - Don’t let exceptions crash the agent
- Validate inputs - Check parameters before using them
- Log strategically - Info for flow, warnings for issues, errors for failures
Maintenance routine
- Weekly log review - Check for new error patterns
- Monthly credential rotation - Update API keys and secrets
- Quarterly function audit - Remove unused functions, optimize slow ones
- Test after updates - Always verify changes in Sandbox first
Documentation
- Document function purpose - What does it do and why?
- List dependencies - Which APIs, secrets, or integrations does it use?
- Note edge cases - What scenarios need special handling?
- Track changes - Keep a changelog of major updates
Related pages