-
Notifications
You must be signed in to change notification settings - Fork 0
feat: llm integration #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/2.50.0
Are you sure you want to change the base?
feat: llm integration #29
Conversation
| @@ -1,5 +1,5 @@ | |||
| # | |||
| # This file is autogenerated by pip-compile with Python 3.13 | |||
| # This file is autogenerated by pip-compile with Python 3.12 | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misschien mooi om dit even te genereren met Python 3.13. Ik stel voor om verder een aparte requirements.txt te maken voor deze module, zoals we dat ook voor classification doen, om conflicten te voorkomen.
Zie bijvoorbeeld:
Line 48 in 70e2f53
| COPY app/signals/apps/classification/requirements.txt /app/signals/apps/classification/requirements.txt |
|
|
||
| def post(self, request, *args, **kwargs): | ||
| try: | ||
| if settings.LLM_FOREGROUND_PREDICTION_ENABLED: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deze kan boven het try blok, toch?
| "content": text, | ||
| }, | ||
| ], | ||
| model='mistral-small-3.2-24b-instruct-2506', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Het is mooi om hier een instelling van te maken via settings en een environment variabele, dan kunnen we dat makkelijk instellen. Dit mag wel de default zijn.
| def get_categories_with_description() -> QuerySet[tuple[str, str, str]]: | ||
| categories = (Category.objects | ||
| .filter(parent__isnull=False) | ||
| .filter(~Q(description=""), description__isnull=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misschien kunnen we deze filter op description eraf halen, dat voorkomt dat we impliciet categorieën niet meenemen.
| def format_categories(categories: QuerySet[tuple[str, str, str]]) -> str: | ||
| result = [] | ||
| for parent_name, name, description in categories: | ||
| result.append(f" - {parent_name} -> {name}: {description}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| result.append(f" - {parent_name} -> {name}: {description}") | |
| result.append(f" - {parent_name} -> {name}: {description or ''}") |
bartjkdp
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ziet er heel goed uit, nog een paar kleine wijzigingen voorgesteld.
Samenvatting
Deze PR integreert het werk uit de PoC: https://github.com/delta10/signal-classification-poc in Signalen. In de PoC is aangetoond dat het mogelijk is om met een (eventueel self-hosted) open-source LLM de categorie van een melding te voorspellen. De voorspelling wordt gedaan op basis van de beschikbare subcategorieën en hun omschrijvingen. Hierdoor is geen apart trainingsproces meer nodig, in tegenstelling tot het huidige TF-IDF-model. Dit maakt de oplossing flexibeler en onderhoudsvriendelijker.
Functionaliteit
Het LLM-model voorspelt de meest waarschijnlijke subcategorie op basis van:
Feature flags
LLM_BACKGROUND_PREDICTION_ENABLED
Zet LLM-voorspellingen op de achtergrond aan. De daadwerkelijke classificatie gebeurt nog steeds via het TF-IDF-model. Op de achtergrond wordt óók een voorspelling uitgevoerd met het LLM-model. Het resultaat hiervan wordt opgeslagen in de database tabel llm_prediction_prediction met de kolommen:
llm_predicted_categorytfidf_predicted_categorysignalLLM_FOREGROUND_PREDICTION_ENABLED
Zet LLM-voorspellingen op de voorgrond aan. De daadwerkelijke classificatie (bijvoorbeeld bij een request vanuit de frontend van Signalen) gebeurt dan met het LLM-model.
Configuratie
De gebruikte LLM wordt geconfigureerd met de volgende environment-variabelen:
LLM_API_URL– URL van het modelLLM_API_KEY– API key voor het modelVoor het testen zijn de hosted generatieve AI-modellen van Scaleway gebruikt. Getest met: mistral-small-3.2-24b-instruct-2506.
Notities
De LLM-voorspelling is op dit moment merkbaar trager dan de oude TF-IDF-voorspelling.
Al uitgevoerde optimalisaties:
max_tokens ingesteld om de response te beperken.
Caching van de get_system_prompt() functie.
Gekozen voor een relatief snel model.
De kosten van het gebruik van de Scaleway-modellen zijn nog niet volledig inzichtelijk (ik had geen toegang tot het kostenoverzicht). Dit moeten we nog goed in de gaten houden.
Testen
LLM_BACKGROUND_PREDICTION_ENABLEDLLM_FOREGROUND_PREDICTION_ENABLEDLLM_API_URLLLM_API_KEYControleer de resultaten in de tabel llm_prediction_prediction.
Alleen subcategorieën met omschrijving worden voorspeld.
Onzekere subcategorie → Overig {{ hoofdcategorienaam }}
Onzekere hoofd- en subcategorie → Overig / Overig