Commit 051b1b00 authored by Kantz's avatar Kantz
Browse files

umbau des retrivals im vector_store.py der rest fehlt noch

parent e02dd127
...@@ -61,3 +61,7 @@ Retrieval settings: ...@@ -61,3 +61,7 @@ Retrieval settings:
- `neighbor_expand` - `neighbor_expand`
- Backend defaults are in `math-tutor/backend/app/api/retrieval.py` (`QueryRequest`). - Backend defaults are in `math-tutor/backend/app/api/retrieval.py` (`QueryRequest`).
- Core retrieval logic is in `math-tutor/backend/app/services/vector_store.py` (`retrieve`). - Core retrieval logic is in `math-tutor/backend/app/services/vector_store.py` (`retrieve`).
## Testing
python -m test.hint_test ...
pyhton -m test.vector_store_test ...
\ No newline at end of file
# Package marker for services # Package marker for services
from app.deterministic_services.vector_store import Source
__all__ = ["Source"]
\ No newline at end of file
...@@ -10,6 +10,7 @@ from psycopg.rows import dict_row ...@@ -10,6 +10,7 @@ from psycopg.rows import dict_row
from pgvector import Vector from pgvector import Vector
from pgvector.psycopg import register_vector from pgvector.psycopg import register_vector
import yaml import yaml
from enum import Enum
@dataclass @dataclass
...@@ -250,6 +251,36 @@ class Retrieved: ...@@ -250,6 +251,36 @@ class Retrieved:
"metadata": self.metadata, "metadata": self.metadata,
"markdown": self.markdown, "markdown": self.markdown,
} }
@dataclass
class Source:
source_id: SourceID
retrieved_as: str
type: str
score: float
markdown: str
def to_dict(self) -> Dict[str, Any]:
return {
"source_id": self.source_id,
"retrieved_as": self.retrieved_as,
"type": self.type,
"score": self.score,
"markdown": self.markdown,
}
def to_string(self) -> str:
return f"Source(source_id={self.source_id.to_string()},\n retrieved_as={self.retrieved_as},\n type={self.type},\n score={self.score},\n markdown_length={len(self.markdown)})"
@dataclass
class SourceID:
chapter_title: Optional[str]
section_title: Optional[str]
subsection_title: Optional[str]
title: Optional[str]
doc_type: str
def to_string(self) -> str:
return f"[{self.chapter_title}|{self.section_title}|{self.subsection_title}|{self.title}|{self.doc_type}]"
def _row_to_retrieved(row: Dict[str, Any]) -> Retrieved: def _row_to_retrieved(row: Dict[str, Any]) -> Retrieved:
...@@ -275,6 +306,26 @@ def _row_to_retrieved(row: Dict[str, Any]) -> Retrieved: ...@@ -275,6 +306,26 @@ def _row_to_retrieved(row: Dict[str, Any]) -> Retrieved:
) )
def _retrivla_to_sources(retrievd : Dict[str, List[Retrieved]]) -> List[Source]:
sources = []
for name, retrieved_grouep in retrievd.items():
for retrival in retrieved_grouep:
sources.append(Source(
source_id=SourceID(
chapter_title = "none",
section_title=retrival.metadata.get("section_title"),
subsection_title=retrival.metadata.get("subsection_title"),
title=retrival.metadata.get("title"),
doc_type=retrival.doc_type
),
retrieved_as=name,
type=retrival.metadata.get("type"),
score=retrival.score,
markdown=retrival.markdown
))
return sources
def retrieve( def retrieve(
pg_url: str, pg_url: str,
embedder: EmbeddingLike, embedder: EmbeddingLike,
...@@ -285,7 +336,7 @@ def retrieve( ...@@ -285,7 +336,7 @@ def retrieve(
type_filter: Optional[List[str]] = None, type_filter: Optional[List[str]] = None,
expand_links: bool = True, expand_links: bool = True,
neighbor_expand: int = 0, neighbor_expand: int = 0,
) -> Dict[str, Any]: ) -> List[Source]:
qvec = Vector(embed_query(embedder, query)) qvec = Vector(embed_query(embedder, query))
where = ["doc_type = 'child'"] where = ["doc_type = 'child'"]
...@@ -441,16 +492,16 @@ def retrieve( ...@@ -441,16 +492,16 @@ def retrieve(
child_uids = {child.uid for child in children} child_uids = {child.uid for child in children}
neighbors = [neighbor for neighbor in neighbors if neighbor.uid not in child_uids] neighbors = [neighbor for neighbor in neighbors if neighbor.uid not in child_uids]
retrivla_dict = {
return {
"children": children, "children": children,
"children_direct": children_direct, "children_direct": children_direct,
"children_expanded": children_expanded, "children_expanded": children_expanded,
"subsections": subsections, "subsections": subsections,
"sections": sections_docs, "sections": sections_docs,
"neighbors": neighbors, "neighbors": neighbors,
"query": query,
} }
sources = _retrivla_to_sources(retrivla_dict)
return sources
def list_sections(pg_url: str) -> List[Dict[str, Any]]: def list_sections(pg_url: str) -> List[Dict[str, Any]]:
......
import argparse
from app import config
from app.deterministic_services.embeddings import OpenAILikeEmbeddings
from app.deterministic_services import vector_store
def _get_embedder() -> OpenAILikeEmbeddings:
settings = config.get_embedding_settings()
return OpenAILikeEmbeddings(
base_url=settings.base_url,
api_key=settings.api_key,
model=settings.model,
target_dim=settings.target_dim,
)
def _normalize_sources(result: object) -> list[vector_store.Source]:
if isinstance(result, list):
return result
if isinstance(result, dict):
groups = {k: v for k, v in result.items() if isinstance(v, list)}
return vector_store._retrivla_to_sources(groups)
raise TypeError("Unexpected retrieval result type")
def main() -> None:
parser = argparse.ArgumentParser(description="Isolierter Vector-Store Retrieval Test.")
parser.add_argument("--query", required=True, help="Query text")
parser.add_argument("--pg", default=None, help="Postgres URL (oder set POSTGRES_URL)")
parser.add_argument("--k", type=int, default=8)
parser.add_argument("--expand", action="store_true")
parser.add_argument("--section-index", type=int, default=None)
parser.add_argument("--subsection-index", type=int, default=None)
parser.add_argument("--type-filter", nargs="*", default=None)
parser.add_argument("--neighbor-expand", type=int, default=0)
args = parser.parse_args()
pg_url = args.pg or config.get_postgres_url()
embedder = _get_embedder()
result = vector_store.retrieve(
pg_url=pg_url,
embedder=embedder,
query=args.query,
k=args.k,
expand_links=args.expand,
section_index=args.section_index,
subsection_index=args.subsection_index,
type_filter=args.type_filter,
neighbor_expand=args.neighbor_expand,
)
sources = _normalize_sources(result)
if not sources:
print("Keine Quellen gefunden.")
return
print(f"Gefundene Quellen: {len(sources)}")
for source in sources:
print(source.to_string())
if __name__ == "__main__":
main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment