Polling Agents in AI Assistants: 11 Implementatiemodellen
Betrouwbare pollingpatronen voor AI-agents.
Pollingagenten zijn een van de minst glamourvolle onderdelen van de architectuur van AI-assistenten, maar ze zijn ook een van de meest nuttige.
Een normale chatassistent wacht tot de gebruiker iets vraagt. Een pollingagent blijft in de gaten houden. Het controleert een bron, merkt veranderingen op, besluit of er iets relevant is, en handelt vervolgens. Die actie kan een melding zijn, een samenvatting, een concept, een toolroep of een volledig workflow.
Zo verandert een assistent van “beantwoord mijn vraag” naar “houd dit voor mij in de gaten”. In plaats van reactief te zijn, wordt het een achtergrondproces dat dingen namens de gebruiker opmerkt en handelt wanneer aan bepaalde voorwaarden wordt voldaan.

Het belangrijke ontwerppunt is eenvoudig: maak het taalmodel niet verantwoordelijk voor tijd, status, opnieuw proberen of locking (sloten). Gebruik daarvoor normale backend-infrastructuur. Gebruik het model waar het waardevol is: het interpreteren van rommelige context, het maken van semantische oordelen en het produceren van nuttige taal.
Wat is een Pollingagent?
Een pollingagent is een achtergrondproces dat herhaaldelijk een bron controleert en een assistentactie uitloost wanneer een voorwaarde wordt voldaan. In de bredere AI-systemen stack — waarbij de assistent een LLM, geheugen, tooling, routing en observability combineert — is de pollinglaag wat de assistent proactief maakt in plaats van puur reactief. Voor het volledige vijf-laagse beeld, zie AI-assistentenarchitectuur: LLM, geheugen, tools, routing, observability.
Voorbeelden:
- Controleer elke ochtend een inbox en vat belangrijke berichten samen.
- Houd een Notion-taaklijst in de gaten en voer de volgende taak uit.
- Monitor een GitHub-issue tot de status verandert.
- Poll een langlopende AI-taak tot het resultaat klaar is.
- Controleer een boekingslot tot er eentje beschikbaar is.
- Houd een leveranciersportaal in de gaten tot een document verschijnt.
- Scan wekelijks nieuwe onderzoeksartikelen en vat de relevante samen.
Een praktische pollingagent heeft vijf verantwoordelijkheden:
- Op het juiste moment wakker worden.
- Uit de bron lezen.
- Onthouden wat het al heeft gezien.
- Beslissen of de nieuwe status relevant is.
- Eenmaal handelen, veilig, zonder zichzelf te herhalen.
Een typische productieflow ziet er als volgt uit:
scheduler
-> polling worker
-> source system
-> state store
-> deterministic filters
-> optionele LLM-evaluatie
-> assistentactie
Deze structuur is saai op de beste mogelijke manier. Saai systemen zijn makkelijker te debuggen om 2 uur ’s nachts.
De Status die Elke Pollingagent Behoort
Pollingagenten hebben duurzame status nodig. Geschiedenis van het gesprek is niet genoeg. De assistent kan het gesprek onthouden, maar het systeem heeft een betrouwbare operationele registratie nodig.
Een goede pollingstatusregistratie bevat meestal:
{
"poll_id": "poll_123",
"user_id": "user_456",
"source_type": "notion",
"source_ref": "database_tasks",
"condition": "neem één taak in Todo-status en voer deze uit",
"interval_seconds": 600,
"last_run_at": "2026-06-19T01:00:00Z",
"next_run_at": "2026-06-19T01:10:00Z",
"last_seen_cursor": "cursor_of_tijdstip",
"last_result_hash": "b64e8a...",
"failure_count": 0,
"status": "active"
}
Het exacte schema hangt af van de bron, maar de meeste systemen hebben deze concepten nodig.
Polldefinitie
Dit beschrijft wat de agent bewaakt en waarom.
poll_id
user_id
workspace_id
source_type
source_ref
condition_text
priority
status
Bijvoorbeeld:
source_type: notion
source_ref: Taken-database
condition_text: Vind één Todo-taak, claim deze, voer deze uit, markeer als Voltooid.
Schema
Dit beschrijft wanneer de agent moet draaien.
interval_seconds
cron_expression
timezone
last_run_at
next_run_at
jitter
Voor een Hermes-agent die elke 10 minuten Notion controleert:
interval_seconds: 600
timezone: Australia/Melbourne
Cursor of Snapshot
Dit helpt de agent om te voorkomen dat dezelfde gegevens opnieuw worden verwerkt.
Afhankelijk van de bron kan dit zijn:
last_seen_id
last_seen_timestamp
api_cursor
etag
version
content_hash
Voor een Notion-taakwachtrij is de cursor minder belangrijk dan taakstatus en claimvelden. Voor Gmail, GitHub of een sync-API is de cursor meestal kritiek.
Claim of Lease
Dit voorkomt dat twee workers dezelfde klus oppakken.
claimed_by
claimed_at
claim_expires_at
run_id
Bijvoorbeeld, een Notion-taak kan worden gewijzigd van:
Status: Todo
naar:
Status: InProgress
ClaimedBy: hermes
ClaimedAt: 2026-06-19T01:00:00Z
ClaimExpiresAt: 2026-06-19T01:30:00Z
RunId: run_789
Dit is het verschil tussen “Ik hoop dat slechts één worker het oppakt” en “het systeem heeft een claimprotocol”.
Uitvoeringsregistratie
Dit registreert wat er tijdens een run is gebeurd.
run_id
poll_id
source_object_id
started_at
finished_at
status
items_checked
items_changed
decision_summary
error
De uitvoeringsregistratie moet in de backend van de assistent leven, niet alleen in Notion of een ander extern hulpmiddel. Notion is goed voor menselijke zichtbaarheid. Het is niet ideaal als je enige uitvoeringslogboek.
Dedupe-registratie
Dit voorkomt dubbele meldingen of herhaalde acties.
dedupe_key
poll_id
source_object_id
condition_version
action_type
delivered_at
Bijvoorbeeld:
user_456:poll_123:notion_page_999:execute:v1
Als dezelfde actie opnieuw wordt geprobeerd, kan het systeem deze onderdrukken.
Methode 1: Geplande Polling Worker
Dit is het eenvoudigste betrouwbare patroon.
Een scheduler wordt elk vast interval wakker en roept een worker aan. De worker leest de bron, update de status en lost een assistentactie uit indien nodig.
scheduler
-> worker
-> source API
-> database
-> assistentactie
Hoe Het Draait
De scheduler is verantwoordelijk voor de tijd. Het kan cron zijn, een cloud scheduler, een Kubernetes CronJob of een kleine interne scheduler.
Elk interval start het een worker-run. De worker laadt zijn configuratie, queryt de doelbron, vergelijkt het resultaat met de opgeslagen status en handelt indien nodig.
Voor een eenvoudige assistent is dit vaak genoeg. Een enkele scheduler en een lichtgewicht workerproces kunnen tientallen dagelijkse controles afhandelen zonder dat wachtrijen, leases of gedistribueerde coördinatie nodig zijn.
Statusmodel
De scheduler slaat zeer weinig op. Meestal weet hij alleen wanneer hij een taak moet triggeren.
De applicatiedatabase slaat de belangrijke status op:
polldefinitie
schema
cursor of snapshot
laatste run-tijd
failure count
status
De worker moet stateless zijn. Hij kan tijdelijke gegevens bevatten tijdens het draaien, maar de duurzame waarheid hoort in de database.
Voorbeeldflow
Elke 10 minuten:
trigger Hermes polling worker
Worker:
laad actieve pollconfiguratie
query bron
vergelijk met vorige status
voer deterministische checks uit
roep LLM alleen aan indien nodig
update status
emit assistentevent
Beste Past
Gebruik geplande polling workers voor:
- Dagelijkse samenvattingen.
- Uurlijkse controles.
- Kleine interne automatiseringen.
- Eenvoudige “houd dit in de gaten”-taken.
- Laag tot middelvolume assistenttaken.
Zwakke Punten
Gepland polling is makkelijk te begrijpen, maar het kan kwetsbaar worden op schaal. Als veel polls tegelijk draaien, kun je je workers overbelasten of tegen provider rate limits aanlopen. Ook kunnen opnieuw proberen rommelig worden als de scheduler direct het werk start.
Methode 2: Wachtrij-gebaseerde Polling Workers
Wachtrij-gebaseerd polling is meestal de beste standaard voor productie AI-assistenten.
De scheduler voert de poll niet direct uit. Hij zet een taak op een wachtrij. Workerprocessen consumeren taken uit de wachtrij.
scheduler
-> wachtrij
-> worker pool
-> source API
-> state store
-> assistentactie
Hoe Het Draait
Een scanner zoekt naar polls die klaar zijn en voegt taken toe aan de wachtrij. Workers halen taken op wanneer ze capaciteit hebben.
Dit geeft je backpressure. Als het systeem druk is, wachten taken in de wachtrij in plaats van de source API of de LLM-provider te overweldigen.
Statusmodel
De database slaat de pollstatus op:
poll_id
user_id
source_ref
condition_text
next_run_at
cursor
status
failure_count
Het wachtrijbericht moet klein blijven:
{
"poll_id": "poll_123",
"scheduled_for": "2026-06-19T01:10:00Z",
"attempt": 1
}
De worker laadt de volledige status uit de database wanneer hij start.
Voorbeeldflow
Elke minuut:
scheduler vindt polls waar next_run_at <= nu
scheduler voegt taken toe aan de wachtrij
Workers:
halen taken uit wachtrij
vergrendelen of leasen de poll
query de bron
update status
emit assistentactie indien nodig
stel next_run_at in
Beste Past
Gebruik wachtrij-gebaseerd polling voor:
- Multi-user AI-assistenten.
- Veel gelijktijdige polls.
- Integraties met rate limits.
- Opnieuw probeerbaar achtergrondwerk.
- Taken die verschillende hoeveelheden tijd kunnen kosten.
- SaaS-producten waar betrouwbaarheid belangrijk is.
Zwakke Punten
Wachtrijen voegen infrastructuur toe. Je hebt dead letter handling, idempotentie, zichtbaarheidstijden en retry-beleid nodig. Dit is het waard voor productsystemen, maar waarschijnlijk overkill voor een klein prototype.
Methode 3: Extern Hulpmiddel als Wachtrij
Dit is het patroon in het Notion plus Hermes-voorbeeld.
Het externe hulpmiddel is niet alleen een databron. Het wordt de menselijke taakwachtrij. De agent controleert periodiek het hulpmiddel, claimt één taak, voert deze uit en update de taakstatus.
scheduler
-> Hermes worker
-> Notion database
-> claim één taak
-> voer taak uit
-> update Notion status
Hoe Het Draait
Elke 10 minuten queryt Hermes de Notion-database voor één taak in Todo-status. Het kiest de volgende taak, meestal op basis van prioriteit en creatiedatum. Vervolgens claimt het de taak door deze op InProgress te zetten.
Daarna voert Hermes de taak uit. Als de uitvoering slaagt, markeert het de taak als Complete. Als de uitvoering mislukt, markeert het de taak als Failed of retourneert deze naar Todo met een retry-telling.
Statusmodel
Notion slaat de menselijke taakstatus op:
Titel
Beschrijving
Status: Todo | InProgress | Complete | Failed
Prioriteit
CreatedAt
ClaimedBy
ClaimedAt
ClaimExpiresAt
RunId
RetryCount
LastError
CompletedAt
Hermes backend slaat de operationele uitvoeringsstatus op:
run_id
notion_page_id
started_at
finished_at
execution_status
tool_calls
LLM trace
error details
idempotency_key
Deze splitsing is belangrijk. Notion is uitstekend voor zichtbaarheid en handmatig bewerken. Hermes backend is beter voor logs, opnieuw proberen, dedupe en auditgeschiedenis.
Voorbeeldflow
Elke 10 minuten:
Hermes wordt wakker
Hermes:
query Notion voor één taak waar Status = Todo
sorteer op Prioriteit, CreatedAt
update geselecteerde taak naar InProgress
stel ClaimedBy, ClaimedAt, ClaimExpiresAt, RunId in
voer de taak uit
schrijf uitvoeringslog
stel taak in op Complete of Failed
Beste Past
Gebruik dit patroon wanneer:
- Mensen al werk beheren in Notion, Jira, Linear, Trello of een ander hulpmiddel.
- Je wilt dat de assistent zichtbare taken verwerkt.
- Het taakbord de gebruikersinterface is.
- Je een eenvoudig human-in-the-loop automatiseringsmodel nodig hebt.
Zwakke Punten
Externe hulpmiddelen zijn zelden perfecte wachtrijen. Atomische claims kunnen beperkt zijn. Queryconsistentie kan achterlopen. Rate limits kunnen van toepassing zijn. Als de agent op meerdere instanties kan draaien, heb je een zorgvuldige claim- of lease-strategie nodig.
De praktische aanbeveling is om Notion te gebruiken als de menselijke taakinbox terwijl alle uitvoeringslogs, retry-registraties, traces en idempotentie-sleutels in Hermes blijven. Notion geeft gebruikers zichtbaarheid; Hermes houdt het systeem betrouwbaar. Voor de dispatcher- en concurrentiemechanica die achter dit patroon in Hermes zitten, zie Kanban in Hermes Agent voor Self-Hosted LLM Workflows.
Methode 4: Langlopende Worker Loop
Een langlopende loop is de eenvoudigste implementatie.
while True:
due_polls = db.find_due_polls()
for poll in due_polls:
run_poll(poll)
sleep(30)
Dit patroon combineert planning en uitvoering in één service, wat het het eenvoudigste mogelijke startpunt maakt voor achtergrondagentwerk.
Hoe Het Draait
Het workerproces draait continu. Elke paar seconden of minuten controleert het de database op due polls en voert deze uit. Het is makkelijk te bouwen, makkelijk te redeneren over en snel te itereren tijdens ontwikkeling.
Statusmodel
De database slaat nog steeds duurzame status op:
pollconfiguratie
next_run_at
cursor
laatste resultaat
failure count
status
Het procesgeheugen moet alleen tijdelijke status bevatten:
huidige batch
kortlevende cache
in-flight run
Sla belangrijke voortgang nooit alleen in het geheugen op. Als het proces crasht, is elke status die niet naar duurzame opslag is geschreven weg, en de volgende run heeft geen manier om te weten waar het stopte.
Beste Past
Gebruik langlopende loops voor:
- Prototypes.
- Lokale ontwikkeling.
- Interne tools.
- Single-tenant systemen.
- Laag-volume agents.
Zwakke Punten
Dit patroon wordt riskant met meerdere replica’s. Zonder leases kunnen twee workers dezelfde poll uitvoeren. Het mist ook de operationele functies van een echte wachtrij of workflowengine.
Een langlopende loop is niet verkeerd als startpunt, maar het is geen gedistribueerde scheduler en moet niet als zodanig worden behandeld. Zodra je meerdere replica’s of sterkere betrouwbaarheids garanties nodig hebt, zul je naar een van de meer gestructureerde patronen hierboven moeten bewegen.
Methode 5: Webhook-First Met Polling Fallback
Als de bron webhooks ondersteunt, gebruik ze dan. Polling moet vaak de backup zijn, niet het primaire mechanisme.
external system
-> webhook endpoint
-> event store
-> assistentactie
reconciliation poll
-> source API
-> vergelijk met event store
-> repare gemiste events
Hoe Het Draait
Het externe systeem stuurt events naar je webhook-endpoint wanneer er iets verandert. Je systeem slaat het event op en verwerkt het asynchroon.
Een langzamer reconciliation poll draait elke paar uur of eenmaal per dag. Het controleert of er events zijn gemist.
Statusmodel
De eventstore registreert inkomende webhooks:
event_id
source_type
source_object_id
event_type
received_at
payload_hash
processed_at
signature_valid
De reconciliation poll slaat op:
last_reconciliation_at
last_seen_cursor
last_seen_version
De source object-tabel slaat de laatst bekende status op:
external_id
current_status
external_updated_at
last_processed_event_id
Beste Past
Gebruik webhook-first architectuur voor:
- GitHub-events.
- Stripe-events.
- Slack-events.
- CRM-updates.
- Deploymentsmeldingen.
- Ticketingsystemen.
Zwakke Punten
Webhooks vereisen een publiek endpoint, signature validatie, replay-bescherming en event dedupe. Sommige providers sturen ook onvolledige events, dus je moet misschien nog steeds het volledige object ophalen.
Desondanks, als goede webhooks bestaan, is elke minuut pollen meestal verspilling.
Methode 6: Provider-Side Background Job Polling
Soms is het ding dat wordt gepolld de AI-taak zelf.
De applicatie start een langlopende providertaak, slaat de job-ID op en controleert later of deze is voltooid.
app
-> start AI background job
-> sla provider job id op
-> poll status
-> haal resultaat op
-> meld gebruiker
Hoe Het Draait
De assistent start een taak met de provider. De provider retourneert een ID. Je backend slaat die ID op en controleert de status tot de taak slaagt, faalt, verloopt of time-out geeft.
Statusmodel
Je backend slaat op:
assistant_task_id
provider_job_id
user_id
status
created_at
last_checked_at
expires_at
result_ref
De provider slaat de tijdelijke jobstatus en output op.
Als de output belangrijk is, kopieer deze dan zo snel mogelijk naar je eigen duurzame opslag zodra de taak is voltooid. Provider-side resultopslag heeft korte retentievensters en is geen vervanging voor een juiste archief in je eigen systeem.
Beste Past
Gebruik provider-side background job polling voor:
- Lange AI-onderzoekstaken.
- Grote documentverwerking.
- Codebase-analyse.
- Rapportgeneratie.
- Data-extractietaken.
- Taken die normale HTTP-request time-outs overschrijden.
Zwakke Punten
Dit patroon lost één probleem op: wachten op een lange providertaak. Het vervangt niet je workflowengine, scheduler, wachtrij of business state store.
Methode 7: Duurzame Workflow Engine
Een duurzame workflowengine beheert langlopende uitvoering, timers, opnieuw proberen en herstel. Temporal is de meest voorkomende keuze voor Go- en Python-gebaseerde assistant backends; voor een volledige implementatiegids zie Implementeren van Workflow Applicaties met Temporal in Go.
In plaats van elke wacht- en retry-manuele bedrading, modelleer je het proces als een workflow.
workflow engine
-> activiteit: check bron
-> timer: wacht
-> activiteit: evalueer resultaat
-> activiteit: meld gebruiker
Hoe Het Draait
De workflow start eenmaal en controleert daarna zijn eigen wachttijd. Het kan minuten, dagen of weken slapen. Als het workerproces crasht, kan de workflowengine hervatten vanuit de opgenomen status.
Statusmodel
De workflowengine slaat op:
workflow_id
executiegeschiedenis
timer status
activiteit pogingen
retry beleid
huidige workflow status
Je applicatiedatabase slaat op:
user-facing poll definitie
autorisatie referenties
business records
melding records
De workflowengine bezit processtatus — uitvoeringsgeschiedenis, timers, opnieuw proberen en activiteitspogingen. Je database bezit business status — gebruikersconfiguraties, autorisatie-registraties, meldingen en auditlogs. Het apart houden van deze lagen voorkomt dat elke laag een verwarde hybride van beide wordt.
Beste Past
Gebruik duurzame workflows voor:
- Meerstaps businessprocessen.
- Langlopende automatiseringen.
- Menselijke goedkeuringsflows.
- Betrouwbare opnieuw proberen.
- Auditabele achtergrondwerk.
- Processen die na falen moeten hervatten.
Zwakke Punten
Workflowengines voegen concepten en infrastructuur toe. Ze zijn uitstekend wanneer het proces belangrijk is, maar zwaar voor eenvoudige uurlijkse controles.
Methode 8: Persistente Agent Runtime
Sommige agentframeworks kunnen agentstatus persistent maken, uitvoering checkpointen en later hervatten.
Dit is nuttig wanneer de agent zelf een meerstaps redeneringsproces heeft.
scheduler of workflow
-> agent runtime
-> laad checkpoint
-> roep tools aan
-> sla checkpoint op
-> hervat later
Hoe Het Draait
Een externe scheduler of workflow start de agent. De agent runtime laadt vorige status, voert de volgende stap uit, roept tools aan indien nodig en schrijft een checkpoint.
De agent runtime moet niet je enige scheduler zijn. Het is beter te behandelen als de redeneringslaag binnen een grotere backendarchitectuur.
Statusmodel
Agent checkpointopslag bevat:
huidige node
berichten
tool outputs
intermediate redeneringsstatus
pending actie
Langdurig geheugen bevat:
stabiele gebruikersvoorkeuren
feiten
projectcontext
bronreferenties
Operationele status hoort nog steeds ergens anders:
poll schema
cursor
status
retry count
dedupe records
Een nuttige regel: geheugen is geen cursor, en een checkpoint is geen wachtrij. Agentgeheugen slaat op wat het model weet; operationele status trackt waar het proces is en wat het heeft gedaan. Het samenvoegen van de twee leidt tot subtiele bugs die pas verschijnen onder concurrentie of na een herstart. De volledige ontwerpruimte voor werkgeheugen, duurzame status en retrieval-lagen wordt behandeld in Geheugensystemen in AI-Assistenten.
Beste Past
Gebruik persistente agent runtime voor:
- Meerstaps onderzoek.
- Agents die pauzeren en hervatten.
- Human-in-the-loop werk.
- Tool-heavy redenering.
- Taken waarbij context zich in de loop van de tijd ophoopt.
Zwakke Punten
Agentpersistentie is niet hetzelfde als operationele betrouwbaarheid. Je hebt nog steeds planning, locking, opnieuw proberen, rate limits en auditlogs nodig.
Methode 9: Database Sync Plus Change Evaluatie
In dit patroon wordt polling gebruikt om externe gegevens te synchroniseren naar je eigen database. De assistent reageert vervolgens op lokale databaseveranderingen in plaats van externe API’s direct te queryen bij elke evaluatiecyclus.
sync poller
-> external API
-> lokale database
-> change evaluator
-> assistentactie
Dit scheidt datasynchronisatie van assistentintelligentie. De sync worker is verantwoordelijk voor het actueel houden van lokale records; de evaluator is verantwoordelijk voor het beslissen wat er met veranderingen moet gebeuren. Elke laag kan onafhankelijk worden getest, gemonitord en geschaald.
Hoe Het Draait
De sync worker haalt periodiek externe veranderingen op en schrijft genormaliseerde records in je database. Een tweede worker of changestream detecteerde bijgewerkte rijen en beslist of de assistent moet handelen.
Statusmodel
De synctabel slaat op:
external_id
source_type
raw_payload
normalized_fields
external_updated_at
synced_at
version
content_hash
De syncstatus slaat op:
source_cursor
last_sync_at
rate_limit_status
failure_count
De assistentevaluatietabel slaat op:
object_id
evaluation_status
last_evaluated_hash
decision
notification_id
Beste Past
Gebruik dit patroon voor:
- CRM-sync.
- Ticketingsystemen.
- Accountantdocumenten.
- Productinventaris.
- Compliance-review.
- Zoekindexering.
- Interne dashboards.
Zwakke Punten
Alles synchroniseren kan duur en onnodig zijn. Het kan ook privacy- en retentie verplichtingen creëren. Gebruik dit patroon wanneer lokale data waarde heeft buiten een enkele assistentactie.
Methode 10: Adaptief Pollen
Adaptief pollen verandert frequentie op basis van status, urgentie of recente activiteit.
actieve object: poll elke 1 minuut
wachtend object: poll elke 1 uur
verouderd object: poll één keer per dag
voltooid object: stop polling
Hoe Het Draait
Na elke run beslist de worker wanneer de volgende run moet plaatsvinden.
Als het object recentelijk is veranderd, poll dan eerder. Als er lang niets is veranderd, vertraag dan. Als de taak voltooid is, stop dan.
Statusmodel
De pollstatus bevat:
current_interval
minimum_interval
maximum_interval
backoff_policy
last_activity_at
priority
stop_condition
De bronsnapshot bevat:
status
updated_at
activity_level
expected_next_change
Beste Past
Gebruik adaptief pollen voor:
- Deploymentsstatus.
- Bezorgingsvolging.
- Beschikbaarheid van agenda-slots.
- Prijsmonitoring.
- Build jobs.
- Langlopende providertaken.
- Elke bron met bursty updates.
Zwakke Punten
Adaptief pollen kan moeilijker te redeneren zijn. Als een taak op een strikt tijdstip moet draaien, houd het dan strikt. Maak compliance-taken niet slim.
Methode 11: Semantisch Pollen Met een LLM Evaluator
Semantisch pollen wordt gebruikt wanneer de voorwaarde vaag is.
Code kan beantwoorden:
Is status gelijk aan Complete?
Is prijs onder 100?
Is er een nieuw bericht?
Een LLM kan helpen beantwoorden:
Klinkt dit e-mail urgent?
Is deze klant waarschijnlijk ontevreden?
Is dit onderzoeksartikel relevant?
Vereist deze verandering mijn aandacht?
Hoe Het Draait
De worker past eerst goedkope deterministische filters toe. Alleen kandidaat-items gaan naar de LLM.
nieuw item?
komt overeen met source filters?
niet al verwerkt?
niet duidelijk irrelevante?
Vervolgens evalueert de LLM de kleinere kandidaatset en retourneert gestructureerde output.
{
"should_notify": true,
"urgency": "high",
"reason": "De klant meldt een productiestoring."
}
Statusmodel
De polldefinitie slaat op:
semantic_condition
examples
negative_examples
user_preference_summary
model_config
De evaluatielog slaat op:
input_reference
model
prompt_version
structured_output
confidence
cost
latency
De pollstatus slaat op:
last_seen_ids
last_evaluated_hashes
last_decision
last_decision_reason
Beste Past
Gebruik semantisch pollen voor:
- Detectie van belangrijke e-mails.
- Klant sentiment monitoring.
- Onderzoekswaarschuwingen.
- Sales opportuniteit detectie.
- Security triage.
- Executive briefings.
Zwakke Punten
LLM-roepen kosten geld en voegen latentie toe. Ze kunnen ook inconsistent zijn als prompts en schemas los zijn. Gebruik eerst deterministische filters. Vraag het model alleen wanneer oordeel echt nodig is.
Beslissingstabel: Een Polling Agent Methode Kiezen
| Methode | Beste Toepassing | Voordelen | Nadelen |
|---|---|---|---|
| Geplande polling worker | Eenvoudige terugkerende assistenttaken | Makkelijk te bouwen, makkelijk te debuggen, minimale infrastructuur | Beperkte schaalbaarheid, basis opnieuw proberen, kan workers overbelasten als veel polls tegelijk afvuren |
| Wachtrij-gebaseerde polling workers | Productie SaaS-assistenten met veel gebruikers | Schaalbaar, veerkrachtig, ondersteunt opnieuw proberen en backpressure | Vereist wachtrijinfrastructuur, idempotentie, dead letter handling |
| Extern hulpmiddel als wachtrij | Notion, Jira, Linear, Trello gebaseerde taakuitvoering | Mensvriendelijk, makkelijk te inspecteren, werkt met bestaande workflows | Externe hulpmiddelen zijn niet perfecte wachtrijen, atomische claim kan moeilijk zijn |
| Langlopende worker loop | Prototypes en interne tools | Zeer eenvoudig, snel te implementeren, weinig bewegende onderdelen | Zwakke betrouwbaarheid, slecht multi-replica gedrag, beperkte operationele controle |
| Webhook-first met polling fallback | Event-gedreven integraties | Snelle reactie, minder API-aanroepen, reconciliation vangt gemiste events op | Vereist publiek endpoint, eventvalidatie, dedupe, provider webhook ondersteuning |
| Provider-side background job polling | Langlopende AI providertaken | Handelt trage AI-taken af, eenvoudig statusmodel, goed voor asynchrone UX | Beheert alleen provider job status, niet volledige business workflow |
| Duurzame workflow engine | Langlopende meerstaps processen | Sterke opnieuw proberen, timers, auditgeschiedenis, herstel na crashes | Meer infrastructuur en concepten, zwaar voor eenvoudig polling |
| Persistente agent runtime | Meerstaps redeneringsagents | Bewaart agentcontext, ondersteunt pauze en hervat, goed voor tool-heavy taken | Geen scheduler of wachtrij vervanging, heeft nog steeds operationele backend nodig |
| Database sync plus change evaluatie | Systemen waar externe data lokale waarde heeft | Schone scheiding, lokale rapportage, minder herhaalde externe calls | Meer opslag, meer sync complexiteit, mogelijke privacy en retentie zorgen |
| Adaptief pollen | Bursty bronnen of variabele urgentie taken | Vermindert kosten, respecteert rate limits, reageert sneller bij hoge activiteit | Moeilijker te redeneren over, niet ideaal voor strenge schema’s |
| Semantisch pollen met LLM evaluator | Vage voorwaarden die oordeel vereisen | Handelt natuurlijke taalintentie af, nuttige samenvattingen, flexibele beslissingen | Kosten, latentie, prompt kwaliteit risico, moet geen vervanging zijn voor eenvoudige code checks |
Aanbevolen Standaardarchitectuur
Voor de meeste productie AI-assistenten, begin met dit:
polls table
-> scheduler
-> wachtrij
-> stateless workers
-> deterministische filters
-> optionele LLM evaluator
-> melding of assistentactie
Een minimaal schema:
CREATE TABLE polls (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
source_type TEXT NOT NULL,
source_ref TEXT NOT NULL,
condition_text TEXT NOT NULL,
schedule_type TEXT NOT NULL,
interval_seconds INTEGER,
timezone TEXT,
next_run_at TIMESTAMP NOT NULL,
last_run_at TIMESTAMP,
cursor_value TEXT,
last_hash TEXT,
status TEXT NOT NULL,
failure_count INTEGER NOT NULL DEFAULT 0,
last_error TEXT,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
CREATE TABLE poll_runs (
id TEXT PRIMARY KEY,
poll_id TEXT NOT NULL,
started_at TIMESTAMP NOT NULL,
finished_at TIMESTAMP,
status TEXT NOT NULL,
items_checked INTEGER,
items_matched INTEGER,
decision_summary TEXT,
error TEXT
);
CREATE TABLE notifications (
id TEXT PRIMARY KEY,
poll_id TEXT NOT NULL,
user_id TEXT NOT NULL,
dedupe_key TEXT NOT NULL,
title TEXT NOT NULL,
body TEXT NOT NULL,
delivered_at TIMESTAMP,
UNIQUE (dedupe_key)
);
Dit geeft je een schone scheiding:
scheduler bezit tijd
wachtrij bezit buffering
worker bezit uitvoering
database bezit status
LLM bezit semantisch oordeel
assistent bezit gebruikersinteractie
Die scheiding is het hart van een betrouwbare pollingagent.
Voorbeeld: Hermes Agent Verwerkt Notion Taken
Laten we de architectuur nu toepassen op een concreet geval.
Stel dat een Notion-database taken bevat. Hermes moet elke 10 minuten draaien, één taak in Todo-status nemen, deze op InProgress zetten, uitvoeren en vervolgens als Complete markeren.
Dit is het beste te beschrijven als:
extern hulpmiddel als wachtrij
+
geplande polling worker
+
claim of lease gebaseerde uitvoering
Voor een productieve versie wordt het:
wachtrij-gebaseerd polling met Notion als de menselijke taakinbox
Notion Taakeigenschappen
De Notion-database moet velden bevatten zoals:
Naam
Status: Todo | InProgress | Complete | Failed
Prioriteit
CreatedAt
ClaimedBy
ClaimedAt
ClaimExpiresAt
RunId
RetryCount
LastError
CompletedAt
De belangrijke velden zijn ClaimedAt, ClaimExpiresAt en RunId. Ze maken de taakclaim zichtbaar en herstelbaar.
Hermes Uitvoeringsstatus
Hermes moet ook zijn eigen uitvoeringsregistratie bijhouden:
run_id
notion_page_id
started_at
finished_at
status
input_snapshot
tool_calls
result_summary
error
idempotency_key
Dit beschermt je als Notion handmatig wordt bewerkt, als een API-aanroep faalt, of als je moet auditen wat Hermes eigenlijk deed.
Uitvoeringsflow
Elke 10 minuten:
Hermes scheduler creëert een run
Hermes worker:
vindt één Notion-taak waar Status = Todo
sorteer op Prioriteit en CreatedAt
claim de taak door Status = InProgress in te stellen
schrijf ClaimedBy, ClaimedAt, ClaimExpiresAt en RunId
voer de taak uit
schrijf uitvoeringslogs naar Hermes backend
stel Notion Status = Complete in bij succes
stel Notion Status = Failed in bij falen
Als Hermes crasht na het claimen van een taak, kan de lease verlopen:
Status = InProgress
ClaimExpiresAt < nu
Een toekomstige run kan dan de taak herstellen of als mislukt markeren.
Faleringsafhandeling
Bij succes:
Status = Complete
CompletedAt = nu
LastError = leeg
Bij herstelbaar falen:
Status = Todo
RetryCount = RetryCount + 1
LastError = korte foutmelding
Bij niet-herstelbaar falen:
Status = Failed
LastError = duidelijke uitleg
Voor veiligheid moet Hermes ook een idempotentie-sleutel gebruiken:
notion_page_id + task_version + action_type
Dit voorkomt dat dezelfde taak twee keer wordt uitgevoerd als een retry op het verkeerde moment plaatsvindt.
Waarom Dit Niet Alleen Pollen Is
Het pollinggedeelte is alleen het wakermakenmechanisme. De echte architectuur is taakclaimen en betrouwbare uitvoering.
Een naïeve implementatie zegt:
Elke 10 minuten, vind een Todo-taak en doe het.
Een betrouwbare implementatie zegt:
Elke 10 minuten, claim precies één geschikte taak, registreer de run, voer idempotent uit en verplaats de taak naar een eindstatus.
Dat is het verschil tussen een demo en een agent die je kunt vertrouwen.
Veelvoorkomende Polling Agent Fouten
Fout 1: Geen Claim Protocol
Als twee workers dezelfde taak kunnen zien, kunnen ze deze beide uitvoeren.
Gebruik:
ClaimedBy
ClaimedAt
ClaimExpiresAt
RunId
Zelfs als je momenteel één worker draait, ontwerp dan alsof er later een tweede worker zou kunnen verschijnen.
Fout 2: Geen Dedupe Sleutel
Elke externe actie moet een dedupe-sleutel hebben.
user_id + poll_id + source_object_id + action_type + condition_version
Dit voorkomt herhaalde meldingen, herhaalde e-mails, herhaalde taakuitvoering en herhaalde toolcalls. De bredere principes achter scoping, opslaan en testen van deze sleutels zijn hier eveneens van toepassing — zie Idempotentie in Gedistribueerde Systemen Die Werkelijk Werken.
Fout 3: Te Vroeg De LLM Aanroepen
Vraag het model niet om databasefiltering te doen.
Slecht:
Stuur alle taken naar de LLM en vraag welke Todo is.
Beter:
Gebruik de Notion API filter om Todo taken op te halen.
Gebruik de LLM dan alleen als taakinterpretatie nodig is.
Fout 4: Notion Behandelen Als Enige Backend
Notion is een goede menselijke interface. Het is geen complete uitvoeringsbackend.
Behoud uitvoeringslogs, opnieuw proberen, traces en idempotentie-registraties in Hermes.
Fout 5: Oneindig Pollen
Elke poll moet een stopvoorwaarde hebben.
Voorbeelden:
stop na succes
stop na datum
stop na max opnieuw proberen
stop wanneer gebruiker het uitschakelt
stop na herhaalde autorisatiefalen
Een pollingagent zonder stopvoorwaarde is een stille kostenlek.
Fout 6: Geen Observability
Je moet het volgende kunnen beantwoorden:
Wat heeft de agent uitgevoerd?
Waarom is het uitgevoerd?
Wat heeft het gelezen?
Wat heeft het veranderd?
Waarom is het mislukt?
Heeft het de gebruiker gemeld?
Is het twee keer uitgevoerd?
Als je die vragen niet kunt beantwoorden, is het systeem niet klaar voor belangrijk werk.
Observability Checklist
Track metrics zoals:
polls_due
polls_started
polls_succeeded
polls_failed
tasks_claimed
tasks_completed
tasks_failed
claim_expired_count
duplicate_suppressed_count
llm_calls
llm_cost
rate_limit_count
average_run_duration
Log velden zoals:
poll_id
run_id
source_type
source_object_id
claim_id
cursor_before
cursor_after
decision
dedupe_key
error
Bouw een admin-view voor:
actieve polls
vastgelopen InProgress taken
recente falen
hoge retry taken
dead letter jobs
duurzame LLM evaluaties
uitgeschakelde integraties
Pollingagenten draaien op de achtergrond, waar falen stil is en problemen zich kunnen opstapelen voordat iemand het merkt. Achtergrondsysteem hebben zichtbaarheid nodig die vanaf het begin is ingebouwd, niet toegevoegd als een afterthought wanneer er iets misgaat. Voor de volledige observability stack voor AI- en LLM-gebackte systemen — metrics, traces, gestructureerde logs en SLO’s — zie Observability voor LLM-systemen: Metrics, Traces, Logs en Testing in Productie.
Eindaanbeveling
Voor een serieuze AI-assistent, begin met wachtrij-gebaseerde polling workers en een duurzame state store. Voeg webhooks toe waar providers ze ondersteunen. Gebruik adaptief pollen wanneer rate limits belangrijk zijn. Gebruik een duurzame workflowengine wanneer het proces langlopend en meerstaps is. Gebruik persistente agent runtime wanneer de agent moet redeneren over tijd.
Voor het Hermes en Notion-voorbeeld, is de juiste architectuur:
Notion als de menselijke taakinbox
Hermes scheduler elke 10 minuten
Hermes worker met claim of lease logica
Hermes backend voor uitvoeringslogs en idempotentie
Notion status updates voor zichtbaarheid
Het pollinginterval is niet het moeilijke deel. Het moeilijke deel is ervoor zorgen dat de agent één taak claimt, deze één keer uitvoert, registreert wat er is gebeurd, en het systeem in een staat achterlaat die mensen kunnen begrijpen.
Dat is wat een pollingscript omzet in een betrouwbare AI-assistent — niet het interval, niet het model, maar de discipline rond het claimen van werk, het registreren ervan, en het systeem in een staat achterlaten die zowel mensen als toekomstige runs kunnen begrijpen.