Campaign Intelligence Agent
Multi-agent triage for inbound X mentions. Routine questions get a retrieval-grounded answer, judgment calls go to a human on Telegram, and posting is never a tool the model can call.
- Status
- Delivered, now offline
- Role
- Client build for a political consultant
- Stack
- Multi-agent, RAG, Vector store, X API, Telegram Bot API, Append-only JSONL
Problem
A political consultant's X accounts get a steady stream of mentions. Most are routine questions with known answers. A few need a person. Drafting replies is a good agent task. Letting an agent post is not.
Architecture
An orchestrator agent watches multiple accounts and triages each inbound mention.
Routine questions go to a retrieval-grounded sub-agent. It answers from a vector store of vetted reference material, so a reply is built from sources the client approved rather than from whatever the model remembers. Judgment calls skip drafting and escalate to a human. A separate scheduled agent runs sentiment analysis across the mention stream.
Drafts go out to Telegram. post_tweet is not registered as a tool. The model has no way to call it and cannot be argued into calling it, because it is not in the tool list at all. Posting lives in a separate code path that only a human reaction on the Telegram message can trigger.
Every draft, escalation, approval, rejection, and post appends to a JSONL audit log. Append only. That log is the record of what the system did and who approved it.
What's interesting
The safety property comes from the tool schema, not the prompt. A prompt-level guardrail is a request. An absent tool is a fact. No jailbreak reaches a function that was never exposed in the first place.
Triage decides what the model is allowed to attempt. Grounding the routine answers and routing the rest to a person keeps the agent working only where being wrong is cheap.
Running approval through Telegram matters for a duller reason. It puts the gate on a phone, a couple of seconds away, which is the only reason a human-in-the-loop step does not get quietly bypassed once it becomes inconvenient.
Status
Delivered. It ran against the client's live accounts for the length of the engagement and is now offline. Client work, so the client stays unnamed.