Skip to content

Commit 333591b

Browse files
committed
cleanup some agent prompt stuff
1 parent 6e74b09 commit 333591b

File tree

3 files changed

+55
-33
lines changed

3 files changed

+55
-33
lines changed

apps/api/src/agent/handlers/chart-handler.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ export async function handleChartResponse(
4040
try {
4141
const queryResult = await executeQuery(parsedAiJson.sql);
4242

43+
const content =
44+
parsedAiJson.text_response ||
45+
(queryResult.data.length > 0
46+
? `Found ${queryResult.data.length} data points for your analysis. The chart below shows the data patterns and trends.`
47+
: getRandomMessage(noDataMessages));
48+
4349
return {
4450
type: 'complete',
45-
content:
46-
queryResult.data.length > 0
47-
? `Found ${queryResult.data.length} data points. Displaying as a ${parsedAiJson.chart_type ? parsedAiJson.chart_type.replace(/_/g, ' ') : 'chart'}.`
48-
: getRandomMessage(noDataMessages),
51+
content,
4952
data: {
5053
hasVisualization: queryResult.data.length > 0,
5154
chartType: parsedAiJson.chart_type || 'bar',

apps/api/src/agent/handlers/metric-handler.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,33 +59,34 @@ function generateTextResponseWithActualValue(
5959
return `${metricLabel || 'Result'}: ${String(formattedValue)}`;
6060
}
6161

62-
// If we have a number value, try to replace any number in the text response
62+
// Handle [RESULT] placeholders first - this is what the AI should use
63+
if (textResponse.includes('[RESULT]')) {
64+
const formattedValue =
65+
typeof actualValue === 'number'
66+
? actualValue.toLocaleString()
67+
: String(actualValue);
68+
return textResponse.replace(/\[RESULT\]/g, formattedValue);
69+
}
70+
6371
if (typeof actualValue === 'number') {
64-
// Round to reasonable precision for display
6572
const roundedValue = Math.round(actualValue * 100) / 100;
6673
const formattedValue = roundedValue.toLocaleString();
6774

68-
// Replace any standalone numbers (with optional decimals) with the actual value
69-
// This pattern matches numbers but avoids replacing numbers within words
7075
const numberPattern = /\b\d+(?:\.\d+)?\b/g;
7176

72-
// Check if the text contains numbers that might be the AI's estimate
7377
const numbersInText = textResponse.match(numberPattern);
7478
if (numbersInText && numbersInText.length > 0) {
75-
// Replace only the first number found with our actual value
76-
// This assumes the main metric is the first number in the sentence
7779
let hasReplaced = false;
7880
return textResponse.replace(numberPattern, (match) => {
7981
if (!hasReplaced) {
8082
hasReplaced = true;
8183
return formattedValue;
8284
}
83-
return match; // Keep other numbers unchanged
85+
return match;
8486
});
8587
}
8688
}
8789

88-
// If no number replacement needed, return original text
8990
return textResponse;
9091
}
9192

apps/api/src/agent/prompts/agent.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ You are Databunny, a world-class, specialized data analyst for the website ${web
7272
<directive name="JSON Output Only">
7373
You MUST ONLY output a single, valid JSON object. Do not include any text, markdown, or explanations outside of the JSON structure.
7474
</directive>
75+
<directive name="Response Quality Standards">
76+
You MUST provide comprehensive, insightful, and actionable responses. Minimal responses like "Result: 100" or single sentences without context are UNACCEPTABLE. Every response must educate the user, provide business context, and offer practical next steps when appropriate. Your role is to be a knowledgeable data analyst who helps users understand what their data means and what they should do about it.
77+
</directive>
7578
</core_directives>
7679
7780
<database_schema>
@@ -185,11 +188,15 @@ Your task is to process the <user_query> according to the current <mode>, while
185188
</case>
186189
<case when="mode == 'execute_chat'">
187190
<instructions>
188-
Your goal is to provide a direct, final answer in a single turn.
189-
1. **Think:** In a <thinking_steps> array within your final JSON, briefly explain your reasoning in simple terms - what you need to find and how you'll approach it.
191+
Your goal is to provide a comprehensive, insightful, and actionable answer in a single turn.
192+
1. **Think:** In a <thinking_steps> array within your final JSON, explain your reasoning in simple terms - what you need to find and how you'll approach it. Keep it conversational and business-focused.
190193
2. **Generate SQL:** Using the patterns, rules, and examples from the <knowledge_base>, write a valid ClickHouse SQL query.
191-
3. **Format Response:** Choose the correct response_type and chart_type. For metrics, provide a helpful text_response as context, following the <explanation_guidelines>.
192-
4. **Respond:** Output a single, valid JSON object matching the <chat_response_format>.
194+
3. **Format Response:** Choose the correct response_type and chart_type. For ALL response types, provide rich, detailed explanations:
195+
- **Metrics:** MUST include comprehensive context, interpretation, benchmarks, and actionable recommendations following <explanation_guidelines>
196+
- **Text responses:** MUST be detailed, helpful, and provide real value - never give minimal answers
197+
- **Charts:** MUST include interpretation of what the data patterns mean and business implications
198+
4. **Quality Check:** Ensure your response provides genuine insight and value, not just raw data
199+
5. **Respond:** Output a single, valid JSON object matching the <chat_response_format>.
193200
</instructions>
194201
</case>
195202
<case when="mode == 'execute_agent_step'">
@@ -215,10 +222,16 @@ Your task is to process the <user_query> according to the current <mode>, while
215222
</time_rules>
216223
<response_guides>
217224
<response_type_selection>
218-
- "metric": Single specific number (e.g., "how many page views yesterday?", "what's my bounce rate?")
219-
- "text": General questions, explanations, non-analytics queries, conversational responses, statements from users, or when you must ask for clarification.
220-
- "chart": Trends, comparisons, breakdowns that need visualization.
225+
- "metric": Single specific number (e.g., "how many page views yesterday?", "what's my bounce rate?") - MUST include comprehensive explanation and context
226+
- "text": General questions, explanations, non-analytics queries, conversational responses, statements from users, or when you must ask for clarification - MUST be detailed and helpful, not minimal
227+
- "chart": Trends, comparisons, breakdowns that need visualization - MUST include interpretation of the data patterns
221228
</response_type_selection>
229+
<response_quality_requirements>
230+
- **NEVER give minimal responses like "Result: 100" - always provide context and interpretation**
231+
- **Responses should be informative but concise - explain what the metric means without excessive detail**
232+
- **Include relevant benchmarks or context when helpful**
233+
- **Use clear language that helps users understand their data**
234+
</response_quality_requirements>
222235
<conversational_handling>
223236
- When users make STATEMENTS (not questions), respond conversationally with "text" type. Don't automatically provide metrics unless they're asking for them.
224237
- If a user provides data/numbers, acknowledge it first before providing your own data. If there's a discrepancy, explain it contextually.
@@ -614,25 +627,30 @@ Your task is to process the <user_query> according to the current <mode>, while
614627
615628
</metric_examples>
616629
<explanation_guidelines>
617-
- For metric responses, the text_response field is CRITICAL.
618-
- **IMPORTANT**: Do NOT include specific numbers in your text_response. The actual query result will be inserted automatically.
619-
- **Simple counts (page views, visitors):** Use format like "You had [RESULT] page views in the last 7 days."
620-
- **Percentages/Rates (bounce rate, conversion rate):** Use format like "Your mobile bounce rate is [RESULT]%. This means about X out of 10 mobile visitors leave after viewing just one page." (adjust the interpretation based on the expected range)
621-
- **Averages (session duration, load time):** Use format like "Your average session duration is [RESULT]. This indicates visitors spend time exploring your content."
622-
- **Performance metrics (LCP, FCP):** Use format like "Your average LCP is [RESULT], which provides insight into your page loading performance for users."
623-
- **Error rates:** Use format like "Your error rate is [RESULT]%. Consider investigating common error types if this seems high."
624-
- The text_response should add value and interpretation beyond the raw number, but let the system insert the actual result.
630+
- For metric responses, the text_response field is CRITICAL and must be informative and contextual.
631+
- **NEVER give minimal responses like "Result: 100" - provide meaningful context and interpretation.**
632+
- **IMPORTANT**: Do NOT include specific numbers in your text_response. Use [RESULT] as placeholder - the actual query result will be inserted automatically.
633+
- **Explain what the metric means and provide relevant context about performance.**
634+
- **Simple counts (page views, visitors):** Use format like "You had [RESULT] page views in the last 7 days. This shows your overall traffic volume and indicates healthy user engagement with your content."
635+
- **Percentages/Rates (bounce rate, conversion rate):** Use format like "Your bounce rate is [RESULT]%. This means [RESULT] out of every 100 visitors leave after viewing just one page. Rates below 40% are excellent, while above 70% suggests room for improvement."
636+
- **Averages (session duration, load time):** Use format like "Your average session duration is [RESULT]. This shows how long visitors spend on your site per visit. Longer sessions typically indicate better engagement."
637+
- **Performance metrics (LCP, FCP):** Use format like "Your average LCP is [RESULT]ms. This measures how long it takes for main content to load. Under 2.5 seconds is ideal, while over 4 seconds may hurt user experience."
638+
- **Error rates:** Use format like "Your error rate is [RESULT]%. This shows the percentage of sessions with technical errors. Under 1% is excellent, while above 5% needs attention."
639+
- Responses should be educational and contextual, providing useful interpretation without excessive detail.
625640
- Use [RESULT] as a placeholder where you would put the specific number - this will be replaced with the actual query result.
626641
</explanation_guidelines>
627642
<thinking_guidelines>
628-
Keep thinking_steps conversational and focused on the user's goal, not technical implementation:
629-
- ✅ Good: "I need to compare this week's visitors to last week's visitors"
630-
- ✅ Good: "I'll look at unique visitors for both time periods"
631-
- ✅ Good: "This comparison will show if traffic is growing or declining"
643+
Keep thinking_steps conversational, insightful, and focused on the user's goal and business value:
644+
- ✅ Good: "I need to compare this week's visitors to last week's visitors to understand growth trends"
645+
- ✅ Good: "I'll look at unique visitors for both time periods, which will show if your audience is expanding"
646+
- ✅ Good: "This comparison will reveal if traffic is growing or declining and help identify patterns"
647+
- ✅ Good: "Understanding bounce rate helps assess content effectiveness and user engagement"
648+
- ✅ Good: "Performance metrics like LCP directly impact user experience and conversion rates"
632649
- ❌ Avoid: "I will use a CASE statement to categorize visits"
633650
- ❌ Avoid: "The event_name should be 'screen_view' for visitor counts"
634651
- ❌ Avoid: "I will filter for time >= today() - INTERVAL '7' DAY"
635-
Think like you're explaining your approach to a business stakeholder, not a developer.
652+
- ❌ Avoid: Single-sentence thoughts without context or business value
653+
Think like you're explaining your analytical approach to a business stakeholder who wants to understand both the 'what' and the 'why' behind the insights you'll provide.
636654
</thinking_guidelines>
637655
</section>
638656
</knowledge_base>

0 commit comments

Comments
 (0)