Commit 9b956985525d5185a4f0c93fd2811f641bb25b24
1 parent
6c35aff8
调试工具展示优化
Showing
3 changed files
with
68 additions
and
34 deletions
Show diff stats
config/config.yaml
| ... | ... | @@ -219,8 +219,8 @@ query_config: |
| 219 | 219 | knn_text_k_long: 300 |
| 220 | 220 | knn_text_num_candidates_long: 720 |
| 221 | 221 | |
| 222 | - knn_image_k: 300 | |
| 223 | - knn_image_num_candidates: 720 | |
| 222 | + knn_image_k: 3000 | |
| 223 | + knn_image_num_candidates: 7200 | |
| 224 | 224 | |
| 225 | 225 | # Function Score配置(ES层打分规则) |
| 226 | 226 | function_score: | ... | ... |
frontend/static/css/style.css
| ... | ... | @@ -350,6 +350,25 @@ body { |
| 350 | 350 | flex-shrink: 0; |
| 351 | 351 | } |
| 352 | 352 | |
| 353 | +/* Per-result multilingual debug (title/brief/vendor) under image, price, title */ | |
| 354 | +.product-main-multilingual { | |
| 355 | + margin-top: 8px; | |
| 356 | + font-family: Menlo, Consolas, "Courier New", monospace; | |
| 357 | + font-size: 11px; | |
| 358 | + color: #555; | |
| 359 | + width: 100%; | |
| 360 | +} | |
| 361 | + | |
| 362 | +.product-main-multilingual .debug-details { | |
| 363 | + margin-top: 6px; | |
| 364 | +} | |
| 365 | + | |
| 366 | +.product-main-multilingual .debug-json-pre { | |
| 367 | + max-height: 180px; | |
| 368 | + font-size: 10px; | |
| 369 | + padding: 8px; | |
| 370 | +} | |
| 371 | + | |
| 353 | 372 | .product-debug { |
| 354 | 373 | flex: 1; |
| 355 | 374 | font-family: Menlo, Consolas, "Courier New", monospace; |
| ... | ... | @@ -472,29 +491,34 @@ body { |
| 472 | 491 | font-size: 11px; |
| 473 | 492 | } |
| 474 | 493 | |
| 494 | +/* Stage cards + query context: one key:value per line, no per-field boxes */ | |
| 475 | 495 | .debug-metrics { |
| 476 | - display: grid; | |
| 477 | - grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); | |
| 478 | - gap: 8px; | |
| 496 | + display: flex; | |
| 497 | + flex-direction: column; | |
| 498 | + gap: 1px 0; | |
| 499 | + margin-top: 6px; | |
| 500 | + font-size: 11px; | |
| 501 | + line-height: 1.4; | |
| 479 | 502 | } |
| 480 | 503 | |
| 481 | -.debug-metric { | |
| 482 | - padding: 8px 9px; | |
| 483 | - background: #f7f7f7; | |
| 484 | - border-radius: 6px; | |
| 485 | - border: 1px solid #efefef; | |
| 504 | +.debug-metric-line { | |
| 505 | + display: block; | |
| 506 | + word-break: break-word; | |
| 486 | 507 | } |
| 487 | 508 | |
| 488 | -.debug-metric-label { | |
| 489 | - font-size: 11px; | |
| 490 | - color: #777; | |
| 491 | - margin-bottom: 2px; | |
| 509 | +.debug-metric-k { | |
| 510 | + color: #666; | |
| 511 | + font-weight: 500; | |
| 492 | 512 | } |
| 493 | 513 | |
| 494 | -.debug-metric-value { | |
| 495 | - color: #222; | |
| 514 | +.debug-metric-sep { | |
| 515 | + color: #aaa; | |
| 516 | + margin: 0 3px 0 1px; | |
| 517 | +} | |
| 518 | + | |
| 519 | +.debug-metric-v { | |
| 520 | + color: #111; | |
| 496 | 521 | font-weight: 600; |
| 497 | - word-break: break-word; | |
| 498 | 522 | } |
| 499 | 523 | |
| 500 | 524 | .debug-score-pills { | ... | ... |
frontend/static/js/app.js
| ... | ... | @@ -436,7 +436,7 @@ function displayResults(data) { |
| 436 | 436 | <div class="product-title"> |
| 437 | 437 | ${escapeHtml(title)} |
| 438 | 438 | </div> |
| 439 | - | |
| 439 | + ${debug ? buildMultilingualFieldsHtml(debug) : ''} | |
| 440 | 440 | <div class="product-meta"> |
| 441 | 441 | ${category ? escapeHtml(category) : ''} |
| 442 | 442 | ${vendor ? ' | ' + escapeHtml(vendor) : ''} |
| ... | ... | @@ -458,16 +458,17 @@ function formatDebugNumber(value, digits = 4) { |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | 460 | function renderMetricList(items) { |
| 461 | - const rows = items | |
| 461 | + const lines = items | |
| 462 | 462 | .filter((item) => item && item.value !== undefined && item.value !== null && item.value !== '') |
| 463 | - .map((item) => ` | |
| 464 | - <div class="debug-metric"> | |
| 465 | - <div class="debug-metric-label">${escapeHtml(item.label)}</div> | |
| 466 | - <div class="debug-metric-value">${escapeHtml(String(item.value))}</div> | |
| 463 | + .map( | |
| 464 | + (item) => ` | |
| 465 | + <div class="debug-metric-line"> | |
| 466 | + <span class="debug-metric-k">${escapeHtml(item.label)}</span><span class="debug-metric-sep">:</span><span class="debug-metric-v">${escapeHtml(String(item.value))}</span> | |
| 467 | 467 | </div> |
| 468 | - `) | |
| 468 | + ` | |
| 469 | + ) | |
| 469 | 470 | .join(''); |
| 470 | - return rows ? `<div class="debug-metrics">${rows}</div>` : ''; | |
| 471 | + return lines ? `<div class="debug-metrics">${lines}</div>` : ''; | |
| 471 | 472 | } |
| 472 | 473 | |
| 473 | 474 | function renderScorePills(items) { |
| ... | ... | @@ -495,6 +496,21 @@ function renderJsonDetails(title, payload, open = false) { |
| 495 | 496 | `; |
| 496 | 497 | } |
| 497 | 498 | |
| 499 | +/** Multilingual title/brief/vendor from per-result debug; shown under image/price/title on the left. */ | |
| 500 | +function buildMultilingualFieldsHtml(debug) { | |
| 501 | + if (!debug || typeof debug !== 'object') { | |
| 502 | + return ''; | |
| 503 | + } | |
| 504 | + const titlePayload = {}; | |
| 505 | + if (debug.title_multilingual) titlePayload.title = debug.title_multilingual; | |
| 506 | + if (debug.brief_multilingual) titlePayload.brief = debug.brief_multilingual; | |
| 507 | + if (debug.vendor_multilingual) titlePayload.vendor = debug.vendor_multilingual; | |
| 508 | + if (Object.keys(titlePayload).length === 0) { | |
| 509 | + return ''; | |
| 510 | + } | |
| 511 | + return `<div class="product-main-multilingual">${renderJsonDetails('Multilingual Fields', titlePayload, true)}</div>`; | |
| 512 | +} | |
| 513 | + | |
| 498 | 514 | function buildProductDebugHtml({ debug, result, spuId, tenantId }) { |
| 499 | 515 | const resultJson = customStringify(result); |
| 500 | 516 | const rawUrl = `${API_BASE_URL}/search/es-doc/${encodeURIComponent(spuId)}?tenant_id=${encodeURIComponent(tenantId)}`; |
| ... | ... | @@ -527,7 +543,7 @@ function buildProductDebugHtml({ debug, result, spuId, tenantId }) { |
| 527 | 543 | { label: 'rank', value: esStage.rank ?? debug.initial_rank ?? 'N/A' }, |
| 528 | 544 | { label: 'es_score', value: formatDebugNumber(esStage.score ?? debug.es_score) }, |
| 529 | 545 | { label: 'es_norm', value: formatDebugNumber(esStage.normalized_score ?? debug.es_score_normalized) }, |
| 530 | - ], renderJsonDetails('Matched Queries', esStage.matched_queries ?? debug.matched_queries, false))} | |
| 546 | + ], renderJsonDetails('Matched Queries', esStage.matched_queries ?? debug.matched_queries, true))} | |
| 531 | 547 | ${buildStageCard('Coarse Rank', 'Text + vector fusion', [ |
| 532 | 548 | { label: 'rank', value: coarseStage.rank ?? 'N/A' }, |
| 533 | 549 | { label: 'rank_change', value: coarseStage.rank_change ?? 'N/A' }, |
| ... | ... | @@ -542,7 +558,7 @@ function buildProductDebugHtml({ debug, result, spuId, tenantId }) { |
| 542 | 558 | { label: 'image_knn', value: formatDebugNumber(coarseStage.signals?.image_knn_score ?? debug.image_knn_score) }, |
| 543 | 559 | { label: 'text_factor', value: formatDebugNumber(coarseStage.text_factor ?? debug.coarse_text_factor) }, |
| 544 | 560 | { label: 'knn_factor', value: formatDebugNumber(coarseStage.knn_factor ?? debug.coarse_knn_factor) }, |
| 545 | - ], renderJsonDetails('Coarse Signals', coarseStage.signals, false))} | |
| 561 | + ], renderJsonDetails('Coarse Signals', coarseStage.signals, true))} | |
| 546 | 562 | ${buildStageCard('Fine Rank', 'Lightweight reranker output', [ |
| 547 | 563 | { label: 'rank', value: fineStage.rank ?? 'N/A' }, |
| 548 | 564 | { label: 'rank_change', value: fineStage.rank_change ?? 'N/A' }, |
| ... | ... | @@ -550,7 +566,7 @@ function buildProductDebugHtml({ debug, result, spuId, tenantId }) { |
| 550 | 566 | { label: 'fine_score', value: formatDebugNumber(fineStage.fine_score ?? debug.fine_score) }, |
| 551 | 567 | { label: 'text_score', value: formatDebugNumber(fineStage.text_score ?? debug.text_score) }, |
| 552 | 568 | { label: 'knn_score', value: formatDebugNumber(fineStage.knn_score ?? debug.knn_score) }, |
| 553 | - ], `${renderJsonDetails('Fine Fusion', fineStage.fusion_summary || debug.fusion_summary || fineStage.fusion_factors, false)}${renderJsonDetails('Fine Input', fineStage.rerank_input ?? debug.rerank_input, false)}`)} | |
| 569 | + ], `${renderJsonDetails('Fine Fusion', fineStage.fusion_summary || debug.fusion_summary || fineStage.fusion_factors, true)}${renderJsonDetails('Fine Input', fineStage.rerank_input ?? debug.rerank_input, true)}`)} | |
| 554 | 570 | ${buildStageCard('Final Rerank', 'Heavy reranker + final fusion', [ |
| 555 | 571 | { label: 'rank', value: rerankStage.rank ?? finalPageStage.rank ?? debug.final_rank ?? 'N/A' }, |
| 556 | 572 | { label: 'rank_change', value: rerankStage.rank_change ?? finalPageStage.rank_change ?? 'N/A' }, |
| ... | ... | @@ -568,11 +584,6 @@ function buildProductDebugHtml({ debug, result, spuId, tenantId }) { |
| 568 | 584 | </div> |
| 569 | 585 | `; |
| 570 | 586 | |
| 571 | - const titlePayload = {}; | |
| 572 | - if (debug.title_multilingual) titlePayload.title = debug.title_multilingual; | |
| 573 | - if (debug.brief_multilingual) titlePayload.brief = debug.brief_multilingual; | |
| 574 | - if (debug.vendor_multilingual) titlePayload.vendor = debug.vendor_multilingual; | |
| 575 | - | |
| 576 | 587 | return ` |
| 577 | 588 | <div class="product-debug"> |
| 578 | 589 | <div class="product-debug-title">Ranking Funnel</div> |
| ... | ... | @@ -580,7 +591,6 @@ function buildProductDebugHtml({ debug, result, spuId, tenantId }) { |
| 580 | 591 | ${stageScores} |
| 581 | 592 | ${stageGrid} |
| 582 | 593 | ${renderJsonDetails('Selected SKU', debug.style_intent_sku, true)} |
| 583 | - ${renderJsonDetails('Multilingual Fields', titlePayload, false)} | |
| 584 | 594 | <div class="product-debug-actions"> |
| 585 | 595 | <button type="button" class="product-debug-inline-result-btn" |
| 586 | 596 | data-action="toggle-result-inline-doc" | ... | ... |