Refacto du code coté Python, java et coté angular afin de mieux séparer les responsabilité et d'avoir moins de répétitivité dans le code.
Some checks failed
E2E Tests / e2e (push) Waiting to run
Tests unitaires / Web (Angular · vitest + couverture) (push) Successful in 26s
Build & Push Images / tests (push) Failing after 13s
Build & Push Images / build (brain) (push) Has been skipped
Build & Push Images / build (core) (push) Has been skipped
Build & Push Images / build (web) (push) Has been skipped
Build & Push Images / build-switcher (push) Has been skipped
Tests unitaires / Brain (Python · pytest + couverture) (push) Successful in 1m12s
Tests unitaires / Core (Java · mvn test + JaCoCo) (push) Failing after 1m28s
Some checks failed
E2E Tests / e2e (push) Waiting to run
Tests unitaires / Web (Angular · vitest + couverture) (push) Successful in 26s
Build & Push Images / tests (push) Failing after 13s
Build & Push Images / build (brain) (push) Has been skipped
Build & Push Images / build (core) (push) Has been skipped
Build & Push Images / build (web) (push) Has been skipped
Build & Push Images / build-switcher (push) Has been skipped
Tests unitaires / Brain (Python · pytest + couverture) (push) Successful in 1m12s
Tests unitaires / Core (Java · mvn test + JaCoCo) (push) Failing after 1m28s
Mise en place de tests unitaires coté Python et Angular Mise en place de la couverture de test directement dans le workflow : le programme ne build pas si jamais un test échoue Passage en v0.16.2 en conséquence
This commit is contained in:
60
brain/tests/test_rerank.py
Normal file
60
brain/tests/test_rerank.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""Tests du reranking LLM des passages RAG (app.application.rerank)."""
|
||||
from __future__ import annotations
|
||||
|
||||
from app.application.rerank import pool_size, rerank
|
||||
|
||||
|
||||
class FakeLLM:
|
||||
def __init__(self, response: str | None = None, exc: Exception | None = None) -> None:
|
||||
self.response = response
|
||||
self.exc = exc
|
||||
|
||||
async def generate(self, prompt, *, temperature=None, output_format=None) -> str:
|
||||
if self.exc:
|
||||
raise self.exc
|
||||
return self.response
|
||||
|
||||
|
||||
def test_pool_size():
|
||||
assert pool_size(8) == 24 # min(max(24, 8), 24)
|
||||
assert pool_size(4) == 12 # 4 * 3
|
||||
assert pool_size(10) == 24 # plafonné à POOL_MAX
|
||||
assert pool_size(1) == 3
|
||||
|
||||
|
||||
async def test_rerank_skips_when_pool_not_larger_than_top_k():
|
||||
passages = [{"text": "a"}, {"text": "b"}]
|
||||
# len <= top_k → renvoyé tel quel, sans appel LLM.
|
||||
assert await rerank(FakeLLM(exc=AssertionError("ne doit pas être appelé")),
|
||||
"q", passages, top_k=3) == passages
|
||||
|
||||
|
||||
async def test_rerank_reorders_by_llm_scores():
|
||||
passages = [{"text": "a"}, {"text": "b"}, {"text": "c"}]
|
||||
out = await rerank(FakeLLM(response='{"scores":[1, 9, 5]}'), "q", passages, top_k=2)
|
||||
assert [p["text"] for p in out] == ["b", "c"]
|
||||
|
||||
|
||||
async def test_rerank_stable_on_score_ties():
|
||||
passages = [{"text": "a"}, {"text": "b"}, {"text": "c"}]
|
||||
# Notes égales → ordre cosinus d'origine préservé.
|
||||
out = await rerank(FakeLLM(response='{"scores":[5, 5, 5]}'), "q", passages, top_k=2)
|
||||
assert [p["text"] for p in out] == ["a", "b"]
|
||||
|
||||
|
||||
async def test_rerank_llm_failure_falls_back_to_cosine_order():
|
||||
passages = [{"text": "a"}, {"text": "b"}, {"text": "c"}]
|
||||
out = await rerank(FakeLLM(exc=RuntimeError("LLM HS")), "q", passages, top_k=2)
|
||||
assert [p["text"] for p in out] == ["a", "b"]
|
||||
|
||||
|
||||
async def test_rerank_wrong_score_count_falls_back():
|
||||
passages = [{"text": "a"}, {"text": "b"}, {"text": "c"}]
|
||||
out = await rerank(FakeLLM(response='{"scores":[1, 2]}'), "q", passages, top_k=2)
|
||||
assert [p["text"] for p in out] == ["a", "b"]
|
||||
|
||||
|
||||
async def test_rerank_non_numeric_scores_fall_back():
|
||||
passages = [{"text": "a"}, {"text": "b"}, {"text": "c"}]
|
||||
out = await rerank(FakeLLM(response='{"scores":["x","y","z"]}'), "q", passages, top_k=2)
|
||||
assert [p["text"] for p in out] == ["a", "b"]
|
||||
Reference in New Issue
Block a user