Indonesian Threads Post Intent Classifier
Tag Indonesian Threads posts with buying intent, recommendation requests, complaints, praise, reviews and 11 more intents, using a small IndoBERT model that runs on a CPU.
An Indonesian Threads post classifier for social listening that tags each post with any of 16 intents, offline on a CPU. Seven are brand signals for social listening: purchase_intent, ask_recommendation, comparison, complaint, praise, review_experience and promotion. Nine name the rest of the feed: question, opinion, curhat, news_info, meme_humor, greeting, engagement_bait, random and spam. A post gets every intent it carries, usually one or two, so a disappointed review that asks for an alternative counts as a complaint, a review and a recommendation request. There is no `other` bucket for real complaints to hide in. It is trained on the way Indonesians post: casual Bahasa Indonesia, abbreviations (yg, gk, bgt), Indonesian-English code-mix (spill, worth it, racun) and regional phrasing. The model is IndoBERT (indobenchmark/indobert-base-p1) cut to 6 of its 12 layers and exported as an INT8 ONNX graph. Examples: "mending HP A atau B? mau beli minggu ini" is comparison, ask_recommendation and purchase_intent, and "udah 2 bulan pakai serum X, juara sih #ad" is review_experience, praise and promotion.
What it answersEvery intent whose score clears the threshold, with a score for each of the 16. An empty list means no intent cleared the threshold.
Specs
Under the hood
| Indonesian | |
|---|---|
| Base model | indobenchmark/indobert-base-p1 |
| Parameters | 66.6M |
| Size | 67.2 MB |
| Format | ONNX INT8 |
| Max tokens | 192 |
Distilled from the base model by keeping fewer layers and trimming the vocabulary to the languages served, then quantised to INT8 so it fits a CPU, an edge device or embedded hardware.
Use cases
What you can do with it
Social listening for a brand
Run every post that mentions your brand or category through the model and keep the complaints, praise, reviews and buying intent; drop memes, greetings and spam by name.
Finding buyers who are asking
Surface purchase_intent, ask_recommendation and comparison posts in your category, where people are choosing what to buy right now.
Choosing when to call a large model
Send only the posts that carry a brand signal to an LLM for summaries or replies. The small model filters the feed first.
Example results
Example results
Real outputs of this exact build on held-out rows — data it never saw in training. Each shows the input, what the model answered, and the reference label it was checked against. Nothing here is written by hand.
>>> classify("honestly capek bolak-balik toko, ada rekomendasi online shop pakan burung kenari yang pengirimannya cepat ke Surabaya? kuota 2 kg per bulan, budget Rp180.000.")
{ "labels": [ "purchase_intent", "ask_recommendation" ], "scores": { "purchase_intent": 0.4195, "ask_recommendation": 0.9605, "comparison": 0.0637, "complaint": 0.0401, "praise": 0.0148, "review_experience": 0.0125, "promotion": 0.0068, "question": 0.036, "opinion": 0.0082, "curhat": 0.1717, "news_info": 0.0127, "meme_humor": 0.0193, "greeting": 0.0223, "engagement_bait": 0.0086, "random": 0.0082, "spam": 0.0093 } }# Reference: ask_recommendation ✗ Differs
>>> classify("Menurut ambo, menonton film di bioskop Rp50.000 lebih berkesan daripada streaming Rp39.000 sebulan.")
{ "labels": [ "comparison" ], "scores": { "purchase_intent": 0.0123, "ask_recommendation": 0.0212, "comparison": 0.8639, "complaint": 0.0263, "praise": 0.0169, "review_experience": 0.2092, "promotion": 0.0212, "question": 0.0084, "opinion": 0.2147, "curhat": 0.0139, "news_info": 0.0177, "meme_humor": 0.0101, "greeting": 0.0109, "engagement_bait": 0.0179, "random": 0.0115, "spam": 0.0137 } }# Reference: comparison ✗ Differs
>>> classify("aplikasi bank maintenance terus, which is parah")
{ "labels": [ "complaint" ], "scores": { "purchase_intent": 0.0167, "ask_recommendation": 0.0163, "comparison": 0.01, "complaint": 0.9532, "praise": 0.0126, "review_experience": 0.0392, "promotion": 0.01, "question": 0.0195, "opinion": 0.0288, "curhat": 0.0454, "news_info": 0.0131, "meme_humor": 0.0163, "greeting": 0.0067, "engagement_bait": 0.0102, "random": 0.0281, "spam": 0.0124 } }# Reference: complaint ✗ Differs
>>> classify("kopi Senja Kita dingin2 gini enak bgt, 10/10 deh")
{ "labels": [ "praise" ], "scores": { "purchase_intent": 0.0115, "ask_recommendation": 0.0143, "comparison": 0.0063, "complaint": 0.0243, "praise": 0.8577, "review_experience": 0.1871, "promotion": 0.013, "question": 0.0118, "opinion": 0.0163, "curhat": 0.0117, "news_info": 0.0125, "meme_humor": 0.0164, "greeting": 0.0058, "engagement_bait": 0.0081, "random": 0.071, "spam": 0.0074 } }# Reference: praise ✗ Differs
>>> classify("Beli helm half-face Rp135.000 di marketplace 🪖 udah 2 bulan dipakai tiap hari. Busa dalam masih empuk, visor agak lecet dikit. Belum ada keluhan, ya sesuai harga lah 👌")
{ "labels": [ "review_experience" ], "scores": { "purchase_intent": 0.0278, "ask_recommendation": 0.0117, "comparison": 0.0159, "complaint": 0.0712, "praise": 0.0361, "review_experience": 0.9557, "promotion": 0.0251, "question": 0.0148, "opinion": 0.0086, "curhat": 0.0094, "news_info": 0.0185, "meme_humor": 0.0089, "greeting": 0.0101, "engagement_bait": 0.0094, "random": 0.0124, "spam": 0.0075 } }# Reference: review_experience ✗ Differs
Training data
Training data
Synthetic Indonesian Threads posts generated across seventeen topics, eight kinds of author, seven post formats, nine writing styles and eight regional registers, labelled with one rubric; a quarter of every batch sits on one of thirteen confusable boundaries and a fifth carries two or three intents. Brand names are invented.
The classes this model learned to recognise:
| Label | Meaning |
|---|---|
purchase_intent | The author wants to buy something, or asks where to buy it. |
ask_recommendation | Asks others which product, shop, place or service to choose. |
comparison | Weighs two or more named options against each other. |
complaint | Unhappy with a product, brand, shop or service, and says so. |
praise | Speaks well of a product, brand, shop or service. |
review_experience | Reports the author's own use of a product or service. |
promotion | Selling, affiliate links, #ad or endorsements, giveaways, open PO, jastip. |
question | Asks for information that is not about choosing or buying. |
opinion | A stance, hot take or argument about a topic, trend or brand. |
curhat | Personal feelings or problems: work, love, money, family. |
news_info | News, tips, tutorials, announcements or promos passed on. |
meme_humor | Jokes, memes and shitposts. |
greeting | Greetings, introductions, good-morning and good-night posts. |
engagement_bait | Posts that exist for replies or follows: 'drop akun kalian', mutualan. |
random | Passing thoughts and small life updates with no ask or stance. |
spam | Online gambling, scams, fake loans, bought followers, link dumps. |
The first five example rows, with the label each one carries:
| # | Text | Label |
|---|---|---|
| 0 | honestly capek bolak-balik toko, ada rekomendasi online shop pakan burung kenari yang pengirimannya cepat ke Surabaya? kuota 2 kg per bulan, budget Rp180.000. | ask_recommendation |
| 1 | Menurut ambo, menonton film di bioskop Rp50.000 lebih berkesan daripada streaming Rp39.000 sebulan. | comparison |
| 2 | aplikasi bank maintenance terus, which is parah | complaint |
| 3 | kopi Senja Kita dingin2 gini enak bgt, 10/10 deh | praise |
| 4 | Beli helm half-face Rp135.000 di marketplace 🪖 udah 2 bulan dipakai tiap hari. Busa dalam masih empuk, visor agak lecet dikit. Belum ada keluhan, ya sesuai harga lah 👌 | review_experience |
intura-ai script
Run it with the intura-ai SDK
- 1
Get it
Sign in on this site and press Get it. The model goes to your library with every version.
- 2
Create a download key
On your account page, create a download key and set it as INTURA_API_KEY. It only downloads what you own.
- 3
Install
pip install "intura-ai[local]" — the SDK plus the CPU runtime it uses to run a model on your machine.
- 4
Run it
Run the script. It downloads the build once and checks each file's SHA-256, then runs on your CPU, edge box or embedded Linux — no network call after the download.
# pip install "intura-ai>=3.0.0"
# export INTURA_API_KEY=... # a download key from your account
from intura_ai import Intura, LocalModel
client = Intura()
# Downloads once into ./chat-threads-post-intent-id/v1.0; later runs reuse the files on disk.
model_dir = client.models.download("chat-threads-post-intent-id", version="v1.0")
model = LocalModel.load(model_dir) # CPU, no network from here on
print(model.predict('honestly capek bolak-balik toko, ada rekomendasi online shop pakan burung kenari yang pengirimannya cepat ke Surabaya? kuota 2 kg per bulan, budget Rp180.000.'))
# {"labels": [...], "scores": {...}}Pass one post as plain text, hashtags and emoji included. Replies and whole threads are not what it was trained on.
Want to see what it answers before you get it? Read the Example results
Versions
Versions
Every version stays downloadable once you own the model. A version id names exactly the bytes you download.
v1.0RecommendedONNX INT867.2 MBReleased Oct 16, 2026
Feedback
Need something changed in this model?
Ask for a new label or language, tell us where it misses on your data, get help running it, or report a bug. A person reads every message and replies by email.
Find the model for your task.
Search by what it has to do, read real example results, and download it to run on your own CPU — from $9 during early bird.