mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
feat(r5.2): assistant au contrat + suggestion de codes de bilan
apps/ai : /internal/ask — seuil de pertinence, extraits sourcés ou refus honnête portant la taille du corpus cherché (D2), rédaction via le Generateur opt-in ; /internal/suggest — similarité sémantique entre la description libre et les libellés ACTIFS des référentiels, un code par champ, confiance FORTE/MOYENNE, « N bilans similaires sur ce parc ». Sans LLM : déterministe, explicable. 23 pytest. Contrat (74 opérations) : POST /assistant/ask → AssistantAnswer (EXTRACTIVE/GENERATED/REFUSAL, extraits cités, corpus cherché) et POST /assistant/suggest-bilan (codes existants seulement) ; clients web/mobile régénérés. API NestJS : module assistant — proxy vers siop2-ai (AI_SERVICE_URL/ AI_SERVICE_TOKEN, ADR-004 §4), permissions matrice (ask=view, suggest=edit), traduction interne→contrat, 503 propre si service éteint. 6 e2e sur stub HTTP (76 tests API). Bug débusqué par la vraie chaîne : fastembed ne norme pas ses vecteurs — la similarité des suggestions dépassait 1 (pgvector normalisait dans son opérateur, masquant l'écart). Normalisation à l'encodage + réindexation : bilans en tête (0.41), refus hors corpus, scores cosinus ≤ 1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1165,6 +1165,84 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/assistant/ask": {
|
||||
"post": {
|
||||
"operationId": "askAssistant",
|
||||
"summary": "Assistant R5 — sourcé ou silencieux : extraits cités ou refus honnête (D2)",
|
||||
"tags": [
|
||||
"assistant"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssistantAsk"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Réponse sourcée ou refus",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssistantAnswer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Service IA indisponible"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/assistant/suggest-bilan": {
|
||||
"post": {
|
||||
"operationId": "suggestBilan",
|
||||
"summary": "Suggérer des codes de bilan depuis une description libre (D1 — l’humain valide)",
|
||||
"tags": [
|
||||
"assistant"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/SuggestBilan"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Suggestions (codes existants seulement)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BilanSuggestions"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Service IA indisponible"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/search": {
|
||||
"get": {
|
||||
"operationId": "globalSearch",
|
||||
@@ -4975,6 +5053,209 @@
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"AssistantAnswer": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"EXTRACTIVE",
|
||||
"GENERATED",
|
||||
"REFUSAL"
|
||||
]
|
||||
},
|
||||
"answer": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"excerpts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sourceType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DOCUMENT",
|
||||
"WORK_ORDER"
|
||||
]
|
||||
},
|
||||
"documentId": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"workOrderId": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"locator": {
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"type": "string"
|
||||
},
|
||||
"score": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"sourceType",
|
||||
"documentId",
|
||||
"workOrderId",
|
||||
"title",
|
||||
"locator",
|
||||
"content",
|
||||
"score"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"corpus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"documents": {
|
||||
"type": "integer",
|
||||
"minimum": -9007199254740991,
|
||||
"maximum": 9007199254740991
|
||||
},
|
||||
"reports": {
|
||||
"type": "integer",
|
||||
"minimum": -9007199254740991,
|
||||
"maximum": 9007199254740991
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents",
|
||||
"reports"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mode",
|
||||
"answer",
|
||||
"excerpts",
|
||||
"corpus"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"AssistantAsk": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"question": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 500
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"question"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"BilanSuggestions": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"suggestions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"field": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DOOR_STATE",
|
||||
"CABIN_POSITION",
|
||||
"ANOMALY",
|
||||
"EXTERNAL_CAUSE",
|
||||
"ACTION_TAKEN",
|
||||
"COMPONENT_CONCERNED"
|
||||
]
|
||||
},
|
||||
"valueId": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"confidence": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"HIGH",
|
||||
"MEDIUM"
|
||||
]
|
||||
},
|
||||
"similarReports": {
|
||||
"type": "integer",
|
||||
"minimum": -9007199254740991,
|
||||
"maximum": 9007199254740991
|
||||
},
|
||||
"score": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"field",
|
||||
"valueId",
|
||||
"label",
|
||||
"confidence",
|
||||
"similarReports",
|
||||
"score"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"suggestions"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SuggestBilan": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"minLength": 10,
|
||||
"maxLength": 2000
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"description"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SearchResponse": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
|
||||
Reference in New Issue
Block a user