feat: Auto-adjust chunk recall weights based on user feedback#12689
feat: Auto-adjust chunk recall weights based on user feedback#12689MkDev11 wants to merge 31 commits intoinfiniflow:mainfrom
Conversation
When users upvote or downvote responses, the system now automatically adjusts the pagerank_fea field of referenced chunks to improve future retrieval quality. - Add ChunkFeedbackService for weight management - Integrate with thumbup endpoint - Add unit tests - Fix: Handle chunks_format() field transformations (id/dataset_id) Closes infiniflow#12670
|
Appreciations! |
- Disable feature by default (CHUNK_FEEDBACK_ENABLED env var) - Reduce weight increments from 1 to 0.1 to prevent outsized impact - Add test for disabled feature flag - Update docstrings to document the safeguards This addresses concerns about pagerank sensitivity and sparse feedback data.
|
@KevinHuSh Thanks for your feedback! You raise valid concerns about pagerank sensitivity. I've added safeguards to address this:
This way, deployments with sparse feedback won't see unintended side effects, while those with dense user activity can opt in and benefit from the learning signal. Happy to adjust the increment further or add additional safeguards (like requiring N votes before applying, or time-based decay) if you think it's needed. |
|
@ZhenhangTung could you please let your members review the PR? |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #12689 +/- ##
==========================================
- Coverage 96.72% 96.52% -0.21%
==========================================
Files 10 10
Lines 703 690 -13
Branches 112 108 -4
==========================================
- Hits 680 666 -14
- Misses 5 8 +3
+ Partials 18 16 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Thanks, please fix the CI error: |
Avoids CI collection error caused by test/testcases/test_web_api/common.py shadowing the project-level common/ package. Uses the same importlib + stub pattern established by other unit tests in this directory (e.g. test_chunk_routes_unit.py).
|
@KevinHuSh @yingfeng sorry to bother you, can you let me know what I need to fix or update? |
|
This design feels a bit simplistic; we might want to explore a feedback-driven weighting approach instead. |
- Default CHUNK_FEEDBACK_WEIGHTING=relevance: split fixed per-event budget using similarity / vector_similarity / term_similarity from reference chunks - Keep CHUNK_FEEDBACK_WEIGHTING=uniform for legacy per-chunk increments - apply_feedback_to_chunks uses even split when scores are unavailable - Update and extend unit tests
- Apply chunk feedback only when vote direction changes; require bool thumbup - Remove unused extract_chunk_ids / apply_feedback_to_chunks; single-pass row build - Lazy logging; document read-modify-write race on pagerank updates - Tests: feedback rows + thumbup idempotency/boolean matrix
- Require dialog access via UserTenantService + DialogService.query before thumb updates and chunk feedback (align with GET /conversation/get) - Store pagerank changes as integers; split one unit across chunks in relevance mode (largest remainder); skip zero deltas - Delegate get_chunk_kb_mapping to _feedback_rows_from_reference - Update chunk_feedback and conversation route unit tests
rank_feature fields must not be set to 0; align chunk feedback with kb_app by sending remove for elasticsearch/opensearch. Extend single-doc update in es_conn and opensearch_conn to honor remove alongside doc payloads. Tests: stub DOC_ENGINE=infinity by default; add ES/OS remove assertions.
- Enforce conv.user_id vs current user on GET/RM/thumbup when user_id is set - Add adjust_chunk_pagerank_fea for ES/OS (painless) and OB (single UPDATE); ChunkFeedbackService prefers atomic path; Infinity keeps RMW - Remove unused get_chunk_kb_mapping; tests derive mapping from feedback rows - conversation unit tests: mineru_parser stub, quart stub, pathlib upload helper; cover non-owner get/rm/thumbup
- Require owner + tenant/dialog before conversation update (is_new false) - Set req user_id only after checks; align create path - Quart stub: Response callable, headers.add_header, current_app/g/session - Extend set_conversation tests; dedupe chunk_feedback mapping tests
Use asyncio.to_thread with a sync helper for test file writes.
- Update conversation with only name, user_id, and optional message list (no reference/dialog_id passthrough) - Extend quart stub: has_request_context, has_websocket_context, websocket, jsonify - _StubQuartHeaders as dict + add_header; seed Content-Type from mimetype/content_type on Response
- Reset get_by_id and tenant/dialog mocks after conv_foreign rm case so successful delete sees owner conversation. - Support sync generators in _read_sse_text (TTS) alongside async SSE.
|
@yingfeng can you review the changes again? |
- Load real quart and only replace Response with the test stub so quart_auth, api_utils, and connection_utils get full quart API. - Stub deepdoc.parser.paddleocr_parser for rag.llm OCR lazy import chain.
Reuse the tenant_id from the dialog ownership loop; chunk feedback only needs that tenant, not a second dialog fetch.
|
@yingfeng @Magicbook1108 can you help me finish the PR? |
|
Waiting for a PR on the Infinity issue to be resolved. This PR hasn't yet applied the necessary changes to Infinity, which will serve as a built-in retrieval engine going forward. To update a single row in Infinity, the internal |
|
which PR do you mean? |
Skip update_chunk_weight on Infinity backend for now, since safe single-row update requires internal row id support not yet available. Update tests to cover the explicit Infinity skip behavior.
|
What problem does this PR solve?
Implements automatic adjustment of knowledge base chunk recall weights based on user feedback (upvotes/downvotes). When users upvote or downvote a response, the system locates the corresponding knowledge snippets and adjusts their recall weight to improve future retrieval quality.
Closes #12670
How it works:
POST /thumbuppagerank_feavalue from document storeFiles changed:
api/db/services/chunk_feedback_service.py- New service for updating chunk pagerank weightsapi/apps/conversation_app.py- Integrated feedback service into thumbup endpointtest/testcases/test_web_api/test_chunk_feedback/- Unit testsType of change