All posts
    Engineering

    A 16-Line Code Check Beat Automated Prompt Tuning

    AltSlate LabsOctober 24, 20268 min read

    We tested Harness², a new method that automatically rewrites the instructions around an AI agent, on a chatbot that takes scam reports. The chatbot ran on a small, cheap model. Every rewritten version, automatic or by hand, made it worse. What fixed it was 16 lines of ordinary code that refuse to save an incomplete record. The automatic method worked out the cause on its own, but couldn't turn that into a fix that held up. Here is what happened, and what we would do on the next small-model chatbot.

    13% → 53%
    Fully correct records
    after adding a 16-line check with no AI in it
    63–81%
    Chats cut short by rewritten prompts
    the agent saved after its first question
    ≈ $16.5
    Spent on the AI doing the rewriting
    both rounds, 24 tuning tasks

    01 — the setup

    A scam-report chatbot we could score exactly

    A fraud-help desk takes reports over chat. The agent must collect a checklist and then save the record once. Some items are always needed: name, phone, type of scam, date, amount lost, how they paid and how the scammer reached them. Others depend on the answers. A UPI payment needs the UPI ID and transaction reference; a card payment needs the bank, the last four digits and whether the card is blocked.

    There are two safety messages too. If the money went today or yesterday, the agent must tell the person to call the 1930 cyber-fraud helpline. If they paid by card and haven't blocked it, it must tell them to. Customers tell their story out of order, mix Hindi and English, say "last Friday", and sometimes correct their phone number halfway through.

    The agent was Qwen3-4B, a small open model of the kind you would run cheaply in production. A second open model played the customers, each built from a hidden profile of true answers, so we could score every saved record exactly. We report the share of items that were right, and the share of chats where the whole record was right, safety messages included.

    02 — the method we tested

    Harness² rewrites an agent's instructions without seeing a score

    The harness is everything wrapped around a fixed model: its instructions, notes, helper scripts and checks. Harness² improves it automatically. For each practice task it runs the agent, has a stronger AI propose two edits, tries each one, and merges them into a new version. It never sees a score; it judges only by reading what the agent did. After each task it writes down a lesson for the next.

    That is appealing, because most real chatbots have no answer key. We used Claude Sonnet 5.5 as the stronger AI, ran 12 practice customers, then tested each version on 45 new customers. To see whether the method's machinery adds anything, we also gave Claude a single editing session, once on its own and once after reading 24 chat transcripts.

    03 — first result

    Every rewritten prompt made the agent worse

    The starting point was one line: "You are a helpful assistant at a fraud-help desk." Every rewrite lost to it, including the prompt we wrote ourselves, both Claude sessions and Harness². Items right fell from 82% to between 45% and 60%, against run-to-run noise of about 3 points.

    Here is a complete chat under the version Claude wrote after reading the transcripts:

    Customer: Hello? I need to report a scam. I think I've been cheated.

    Agent: Hello, I'm here to help. Can you please share your full name and 10-digit phone number?

    Customer: My name is Pooja Yadav. My mobile number is 7747885775.

    Agent saves: {"reporter_name": "Pooja Yadav", "reporter_phone": "7747885775"}

    The chat ends there. The prompt told the agent to ask one or two questions at a time, which is good advice for a friendly chat. But once the small model holds an answer or two, it treats the job as done and saves. The polite, step-by-step style that suits a person made early saving more likely. The one-line prompt escaped by accident: with no guidance, it pasted the whole checklist into its first message.

    saved after 1st questionsaved laternever savedOne-line prompt11%88%Our handwritten prompt63%36%Claude, after reading chats79%19%Harness², after 12 tasks81%19%One-line + 16-line check93%
    How each chat ended, 45 new customers. Rewritten prompts made the agent save after its first question in 63–81% of chats. With the code check (bottom row), early saving almost disappears.

    04 — the diagnosis

    The automatic method found the cause on its own

    Harness² never saw a score, yet its lesson notes named the real problem. After six tasks it wrote, in effect: three differently worded "don't save early" rules all failed, so stop rewording the rule and add a check that doesn't depend on the model's own judgment. It also marked its confidence as low where the evidence was thin. That is a good diagnosis, honestly reported.

    But we had given it no way to build such a check. Our setup had no hook that could stop a save, and a script the agent must choose to run is still just another instruction. So its later versions kept adding more words. That limit was our choice: the original method allows plugins that can intercept an agent's actions, and we had left them out.

    05 — the fix

    A check in code fixed it, and the plainest check did best

    In a second round we added a submit check: a small script that runs on every save, outside the model's control. If it rejects the record, the agent gets the reason back as a message and the chat carries on. Harness² and both Claude sessions were told about it and could write their own. We also wrote a deliberately plain one. It only rejects records with a needed item missing.

    Customertells their storyAgentsmall 4B modelSubmit check16 lines, no AIRecord savedonce, completechatsaveokREJECT: still missing scammer_number.Ask the customer, then save again.
    The submit check. The agent cannot skip it. A rejection goes back to the agent as a message naming what is missing, so the next step is obvious: ask the customer.

    Early saving nearly vanished, and fully correct records rose for every version. The biggest jump came from the version with no AI in the loop at all: the one-line prompt plus our plain check, from 13% to 53%. To be fair, we wrote that check after seeing the failure, so treat it as a ceiling rather than a level contest.

    0%20%40%60%One-line prompt, no check13%One-line + 16-line check53%Claude, one session33%Claude, after reading chats42%Harness², after 6 tasks43%Harness², after 12 tasks21%
    Fully correct records on 45 new customers, second round. Every version except the top row had a submit check. Harness² matched one Claude session after 6 practice tasks, then got worse after 12.

    Harness² did not stand out. After 6 practice tasks it was level with one Claude session that had read 24 transcripts. After 12 it was clearly worse, as it had been in the first round. Inside each task, its merged version beat the starting one on 6 of 12 customers and beat its own better single edit on only 3. Merging two edits, each judged from one chat, tended to drop the one that worked.

    06 — the new failure

    Stricter checks trapped the agent in a loop

    The check brought a failure of its own: chats that never save at all. Under the plain check that was 3%. Under the checks Harness² wrote, it was 18–21%. Their checks tested more than whether items were present, and two rules caused most of the loops.

    One demanded the amount as a number, but our tool told the model every field is text, so it kept sending "8000" in quotes. The other said to remove items that don't apply. The model fills those with blanks, the check counted blanks as present, and the model could not reliably delete them. In one chat it got the same rejection three times, replied "I have removed all non-applicable fields as per policy", sent the same record again, and finally said goodbye with nothing saved.

    We share the blame here. Both rules came straight from the desk procedure we wrote, which asks for the amount in whole rupees and says to leave out items that don't apply. Harness² enforced our procedure faithfully. The procedure clashed with our own tool definition, and a small model could not satisfy both. A check that asks for more than the model can produce turns into a trap.

    07 — what this does not show

    Limits we want to be clear about

    It is one small study. One task, one small agent model, simulated customers and 12 practice tasks. The second round was designed after we saw the first, so it is a follow-up, not a test we planned in advance.

    We ran Harness² in its simplest setting, with one candidate per task, and with a different stronger AI than the original authors used. It may do better with more candidates per task, on other tasks, or with larger agent models. Our result covers a small model on a structured form.

    08 — practical lessons

    Write the check first and the prompt second

    A small model will not reliably follow an instruction to wait. A few lines of code that refuse an incomplete record will.

    Put every irreversible action behind a code check. Saving a record, sending a message, making a payment: if the agent can do it early, a small model eventually will. Rewording the instruction did not help in any of our versions.

    Keep the check lenient. Reject only what is missing. Ignore blanks, and accept any format your tool allows. Every extra rule is a new way for the agent to loop.

    Make the rejection say what to do next. "Still missing: scammer_number. Ask the customer" gives the model one clear step.

    Test any new prompt against a one-line baseline. A friendlier, step-by-step prompt made our agent worse. Without a baseline we would not have known.

    Use AI review to find the problem, and scored tests to pick the fix. The automatic method read the chats well and named the right cause. Choosing which edit to keep was where it did no better than a coin flip.