Signora is a Voice of Customer dataset build pipeline and generated dataset package for customer-feedback retrieval, product-identity cleanup, and RAG evaluation experiments.
Google Drive link: Voice of Customer source folder
Use the Drive folder for source handoff files that should not live directly in git, such as raw archives, source documents, or replacement CSV exports.
Build journal: BUILD_LOG.md
The journal tracks implementation decisions, commands run, retrieval experiments, and observations from testing Signora.
scripts/build_voc_dataset.pybuilds the dataset from the provided source inputs.scripts/build_retrieval_index.pybuilds a local semantic index from feedback atoms.scripts/query_retrieval.pyruns local semantic retrieval with keyword score fusion and metadata filters.scripts/tests/test_dataset_integrity.pyvalidates generated counts, public metadata cleanup, and index-exclusion rules.scripts/tests/test_retrieval_index.pyvalidates generated retrieval index artifacts.dataset/data/public/normalized/feedback_items.jsonlcontains accepted public Reddit feedback records.dataset/data/public/quarantined/feedback_items.jsonlcontains records held out by validation rules.dataset/data/processed/feedback_items.jsonlanddataset/data/processed/feedback_atoms.jsonlcontain the combined retrieval-ready corpus.dataset/reports/contains audit, quality, and final dataset reports.
The public Reddit normalization keeps raw CSV inputs unchanged and fixes product identity in generated artifacts:
- Amazon Echo records are normalized under
Amazon Echo / Alexawithproduct_familyandproduct_model. - Sony WH-1000X records are separated into XM4, XM5, XM6, and series-level identities.
- Reddit thread fields include
thread_id,root_post_id,parent_id, andis_root_postwhere they can be derived conservatively. - Wyze records with generic subreddit URLs keep unknown thread relationships as
null.
From the repository root:
python scripts\build_voc_dataset.pyThe build writes regenerated dataset artifacts, reports, manifests, and reference files under dataset/.
python scripts\tests\test_dataset_integrity.pyExpected result:
dataset integrity checks passed
Install the retrieval dependencies with Python 3.12:
py -3.12 -m pip install -r requirements.txtBuild the production embedding index. The default profile is openai_small,
which uses text-embedding-3-small because it was the practical winner in the
benchmark: it led the core retrieval metrics while being cheaper than
text-embedding-3-large.
py -3.12 scripts\build_retrieval_index.pyFor a fully local/offline baseline, build with MPNet instead:
py -3.12 scripts\build_retrieval_index.py --profile mpnetThe generated semantic index is written to dataset/index/. It is intentionally ignored by git because it is rebuildable and model-dependent.
Run a retrieval query:
py -3.12 scripts\query_retrieval.py "Why are enterprise administrators struggling with onboarding?" --top-k 5Optional filters:
py -3.12 scripts\query_retrieval.py "Which customers complain about delayed notifications?" --product-area notifications --top-k 5The query pipeline uses the same model recorded in the index manifest and fuses
dense semantic similarity with keyword overlap. The benchmark showed keyword
fusion improved retrieval ranking for both local models, so the production
default keeps fusion enabled with --semantic-weight 0.75.
Use the v2 benchmark whenever the corpus, document recipe, embedding model, filters, or ranking logic changes:
py -3.12 scripts\benchmark\run_reproducible_eval.py --models openai_small mpnetThat command rebuilds model-specific indexes, evaluates dense retrieval and the
production-like keyword-fusion pipeline, scores abstention, and regenerates the
benchmark report under dataset/benchmark_results/.
Current interpretation from the completed experiment:
text-embedding-3-smallis the production default for this benchmark.all-mpnet-base-v2is the strongest local baseline.- Keyword fusion improved retrieval ranking for both local models.
- MPNet dense retrieval produced the strongest held-out local abstention result.
The lower-level benchmark runner uses 59 predicate-backed retrieval questions and 20 no-answer cases. It reports exact canonical citation recall separately from predicate-backed evidence coverage so broad semantic retrieval questions are not graded only against one small set of pre-selected atom IDs:
py -3.12 scripts\evaluation\run_benchmark.pyBuild one isolated index per model first, for example py -3.12 scripts\embeddings\embed_minilm.py; indexes live under
dataset/index/<model-slug>/ and are intentionally ignored by git.
- Do error analysis on the weak queries for
text-embedding-3-small. - Decide whether parent-thread context should be retrieved automatically for Reddit comments.
- Add answer generation on top of retrieved evidence, with citations back to atom IDs and source feedback IDs.
- The generated CloudDesk corpus is synthetic.
- Public Reddit CSV samples are user-provided source material and should be reviewed before publication.
- Evaluation answer keys and hidden patterns are excluded from the normal vector-index include manifest.