feat: Ran manual chat evaluation against live endpoint, documented qual…
- ".gsd/milestones/M025/slices/S09/S09-QUALITY-REPORT.md" - "backend/pipeline/quality/results/chat_eval_baseline.json" GSD-Task: S09/T03
This commit is contained in:
parent
3cbb614654
commit
4854dad086
5 changed files with 364 additions and 1 deletions
|
|
@ -41,7 +41,7 @@ Steps:
|
|||
- Estimate: 1h
|
||||
- Files: backend/chat_service.py, backend/tests/test_chat.py
|
||||
- Verify: cd backend && python -m pytest tests/test_chat.py -v
|
||||
- [ ] **T03: Run chat evaluation, assess personality fidelity, write quality report** — Execute the chat evaluation harness against the live Chrysopedia chat endpoint on ub01, assess personality fidelity across weight levels for multiple creators, and write a quality report documenting all findings.
|
||||
- [x] **T03: Ran manual chat evaluation against live endpoint, documented quality baseline with critical findings on creator scoping and missing personality profiles** — Execute the chat evaluation harness against the live Chrysopedia chat endpoint on ub01, assess personality fidelity across weight levels for multiple creators, and write a quality report documenting all findings.
|
||||
|
||||
This task requires the live stack running on ub01 (API at http://ub01:8096). If the endpoint is unreachable, use manual curl-based evaluation with representative queries and score responses by inspection.
|
||||
|
||||
|
|
|
|||
169
.gsd/milestones/M025/slices/S09/S09-QUALITY-REPORT.md
Normal file
169
.gsd/milestones/M025/slices/S09/S09-QUALITY-REPORT.md
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# S09 Chat Quality Report
|
||||
|
||||
**Date:** 2026-04-04
|
||||
**Evaluation method:** Manual curl-based (LLM upstream `chat.forgetyour.name` returning 502 — automated eval harness could not complete LLM scoring)
|
||||
**Endpoint:** http://ub01:8096/api/v1/chat
|
||||
**API health:** ✅ Connected, search pipeline functional
|
||||
|
||||
---
|
||||
|
||||
## 1. Evaluation Summary
|
||||
|
||||
The chat endpoint is operational for source retrieval (search + Qdrant semantic pipeline) but LLM generation was unavailable during evaluation due to the upstream OpenAI-compatible proxy returning 502 Bad Gateway. This limits scoring to source quality, prompt architecture review, and personality fidelity mechanism assessment.
|
||||
|
||||
**What was testable:**
|
||||
- Source retrieval quality and relevance (10 sources per query)
|
||||
- Cross-creator source diversity
|
||||
- Creator-scoped search behavior
|
||||
- Personality weight parameter acceptance and routing
|
||||
- Prompt template quality (code review + unit test coverage)
|
||||
- Personality injection architecture (5-tier progressive system)
|
||||
|
||||
**What was NOT testable:**
|
||||
- Actual LLM response quality (citation accuracy, response structure, domain expertise, source grounding)
|
||||
- Personality fidelity in generated text (requires LLM completions)
|
||||
- End-to-end composite scoring via the chat_eval harness
|
||||
|
||||
---
|
||||
|
||||
## 2. Prompt Changes (Before → After)
|
||||
|
||||
### Before (4 lines, flat)
|
||||
```
|
||||
You are Chrysopedia, an expert encyclopedic assistant for music production techniques.
|
||||
Answer the user's question using ONLY the numbered sources below. Cite sources by
|
||||
writing [N] inline (e.g. [1], [2]) where N is the source number. If the sources
|
||||
do not contain enough information, say so honestly — do not invent facts.
|
||||
```
|
||||
|
||||
### After (structured, 18 lines with headers)
|
||||
```
|
||||
You are Chrysopedia, an expert assistant for music production techniques —
|
||||
synthesis, sound design, mixing, sampling, and audio processing.
|
||||
|
||||
## Rules
|
||||
- Use ONLY the numbered sources below. Do not invent facts.
|
||||
- Cite every factual claim inline with [N] immediately after the claim
|
||||
(e.g. "Parallel compression adds sustain [2] while preserving transients [1].").
|
||||
- When sources disagree, present both perspectives with their citations.
|
||||
- If the sources lack enough information, say so honestly.
|
||||
|
||||
## Response format
|
||||
- Aim for 2–4 short paragraphs. Expand only when the question warrants detail.
|
||||
- Use bullet lists for steps, signal chains, or parameter lists.
|
||||
- **Bold** key terms on first mention.
|
||||
- Use audio/synthesis/mixing terminology naturally — do not over-explain
|
||||
standard concepts (e.g. LFO, sidechain, wet/dry) unless the user asks.
|
||||
```
|
||||
|
||||
### Changes Summary
|
||||
| Dimension | Before | After |
|
||||
|-----------|--------|-------|
|
||||
| Citation guidance | Generic `[N]` instruction | Specific inline citation examples with multi-source sentence |
|
||||
| Response structure | None | 2–4 paragraphs, bullet lists for steps, bold key terms |
|
||||
| Domain awareness | "expert encyclopedic" | Explicit music production subdomain list + terminology guidance |
|
||||
| Conflicting sources | Not addressed | Explicit "present both perspectives" instruction |
|
||||
| Response length | Not addressed | "2–4 short paragraphs" with expand-when-warranted clause |
|
||||
| Line count | 4 | 18 (well under 30-line budget) |
|
||||
|
||||
All 26 existing tests passed without modification after the rewrite — the tests assert behavioral properties (SSE format, citation numbering, personality injection mechanics) rather than exact prompt text.
|
||||
|
||||
---
|
||||
|
||||
## 3. Source Retrieval Quality
|
||||
|
||||
### Technical queries
|
||||
| Query | Sources | Creators represented | Assessment |
|
||||
|-------|---------|---------------------|------------|
|
||||
| "How do I set up sidechain compression?" | 10 | Break(3), Caracal Project(2), Chee(2), KOAN Sound(1) | ✅ Highly relevant, multi-creator |
|
||||
| "What are different approaches to layering synth sounds?" | 10 | Chee(5), COPYCATT(2), Caracal Project(1), Current Value(1), Emperor(1) | ⚠️ Skewed toward Chee — 5/10 sources |
|
||||
|
||||
### Creator-scoped queries
|
||||
| Query | Creator | Sources from creator | Assessment |
|
||||
|-------|---------|---------------------|------------|
|
||||
| "How does this creator approach sound design for bass?" | Keota | 0/10 from Keota | ❌ Creator scoping not filtering — returned COPYCATT, Break, Chee |
|
||||
| "What mixing techniques does this creator recommend for width?" | Mr. Bill | 0/10 from Mr. Bill | ❌ Same issue — no Mr. Bill sources |
|
||||
|
||||
**Finding:** Creator-scoped chat queries use the cascade search mechanism (creator tier → domain tier → global tier), but the ll_keywords approach does not strictly filter to the requested creator. Post-filtering or direct creator ID filtering in the semantic search would improve this.
|
||||
|
||||
---
|
||||
|
||||
## 4. Personality Fidelity Assessment
|
||||
|
||||
### Architecture Review
|
||||
|
||||
The personality injection system uses a 5-tier progressive weight mechanism in `_build_personality_block()`:
|
||||
|
||||
| Weight Range | Tier | What's Injected |
|
||||
|-------------|------|-----------------|
|
||||
| < 0.2 | None | No personality block |
|
||||
| 0.2–0.39 | Basic tone | teaching_style, formality, energy + subtle hint |
|
||||
| 0.4–0.59 | Voice adoption | + descriptors, explanation_approach, analogies, engagement |
|
||||
| 0.6–0.79 | Creator voice | + signature_phrases (count scaled by weight) |
|
||||
| 0.8–0.89 | Full embodiment | + distinctive_terms, sound_descriptions, sound_words, self_references, pacing |
|
||||
| ≥ 0.9 | Complete persona | + full summary paragraph |
|
||||
|
||||
Temperature also scales: 0.3 (encyclopedic) → 0.5 (full personality).
|
||||
|
||||
### Critical Finding: No Personality Profiles Exist
|
||||
|
||||
**All 25 creators in the database have `personality_profile IS NULL`.** This means:
|
||||
|
||||
- Any `personality_weight > 0` silently falls back to encyclopedic mode (the `_inject_personality` method returns the unmodified prompt when profile is null)
|
||||
- The 5-tier progressive system is architecturally sound but has zero data to operate on
|
||||
- The test suite validates the mechanism works correctly with mock profiles (26 tests pass), but no real personality fidelity assessment is possible against the live system
|
||||
|
||||
### Personality Fidelity Test Matrix (Weight Levels)
|
||||
|
||||
| Creator | Weight 0.0 | Weight 0.5 | Weight 0.8 | Weight 1.0 |
|
||||
|---------|-----------|-----------|-----------|-----------|
|
||||
| Keota | Encyclopedic (no profile) | Falls back to encyclopedic | Falls back to encyclopedic | Falls back to encyclopedic |
|
||||
| Mr. Bill | Encyclopedic (no profile) | Falls back to encyclopedic | Falls back to encyclopedic | Falls back to encyclopedic |
|
||||
|
||||
**Result:** Progressive personality injection cannot be assessed until personality profiles are populated. The mechanism is tested and correct (unit tests), but produces no visible differentiation on the live system.
|
||||
|
||||
---
|
||||
|
||||
## 5. Test Coverage
|
||||
|
||||
| Test file | Tests | Status |
|
||||
|-----------|-------|--------|
|
||||
| `backend/tests/test_chat.py` | 26 | ✅ All pass (1.22s) |
|
||||
|
||||
Test categories covered:
|
||||
- SSE format and event ordering (sources → token → done)
|
||||
- Citation numbering in context block
|
||||
- Creator parameter forwarding to search
|
||||
- Input validation (empty query, missing query → 422)
|
||||
- LLM error produces error SSE event
|
||||
- Conversation memory (Redis save/load, cap at 10 pairs, TTL refresh)
|
||||
- Personality weight acceptance, prompt injection, tier interpolation
|
||||
- Personality fallbacks (null profile, missing creator, weight=0 skips)
|
||||
- Temperature scaling with personality weight
|
||||
- Weight validation (>1 → 422, <0 → 422, string → 422)
|
||||
- Connection error and 500 error fallback behavior
|
||||
|
||||
---
|
||||
|
||||
## 6. Recommendations
|
||||
|
||||
### Immediate (next milestone)
|
||||
1. **Populate personality profiles** — Run the personality extraction pipeline for all 25 creators. Without this data, the personality fidelity feature is architecturally complete but functionally inert.
|
||||
2. **Fix creator-scoped search** — Creator-scoped chat queries should return sources predominantly from the requested creator. Either tighten the cascade's creator tier (hard filter on creator_id) or add a minimum-creator-source threshold.
|
||||
|
||||
### When LLM proxy is restored
|
||||
3. **Run automated evaluation** — Execute `python -m pipeline.quality chat_eval --base-url http://localhost:8000` inside the API container to generate baseline composite scores across all 5 dimensions.
|
||||
4. **A/B test prompt versions** — Save the old 4-line prompt, run eval with both, compare citation_accuracy and response_structure dimensions.
|
||||
|
||||
### Future improvements
|
||||
5. **Response length tracking** — Add token/word count to chat usage logs for empirical length distribution analysis.
|
||||
6. **Citation hit rate** — Track what fraction of provided sources actually get cited in responses (requires post-processing of LLM output against source numbers).
|
||||
7. **Creator source precision** — For creator-scoped queries, measure precision (fraction of returned sources belonging to the target creator) as a search quality metric.
|
||||
|
||||
---
|
||||
|
||||
## 7. Raw Evaluation Data
|
||||
|
||||
Manual evaluation results saved to: `backend/pipeline/quality/results/chat_eval_baseline.json`
|
||||
|
||||
The JSON contains source retrieval assessments for each test query since LLM scoring was not possible. When the LLM proxy is restored, re-run the automated eval to generate full 5-dimension scores.
|
||||
24
.gsd/milestones/M025/slices/S09/tasks/T02-VERIFY.json
Normal file
24
.gsd/milestones/M025/slices/S09/tasks/T02-VERIFY.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"taskId": "T02",
|
||||
"unitId": "M025/S09/T02",
|
||||
"timestamp": 1775313909993,
|
||||
"passed": false,
|
||||
"discoverySource": "task-plan",
|
||||
"checks": [
|
||||
{
|
||||
"command": "cd backend",
|
||||
"exitCode": 0,
|
||||
"durationMs": 14,
|
||||
"verdict": "pass"
|
||||
},
|
||||
{
|
||||
"command": "python -m pytest tests/test_chat.py -v",
|
||||
"exitCode": 4,
|
||||
"durationMs": 239,
|
||||
"verdict": "fail"
|
||||
}
|
||||
],
|
||||
"retryAttempt": 1,
|
||||
"maxRetries": 2
|
||||
}
|
||||
79
.gsd/milestones/M025/slices/S09/tasks/T03-SUMMARY.md
Normal file
79
.gsd/milestones/M025/slices/S09/tasks/T03-SUMMARY.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
---
|
||||
id: T03
|
||||
parent: S09
|
||||
milestone: M025
|
||||
provides: []
|
||||
requires: []
|
||||
affects: []
|
||||
key_files: [".gsd/milestones/M025/slices/S09/S09-QUALITY-REPORT.md", "backend/pipeline/quality/results/chat_eval_baseline.json"]
|
||||
key_decisions: ["Used manual curl-based evaluation as fallback when upstream LLM proxy returned 502", "Documented personality fidelity as architecturally complete but functionally inert"]
|
||||
patterns_established: []
|
||||
drill_down_paths: []
|
||||
observability_surfaces: []
|
||||
duration: ""
|
||||
verification_result: "Quality report exists at 169 lines (threshold 30). Baseline JSON exists. All 26 chat tests pass in 1.13s."
|
||||
completed_at: 2026-04-04T14:50:39.841Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
# T03: Ran manual chat evaluation against live endpoint, documented quality baseline with critical findings on creator scoping and missing personality profiles
|
||||
|
||||
> Ran manual chat evaluation against live endpoint, documented quality baseline with critical findings on creator scoping and missing personality profiles
|
||||
|
||||
## What Happened
|
||||
---
|
||||
id: T03
|
||||
parent: S09
|
||||
milestone: M025
|
||||
key_files:
|
||||
- .gsd/milestones/M025/slices/S09/S09-QUALITY-REPORT.md
|
||||
- backend/pipeline/quality/results/chat_eval_baseline.json
|
||||
key_decisions:
|
||||
- Used manual curl-based evaluation as fallback when upstream LLM proxy returned 502
|
||||
- Documented personality fidelity as architecturally complete but functionally inert
|
||||
duration: ""
|
||||
verification_result: passed
|
||||
completed_at: 2026-04-04T14:50:39.841Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
# T03: Ran manual chat evaluation against live endpoint, documented quality baseline with critical findings on creator scoping and missing personality profiles
|
||||
|
||||
**Ran manual chat evaluation against live endpoint, documented quality baseline with critical findings on creator scoping and missing personality profiles**
|
||||
|
||||
## What Happened
|
||||
|
||||
Attempted automated chat_eval harness against ub01:8096 — API healthy, search pipeline functional, but upstream LLM proxy returning 502. Fell back to manual curl evaluation of 6 queries across 4 categories. Found: general source retrieval works well (10 relevant sources, multi-creator diversity), creator-scoped search fails (zero sources from target creator for Keota and Mr. Bill), all 25 creators lack personality_profile data (5-tier injection system architecturally sound but inert), prompt improvements from T02 validated by 26 passing tests. Wrote 169-line quality report and baseline JSON.
|
||||
|
||||
## Verification
|
||||
|
||||
Quality report exists at 169 lines (threshold 30). Baseline JSON exists. All 26 chat tests pass in 1.13s.
|
||||
|
||||
## Verification Evidence
|
||||
|
||||
| # | Command | Exit Code | Verdict | Duration |
|
||||
|---|---------|-----------|---------|----------|
|
||||
| 1 | `test -f .gsd/milestones/M025/slices/S09/S09-QUALITY-REPORT.md && wc -l | awk '{exit ($1 < 30)}'` | 0 | ✅ pass | 100ms |
|
||||
| 2 | `test -f backend/pipeline/quality/results/chat_eval_baseline.json` | 0 | ✅ pass | 50ms |
|
||||
| 3 | `cd backend && python -m pytest tests/test_chat.py -v` | 0 | ✅ pass | 1130ms |
|
||||
|
||||
|
||||
## Deviations
|
||||
|
||||
Used manual curl evaluation instead of automated harness (planned fallback). Chat endpoint at /api/v1/chat not /api/chat.
|
||||
|
||||
## Known Issues
|
||||
|
||||
LLM proxy 502 prevents automated scoring. Creator-scoped search returns zero target-creator sources. No personality profiles populated.
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `.gsd/milestones/M025/slices/S09/S09-QUALITY-REPORT.md`
|
||||
- `backend/pipeline/quality/results/chat_eval_baseline.json`
|
||||
|
||||
|
||||
## Deviations
|
||||
Used manual curl evaluation instead of automated harness (planned fallback). Chat endpoint at /api/v1/chat not /api/chat.
|
||||
|
||||
## Known Issues
|
||||
LLM proxy 502 prevents automated scoring. Creator-scoped search returns zero target-creator sources. No personality profiles populated.
|
||||
91
backend/pipeline/quality/results/chat_eval_baseline.json
Normal file
91
backend/pipeline/quality/results/chat_eval_baseline.json
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"timestamp": "20260404_043200",
|
||||
"evaluation_method": "manual_curl",
|
||||
"llm_status": "unavailable (upstream 502 Bad Gateway at chat.forgetyour.name)",
|
||||
"api_health": "ok",
|
||||
"total_queries": 6,
|
||||
"scored_queries": 0,
|
||||
"errors_llm": 6,
|
||||
"note": "LLM completions unavailable — only source retrieval quality assessed. Re-run with automated eval when LLM proxy is restored.",
|
||||
"source_retrieval_results": [
|
||||
{
|
||||
"query": "How do I set up sidechain compression on a bass synth using a kick drum as the trigger?",
|
||||
"creator": null,
|
||||
"personality_weight": 0.0,
|
||||
"category": "technical",
|
||||
"source_count": 10,
|
||||
"unique_creators": ["Break", "Caracal Project, The", "Chee", "KOAN Sound"],
|
||||
"creator_distribution": {"Break": 3, "Caracal Project, The": 2, "Chee": 2, "KOAN Sound": 1},
|
||||
"relevance_assessment": "highly_relevant",
|
||||
"notes": "All 10 sources directly about sidechain compression. Good creator diversity."
|
||||
},
|
||||
{
|
||||
"query": "What are the different approaches to layering synth sounds across creators?",
|
||||
"creator": null,
|
||||
"personality_weight": 0.0,
|
||||
"category": "cross_creator",
|
||||
"source_count": 10,
|
||||
"unique_creators": ["Chee", "COPYCATT", "Caracal Project, The", "Current Value", "Emperor"],
|
||||
"creator_distribution": {"Chee": 5, "COPYCATT": 2, "Caracal Project, The": 1, "Current Value": 1, "Emperor": 1},
|
||||
"relevance_assessment": "relevant_but_skewed",
|
||||
"notes": "50% of sources from Chee — cross-creator diversity could be improved."
|
||||
},
|
||||
{
|
||||
"query": "How does this creator approach sound design for bass sounds?",
|
||||
"creator": "Keota",
|
||||
"personality_weight": 0.0,
|
||||
"category": "creator_encyclopedic",
|
||||
"source_count": 10,
|
||||
"unique_creators": ["COPYCATT", "Break", "Chee", "Caracal Project, The"],
|
||||
"creator_distribution": {"COPYCATT": 2, "Break": 2, "Chee": 3, "Caracal Project, The": 3},
|
||||
"relevance_assessment": "creator_scope_failure",
|
||||
"notes": "Zero sources from Keota despite creator-scoped query. Cascade fell through to global tier."
|
||||
},
|
||||
{
|
||||
"query": "What mixing techniques does this creator recommend for achieving width in a mix?",
|
||||
"creator": "Mr. Bill",
|
||||
"personality_weight": 0.0,
|
||||
"category": "creator_encyclopedic",
|
||||
"source_count": 10,
|
||||
"unique_creators": ["Break", "Frequent", "Caracal Project, The", "COPYCATT", "Chee"],
|
||||
"creator_distribution": {"Break": 2, "Frequent": 1, "Caracal Project, The": 2, "COPYCATT": 2, "Chee": 3},
|
||||
"relevance_assessment": "creator_scope_failure",
|
||||
"notes": "Zero sources from Mr. Bill despite creator-scoped query."
|
||||
},
|
||||
{
|
||||
"query": "How does this creator approach sound design for bass sounds? (personality)",
|
||||
"creator": "Keota",
|
||||
"personality_weight": 0.7,
|
||||
"category": "creator_personality",
|
||||
"source_count": 10,
|
||||
"personality_profile_exists": false,
|
||||
"notes": "Personality weight=0.7 accepted but no profile data exists — falls back to encyclopedic mode silently."
|
||||
},
|
||||
{
|
||||
"query": "What mixing techniques does this creator recommend for width? (personality)",
|
||||
"creator": "Mr. Bill",
|
||||
"personality_weight": 0.7,
|
||||
"category": "creator_personality",
|
||||
"source_count": 10,
|
||||
"personality_profile_exists": false,
|
||||
"notes": "Personality weight=0.7 accepted but no profile data exists — falls back to encyclopedic mode silently."
|
||||
}
|
||||
],
|
||||
"personality_profiles_status": {
|
||||
"total_creators": 25,
|
||||
"creators_with_profile": 0,
|
||||
"assessment": "No personality profiles populated. The 5-tier progressive injection system is architecturally complete (26 unit tests pass) but functionally inert on the live system."
|
||||
},
|
||||
"prompt_changes": {
|
||||
"before_lines": 4,
|
||||
"after_lines": 18,
|
||||
"changes": [
|
||||
"Added structured citation guidance with inline example",
|
||||
"Added response format section (2-4 paragraphs, bullet lists, bold terms)",
|
||||
"Added domain awareness (music production subdomain list)",
|
||||
"Added conflicting source handling instruction",
|
||||
"Added response length guidance"
|
||||
],
|
||||
"test_impact": "Zero test modifications needed — all 26 tests pass unchanged"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue