Audience Builder
Purpose
The primary end-to-end skill. Takes a natural language audience description and produces a validated, sized, and confirmed segment. Composes schema-discovery, filterql-builder, segment-manager, and confirmation-gate.
Environment
LYTICS_API_TOKEN-- API authentication tokenLYTICS_API_URL-- Base URL (default:https://api.lytics.io)
Inputs
- Natural language description of the desired audience
- Optional: segment name, table (default:
user), kind (default:segment), tags
End-to-End Flow
Step 0: Check if Advisor Would Be Better
If the user's request is goal-oriented rather than specific (e.g., "I want to drive more conversions" vs "US users who visited 5+ times"), suggest starting with the audience-advisor skill first:
"It sounds like you have a business goal in mind. Would you like me to analyze your data first to recommend the best targeting strategy? I can look at ML models, field distributions, and existing segments to suggest evidence-based filters."
If the user has a specific audience description, proceed directly to Step 1.
Step 1: Parse Intent
Extract the key concepts from the natural language description:
- Target attributes (demographics, behaviors, properties)
- Inclusion criteria (what they have/did)
- Exclusion criteria (what they lack/didn't do)
- Temporal constraints (time-based conditions)
Example: "US customers who haven't purchased socks in over a year"
- Attribute: country = US
- Exclusion: no sock purchases
- Temporal: over 1 year ago
Step 2: Schema Discovery
Use schema-discovery skill to find matching fields:
# Get all fields to find candidates
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/schema/user/field" \
-H "Authorization: ${LYTICS_API_TOKEN}"Score candidate fields by name match, type compatibility, and value distribution. For the example:
- "US customers" -> look for:
country,geo_country,country_code(string type) - "purchased socks" -> look for:
products_purchased(set),purchase_categories(set),last_purchase_date(date)
Fetch value suggestions for top candidates -- the q parameter is required:
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/api/schema/user/fieldsuggest/${FIELD}?q=${QUERY}" \
-H "Authorization: ${LYTICS_API_TOKEN}"Example: /api/schema/user/fieldsuggest/country?q=US
Confirm field values match (e.g., country contains "US", products_purchased contains "socks").
Step 3: Build FilterQL
Use filterql-builder skill to construct the filter expression.
Map each concept to a FilterQL condition based on field type (see ../references/field-types.md):
- String equality:
country = "US" - Set non-membership:
NOT products_purchased INTERSECTS ("socks") - Date comparison:
last_sock_purchase < "now-1y"
Compose with AND/OR:
FILTER AND (
country = "US",
NOT products_purchased INTERSECTS ("socks")
) FROM user ALIAS us_no_socksStep 4: Validate FilterQL
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/api/segment/validate" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: text/plain" \
-d 'FILTER AND (country = "US", NOT products_purchased INTERSECTS ("socks")) FROM user ALIAS us_no_socks'If validation fails:
- Parse the error message
- Identify the syntax issue
- Fix the FilterQL
- Retry (max 3 attempts)
- If still failing, show the error and ask the user for guidance
Step 5: Estimate Size
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/api/segment/size" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: text/plain" \
-d 'FILTER AND (country = "US", NOT products_purchased INTERSECTS ("socks")) FROM user ALIAS us_no_socks'Step 6: Present Draft (Confirmation Gate)
Show the user a complete summary before creating:
## Proposed Audience: US Non-Sock Buyers
**Name**: US Non-Sock Buyers
**Slug**: us_no_socks
**Table**: user
**Kind**: segment
**Description**: US customers who have not purchased socks
**Field Mapping**:
- "US customers" -> `country = "US"` (field type: string, sample values: US, CA, UK)
- "haven't purchased socks" -> `NOT products_purchased INTERSECTS ("socks")` (field type: []string)
**FilterQL**:
FILTER AND (country = "US", NOT products_purchased INTERSECTS ("socks")) FROM user ALIAS us_no_socks
**Estimated Size**: ~45,000 profilesThen show the raw API payload:
{
"name": "US Non-Sock Buyers",
"slug_name": "us_no_socks",
"description": "US customers who have not purchased socks",
"segment_ql": "FILTER AND (country = \"US\", NOT products_purchased INTERSECTS (\"socks\")) FROM user ALIAS us_no_socks",
"kind": "segment",
"table": "user",
"is_public": true,
"save_hist": true,
"tags": []
}Ask for confirmation: "Proceed with creating this segment? (yes/no)"
Step 7: Execute on Approval
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/segment" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{ ... approved payload ... }'Report the result:
Successfully created segment "US Non-Sock Buyers" (id: abc123)
View at: ${LYTICS_API_URL}/segment/us_no_socksAfter successful creation, offer an audience snapshot: "Segment created successfully. Would you like to see an audience snapshot showing the demographic breakdown and field distributions?" If yes, invoke the audience-snapshot skill with the new segment ID.
Handling Ambiguity
When field mapping is ambiguous (multiple equally strong candidates):
- Present the top candidates with sample values
- Let the agent pick the best match based on context -- do NOT prompt the user unless truly ambiguous
- Only ask the user when there's a genuine tie or the field purpose is unclear
Updating Existing Segments
If the user wants to update an existing segment:
- Fetch the current segment:
GET /v2/segment/${ID}?inline=true - Show current FilterQL and proposed changes
- Use
PUT /v2/segment/${ID}instead of POST
Error Handling
- No matching fields: Report clearly, suggest the user describe their data differently
- Validation failure after 3 retries: Show the FilterQL and error, ask for help
- Empty segment (size 0): Warn and suggest broadening criteria
- Very large segment (>90% of total): Note this and confirm intent
Dependencies
- Composes:
schema-discovery skill,filterql-builder skill,segment-manager skill,../references/confirmation-gate.md - References:
../references/filterql-grammar.md,../references/field-types.md