Replace Asterisk's app_amd with VM Hunter: an EAGI client that streams the first seconds of the call to a speech-based detector and sets AMDSTATUS and AMDCAUSE the way your dialplan already expects.
Asterisk's app_amd decides from timing. It measures the initial silence, the length of the greeting, the silence after it and the number of words, against the thresholds in amd.conf. Those thresholds are a guess about how people and machines sound, and real calls break them in both directions: a person who pauses after "Hello" reads as a machine, and a voicemail greeting that opens with a name reads as a person. Operators who measure it typically find 15 to 20% of live answers misclassified.
VM Hunter decides from what is said. It transcribes the first two seconds, recognises voicemail wording, carrier prompts and call screening, and still runs tone and silence analysis for beeps, SIT tones and dead air. The Asterisk integration is one script and one dialplan line.
| app_amd | VM Hunter | |
|---|---|---|
| Input | Silence and word timing from amd.conf thresholds | Transcript of the first two seconds, plus tone and energy analysis |
| AMDSTATUS values | HUMAN, MACHINE, NOTSURE, HANGUP | HUMAN, MACHINE (plus CALLGUARD and FAILED in AMDSTATUS_RAW) |
| AMDCAUSE values | INITIALSILENCE, LONGGREETING, MAXWORDS, TOOLONG, HUMAN | HUMAN, MACHINE, MACHINE_BEEP, MACHINE_STATIC, DISCONNECT, INITIALSILENCE, MAXWORD, CALLGUARD_PHRASE:<phrase> |
| Short answers ("Hello?") | Depends on silence thresholds; often MACHINE | HUMAN when the speaker stops and waits |
| Greetings that start like a person | HUMAN | MACHINE once the voicemail wording follows |
| Call screening | Not detected | Detected and labelled |
| Disconnected numbers | Not detected | SIT tones labelled DISCONNECT |
| Per-call evidence | None | Transcript, reason and audio in the portal |
Where you call AMD() today, call the client with EAGI instead and branch on the same variables:
exten => s,n,EAGI(/var/lib/asterisk/agi-bin/vmhunter.agi.py,${CALLERID(num)})
exten => s,n,GotoIf($["${AMDSTATUS}"="HUMAN"]?agent:hangup)
exten => s,n(agent),Queue(sales)
exten => s,n(hangup),Hangup()Play silence, not ringback or a prompt, while the script runs. The API key comes from an environment variable Asterisk can see. Full steps are in the Asterisk and VICIdial guide; the script is open source on GitHub.
For everything else, the way to decide is to measure: run both on the same list for a day and compare the dispositions against the recordings.
The free plan includes 5,000 calls a month, enough to run VM Hunter next to your current AMD for a day and compare the dispositions. No card needed.