Polish grounded assistant output
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-16 03:54:25 +02:00
parent 1e23d30eaf
commit d0210b9a3c
4 changed files with 56 additions and 0 deletions
@@ -132,6 +132,26 @@ class GeoAssistantService:
f"{answer}"
)
@staticmethod
def rounded_context_value(value: float, unit: str) -> int | float:
normalized_unit = unit.casefold().strip()
if normalized_unit in {"inwoners", "personen", "objecten", "features"}:
return int(round(value))
if "%" in normalized_unit or "ha" in normalized_unit or "km" in normalized_unit or normalized_unit == "m":
return round(value, 2)
if "score" in normalized_unit:
return round(value, 4)
return round(value, 2)
@staticmethod
def normalize_plain_text(answer: str) -> str:
lines: list[str] = []
for line in answer.splitlines():
normalized = re.sub(r"^\s*\*\s+", "- ", line.strip())
normalized = normalized.replace("**", "").replace("__", "").replace("`", "")
lines.append(normalized)
return "\n".join(lines).strip()
def __init__(self, settings: Settings | None = None):
self.settings = settings or get_settings()
@@ -386,6 +406,7 @@ class GeoAssistantService:
)
context_metrics.append(item)
serialized_metrics.append(item.model_dump(mode="json"))
serialized_metrics[-1]["value"] = self.rounded_context_value(item.value, item.unit)
serialized_metrics[-1]["measurement_quality"] = (
"schatting" if item.is_estimate else "exact_binnen_bronrepresentatie"
)
@@ -428,6 +449,7 @@ class GeoAssistantService:
)
context_metrics.append(item)
serialized_metrics.append(item.model_dump(mode="json"))
serialized_metrics[-1]["value"] = self.rounded_context_value(item.value, item.unit)
serialized_metrics[-1]["measurement_quality"] = "resolutiegebonden_bronmeting"
source_dataset_ids.append(dataset.id)
current_context.append(
@@ -473,6 +495,7 @@ class GeoAssistantService:
)
context_metrics.append(item)
serialized_metrics.append(item.model_dump(mode="json"))
serialized_metrics[-1]["value"] = self.rounded_context_value(item.value, item.unit)
serialized_metrics[-1]["measurement_quality"] = "exacte_berekening_binnen_gemodelleerd_scenario"
source_dataset_ids.append(dataset.id)
current_context.append(
@@ -584,6 +607,8 @@ class GeoAssistantService:
"scope.label is het exact geanalyseerde gebied; vervang dit nooit door project.name of project.region. "
"Noem bij cijfers de bron en eenheid. Maak duidelijk onderscheid tussen exacte metingen en schattingen. "
"Als is_estimate true is, noem de waarde verplicht een schatting en nooit exact. "
"Een officiële bron maakt een afgeleide gebiedswaarde niet exact; noem een schatting nooit officieel geteld. "
"De numerieke contextwaarden zijn al bronveilig afgerond; neem die afgeronde waarden letterlijk over. "
"Objectaantallen zijn ondersteunend; geef betekenisvolle oppervlakte-, lengte- of bevolkingsmetriek voorrang. "
"Wanneer de gebruiker meerdere thema's opsomt, behandel elk gevraagd thema en voeg geen ongevraagd thema toe. "
"Houd het antwoord beknopt: groepeer de kernmetrieken per gevraagd thema en herhaal geen beperkingen. "
@@ -627,6 +652,7 @@ class GeoAssistantService:
answer = str(message.get("content") or "").strip()
if not answer:
raise AppError(code="OLLAMA_EMPTY_RESPONSE", message="Ollama gaf geen antwoord terug.", status_code=502)
answer = self.normalize_plain_text(answer)
answer = self.ensure_estimate_disclosure(answer, metrics)
return AssistantQueryResponse(
answer=answer,