AI Message Intent Classification
Overview
Beyond literal keyword replies, the platform also supports a chatbot that understands the user's intent. This job takes an incoming user message, classifies it into an intent through three processing phases (keyword → vector → LLM), then hands it to the response sender to reply according to the intent that was matched.
It runs as part of a workflow: trigger rules with source_type = 'message_received' are
grouped by workflow_id, and classification runs once per workflow.
Business Flow
- Receive a payload containing
lineUserId,lineOaId,organizationId,messageText,messageType,replyToken, andtimestamp. - Load the
trigger_rulerows for that (lineOaId, organizationId) pair wheresource_type='message_received',enabled=true, and the rule is not deleted. If none exist, the job ends. - Group the rules by
workflow_id, preserving insertion order to match the behaviour of a JS Map, then iterate throughclassifyAndRoute. - Read the classifier configuration from the first rule's
sourceConfig:intents,fallbackIntentId,confidenceThreshold(default 0.3), andconversationMemory. - Split intents into two kinds:
keywordandai. - Load conversation history — when memory is enabled, read from the Redis list keyed by the
line OA and line user pair, up to
maxMessagesentries (default 10), then reverse the order so it runs oldest to newest. - Three-phase classification
- Phase 1 — Keyword:
matchKeywordcompares the message against each intent's keywords. A hit yields a confidence of 1.0 and ends classification immediately — the cheapest and fastest path. - Phase 2 — Vector: compare the message embedding against the
intentVectorsstored in the configuration using cosine similarity. If it clears the threshold, that result is used. - Phase 3 — AI: call the LLM through
aix, which readsai_configper OA and provider, asking it to classify the intent along with a confidence score. Anything below the threshold falls back tofallbackIntentId.
- Phase 1 — Keyword:
- Once an intent is determined, route to
ResponseSenderService.SendResponse, which supports several modes:- reply with a plain text message, a rich message, or a configured flex message
ai_knowledgemode searches the knowledge base using Meilisearch combined with vectors — governed bytopK,semanticRatio,directAnswer, anddirectAnswerThreshold— then has the LLM compose the answer- attach quick reply chips, resolve
custommerge tags, and wrap URLs in the answer with a tracking redirect whentracking.enabledis on - store the assistant's reply back into memory via
storeAssistantMemory
- Record the outcome to
trigger_logthroughTriggerLogger.
note
message_received_trigger is the only queue in the system that is not DLQ-monitored — its
topology is asserted, but nothing subscribes to its .dlq queue.
Key Files & Functions
internal/messagetrigger/service.goMessageTriggerService.ProcessMessage(ctx, payload)— the entry pointfetchMessageReceivedRules(),classifyAndRoute(),matchKeyword(),parseClassificationResult(),cosineSimilarity(),decodeIntents()- the
MessageReceivedPayload,classificationResult,IntentDefinition, andConversationEntrystructs
internal/messagetrigger/response_sender.goResponseSenderService.SendResponse(ctx, params)applyTracking(),loadMergeUser(),storeAssistantMemory(),appendQuickReply()IntentResponseConfig, whoseExtrafield carriesknowledgeBaseId,retrievalConfig, andtracking
internal/messagetrigger/prompts.go— prompt templates for the classifier and the answerinternal/messagetrigger/transform.go— message object transformationinternal/messagetrigger/consumer.go—Consumer.HandleMessageReceivedinternal/aix/aix.go— the LLM client, withConfigResolverreading from theai_configtableinternal/embedx/embedx.go— the embedding API client, andinternal/meilix/meilix.go— the Meilisearch client- Queue:
message_received_trigger(profilemain)
Connections to Other Services
- Receives jobs from: the
line_webhookhandler when priority isai_classifier_only, or from Keyword Auto-response whenfallbackToAi = true - Tables:
trigger_rule(classifier configuration),ai_config(provider, model, and API key per OA),knowledge_chunkandknowledge_document(for knowledge-base answers),trigger_log, andline_user - Redis: a list holding conversation memory, keyed by the line OA and line user pair
- External services: the LLM provider configured in
ai_config, the embedding API (EMBEDDING_API_URL), and Meilisearch (MEILISEARCH_HOST) - LINE API: reply and push for delivering the answer
- Connects to: Knowledge Base Indexing as the source of answers, and
the action executor, which reuses the same response sender for the
send_messageaction