cd /news/artificial-intelligence/lower-token-usage-through-representa… · home topics artificial-intelligence article
[ARTICLE · art-67691] src=github.com ↗ pub= topic=artificial-intelligence verified=true sentiment=· neutral

Lower token usage through representation engineering

A new technique called Prompt+Steer, which combines prompting with activation steering, reduces output tokens by an additional ~13% beyond prompting alone on the CodeXGLUE code-to-text task, according to researchers testing the Qwen2.5-Coder-7B-Instruct model. The caveman package, which uses prompting to cut roughly 65% of output tokens, served as the baseline, and the combined method achieved an average of 49.3 tokens per response while maintaining 90-95% correctness.

read11 min views1 publishedJul 21, 2026
Lower token usage through representation engineering
Image: source

The caveman package has become very popular. Many engineers want their coding agent to drop the filler and answer concisely. Its motto is short and to the point: "why use many token when few token do trick"?

By prompting the model to trim definite articles and favor fragment-style answers, the package cuts roughly 65% of output tokens while keeping code and technical content intact.

Here, we ask whether activation steering can push the correctness and conciseness of these outputs even further. Our setup follows the line of work on activation steering for instruction following studied by Stolfo et al. [1], among others, applied to a practical use case: the caveman

skill for agent-based development.

The model we test is Qwen2.5-Coder-7B-Instruct

, and the thing we are trying to compress is its natural-language explanations of code. Prompting alone can already shorten these explanations; the real question is whether steering adds anything on top of prompting, and whether it can do so without degrading the explanation itself. Overall, our results support Prompt+Steer outperforming the Prompt method alone.

We test four methods:

1. Base — A neutral prompt: no conciseness instruction, no steering. This is our reference point for what the model does when left to its own devices.

2. Prompt — The caveman "full" mode instruction, reproduced word for word from caveman's skills/caveman/SKILL.md

. We keep the opening line, the Persistence section, the Rules, the no-self-reference paragraph, and the Pattern line (assembled in model_common.CAVEMAN_SUFFIX

).

3. Steer — The diff-in-means steering vector, added at inference time on top of the Base prompt. There is no conciseness instruction in the prompt, so the only pressure toward brevity comes from the steering vector itself; this isolates what steering does on its own. The vector is computed by difference-in-means, as in Arditi et al. [3]: the mean residual-stream activation over a set of concise ("caveman") generations minus the mean over ordinary verbose ones, taken at a chosen layer. 1

4. Prompt+Steer — The same steering vector, added at inference time, but layered on top of the Prompt condition. This is our primary comparison, and it targets the central question directly.

Condition Avg tokens Fully correct
Base 150.0 (censored — see below) 90-95%
Prompt 56.8 90-95%
Steer alone 149.9 90-95%
Prompt+Steer
49.3
90-95%

Steering on top of the prompt gets a further ~13% token reduction beyond prompting alone. Constant steering alone results in 149.9 tokens, which makes it indistinguishable from Base; the coefficient was calibrated specifically for the combined regime, not as a standalone replacement for the instruction. This matches a pattern we observed at higher coefficients during calibration: difference-of-means steering alone is substantially weaker than prompting.

We set the max token count to 150 for cost and performance reasons. Accordingly, the average token count reported for Base is lower than it would be in a natural setting -- 95% of Base responses hit MAX_NEW_TOKENS

without the model choosing to stop. The most informative comparison is Prompt vs. Prompt+Steer, since both are close to fully natural stopping.

All experiments run on the CodeXGLUE code-to-text task, where the model is asked to explain a function in natural language.

One important preprocessing step: before any code is used as a reference, we strip its docstrings out via AST parsing (src/data_prep.py

). This prevents answer leakage — without it, the reference explanation could bleed into the prompt body and quietly inflate the model's apparent accuracy. Stripping the docstrings keeps the evaluation honest.

We split the corpus into 180 train, 50 dev, and 180 held-out test examples, and report method comparisons on the test set. For correctness, we employ gpt-4o-mini

to evaluate each output explanation, assigning a score of 0 (incorrect), 1 (partially correct), or 2 (completely correct).

The rule from caveman's SKILL.md

is explicit and mechanically checkable: "Drop: articles (a/an/the)... Fragments OK."

Instead of trying to eyeball compliance, we simply did a keyword search counting how often a

, an

, or the

appears despite being told not to. Article usage varies sharply across the four conditions:

Condition Responses containing a/an/the Articles per 100 words
Base 100% 12.68
Steer alone 100% 12.47
Prompt 46.1% 4.27
Prompt+Steer
31.1%
2.48

Clearly, the prompt instruction (model_common.CAVEMAN_SUFFIX

) changes model behavior substantially: articles see a 66% reduction. However, compliance with the specific "drop articles" rule is only partial, and 46% of prompted responses still use one. Steer alone (calibrated for the combined regime, not as a standalone replacement) shows no effect on style either, consistent with its lack of effect on length. Steering on top of the prompt pushes compliance further than the text instruction manages alone.

Overall, we observe the prompted and steered model to use fewer articles, and at a lower rate.

In the cases below, both Prompt

and Prompt + Steer

examples are judged fully correct (correct=2

). The Prompt

response is already article-free, while steering compresses further without dropping explanatory value. Across these five examples, Prompt+Steer cuts token count by 51% on average versus Prompt alone.

initial_step

(CORDIC algorithm)

def initial_step(self, phase, x, y):
    self.x[0] = x
    self.y[0] = y
    self.phase[0] = phase
    if self.MODE == CordicMode.ROTATION:
        if phase > 0.5:
            self.x[0] = -x
            self.phase[0] = phase - 1.0
        elif phase < -0.5:
            self.x[0] = -x
            self.phase[0] = phase + 1.0
    elif self.MODE == CordicMode.VECTORING:
        if x < 0.0 and y > 0.0:
            self.x[0] = -x
            self.y[0] = -y
            self.phase[0] = 1.0
        elif x < 0.0 and y < 0.0:
            self.x[0] = -x
            self.y[0] = -y
            self.phase[0] = -1.0

Prompt:

"Function

initial_step

sets initial values for coordinatesx

,y

, and phase. Depending onMODE

, it adjusts these values based on specific conditions. If in rotation mode, it flipsx

and adjusts phase if outside [-0.5, 0.5]. In vectoring mode, it flips bothx

andy

and sets phase to 1 or -1 based on quadrant."

Prompt+Steer:

"Set initial values for

x

,y

, andphase

. Adjust based onMODE

and input values. Continue with next step."

gen

(docs build)

def gen(skipdirhtml=False):
    docs_changelog = 'docs/changelog.rst'
    check_git_unchanged(docs_changelog)
    pandoc('--from=markdown', '--to=rst', '--output=' + docs_changelog, 'CHANGELOG.md')
    if not skipdirhtml:
        sphinx_build['-b', 'dirhtml', '-W', '-E', 'docs', 'docs/_build/dirhtml'] & FG
    sphinx_build['-b', 'html', '-W', '-E', 'docs', 'docs/_build/html'] & FG

Prompt:

"Function

gen

generates documentation. It first checks ifdocs/changelog.rst

is unchanged usingcheck_git_unchanged

. If unchanged, it convertsCHANGELOG.md

todocs/changelog.rst

using Pandoc. Then, based onskipdirhtml

, it builds HTML and optionally dirHTML documentation using Sphinx."

Prompt+Steer:

"Function

gen

generates documentation. Skips directory HTML build if specified. Converts Markdown changelog to RST. Builds Sphinx HTML and dirHTML outputs."

Uninstall

(ADB package removal)

def Uninstall(self, package_name, keep_data=False, timeout_ms=None):
    cmd = ['pm uninstall']
    if keep_data:
        cmd.append('-k')
    cmd.append('"%s"' % package_name)
    return self.Shell(' '.join(cmd), timeout_ms=timeout_ms)

Prompt:

"Uninstalls specified app. Removes it from device. Optionally keeps user data. Uses

pm uninstall

command. Passes package name. Adds-k

flag if keeping data. Executes viaShell

method. Waits up totimeout_ms

. Returns result of uninstall operation."

Prompt+Steer:

"Uninstalls app. Removes it from device. Keeps data if specified. Runs command. Waits for completion. Returns result."

_call

(HTTP wrapper with 401 handling)

def _call(self, path, method, body=None, headers=None):
    try:
        resp = self.http.do_call(path, method, body, headers)
    except http.HTTPError as err:
        if err.status == 401:
            raise PermissionError('Insufficient permissions to query ' + '%s with user %s :%s' % (path, self.user, err))
        raise
    return resp

Prompt:

"Function

_call

makes HTTP request. Takespath

,method

, optionalbody

, andheaders

. Callsself.http.do_call

with these parameters. If HTTP error occurs, checks status code. If 401, raisesPermissionError

with message about insufficient permissions. Otherwise, re-raises original error. Returns response from HTTP call otherwise."

Prompt+Steer:

"Function

_call

sends HTTP request. Takespath

,method

, optionalbody

, andheaders

. Tries sending request. If gets401

error, raisesPermissionError

. Otherwise, returns response."

callgraph

(static call-graph builder)

def callgraph(G, stmt_list):
    func_list = []
    for stmt in stmt_list:
        try:
            G.add_node(stmt.head.ident.name)
            func_list.append(stmt)
        except:
            pass
    for func in func_list:
        assert isinstance(func, node.function)
        func_name = func.head.ident.name
        for s in node.postorder(func):
            if s.__class__ is node.funcall and s.func_expr.__class__ is node.ident:
                G.add_edge(func_name, s.func_expr.name)

Prompt:

"Function

callgraph

takes graphG

and list of statementsstmt_list

. It adds nodes for functions found instmt_list

to graphG

. Then it iterates over these functions, adding edges to graphG

for each function call within them. This helps visualize function calls in code structure."

Prompt+Steer:

"Function

callgraph

takes graphG

and list of statementsstmt_list

. It adds nodes for functions found instmt_list

and connects nodes with edges representing function calls."

We chose the steering coefficient by sweeping (layer, coefficient) pairs on the development set — 20 configurations across 50 dev examples — and discarding any that produced degenerate, repetitive output. The full grid (src/sweep_dev.py

, src/judge_sweep.py

, src/analyze_sweep.py

) shows why simply picking the most aggressive non-degenerate configuration is unsafe. Under constant steering, correctness holds at 90–95%+ for coefficients 6–12 at layers 14 and 18, then drops sharply past a coefficient of roughly 20, falling to 40–65%. We select layer 14, coefficient 6: the point that gives up a little token reduction in exchange for correctness.

This tradeoff is reflected in the prior literature. Stolfo et al. [1] report the same direction on IFEval length instructions — larger steering weights c

yield increasingly concise outputs (their Figure 5a, they have c ∈ {0, 5, 10, 20, 40}

). They note that steering degraded generation quality in a few cases.

Heyman & Vandeputte [2] give a mechanistic explanation. A real prompt's influence varies sharply by token position, but a constant coefficient applies the same intervention to every position, whether or not that position needs it.

Constant steering is therefore prone to oversteering. Once the coefficient exceeds what any single position calls for, the target attribute keeps moving in the intended direction while coherence collapses. Their fix, Prompt Steering Replacement, learns a token-specific coefficient instead of a constant one.

Overall, conciseness and correctness seem to trade off against one other: pushing the coefficient for shorter responses usually costs correctness or intelligibility. But these experiments show that activation steering for instruction following can keep responses short without sacrificing their explanatory value.

  • This same approach could be applied to any open model, most easily through transformers

. - As seen above, Prompt Steering Replacement (Heyman & Vandeputte) likely further improves conciseness and adherence to instructions.

  • The task is code explanation only. This mirrors the use case within Caveman and popular for code assistant usage as a whole.

Please connect with me on LinkedIn if you found this interesting or useful! Or check out my other projects here.

Everything in src/data_prep.py

, src/judge*.py

, and src/analyze*.py

can run locally — no GPU needed. The GPU-bound steps (steering_const.py

, sweep_dev.py

, generate.py

) run on a rented GPU pod via infra/run_gpu_pipeline.sh

(or invoked directly, as when re-running just one step).

python3 src/data_prep.py                        # local — data/{train,dev,test}.jsonl

bash infra/setup_runpod.sh
python3 src/steering_const.py                   # -> results/const_steer_{config.json,directions.pt}
python3 src/sweep_dev.py                        # -> results/sweep_dev.jsonl (all grid configs, dev)

python3 src/judge_sweep.py                      # -> results/judged_sweep_dev.jsonl (needs openai.key)
python3 src/analyze_sweep.py                    # -> results/summary_sweep_dev.json, plot

python3 src/generate.py --split test            # -> results/generations_test.jsonl

python3 src/judge.py --split test               # -> results/judged_test.jsonl (needs openai.key)
python3 src/analyze.py --split test             # -> results/summary_test.json, summary_plot_test.png

[1] Alessandro Stolfo, Vidhisha Balachandran, Safoora Yousefi, Eric Horvitz, Besmira Nushi. "Improving Instruction-Following in Language Models through Activation Steering." arXiv:2410.12877. https://arxiv.org/abs/2410.12877

[2] Geert Heyman, Frederik Vandeputte. "Steer Like the LLM: Activation Steering that Mimics Prompting." arXiv:2605.03907. https://arxiv.org/abs/2605.03907

[3] Andy Arditi, Oscar Obeso, Aaquib Syed, Daniel Paleka, Nina Panickssery, Wes Gurnee, Neel Nanda. "Refusal in Language Models Is Mediated by a Single Direction." arXiv:2406.11717. https://arxiv.org/abs/2406.11717

[4] Alexander Matt Turner, Lisa Thiergart, Gavin Leech, David Udell, Juan J. Vazquez, Ulisse Mini, Monte MacDiarmid. "Activation Addition: Steering Language Models Without Optimization." arXiv:2308.10248. https://arxiv.org/abs/2308.10248

[5] Andy Zou, Long Phan, Sarah Chen, James Campbell, Phillip Guo, Richard Ren, Alexander Pan, Xuwang Yin, et al. "Representation Engineering: A Top-Down Approach to AI Transparency." arXiv:2310.01405. https://arxiv.org/abs/2310.01405

[6] Kenneth Li, Oam Patel, Fernanda Viégas, Hanspeter Pfister, Martin Wattenberg. "Inference-Time Intervention: Eliciting Truthful Answers from a Language Model." arXiv:2306.03341. https://arxiv.org/abs/2306.03341

[7] Nina Rimsky, Nick Gabrieli, Julian Schulz, Meg Tong, Evan Hubinger, Alexander Matt Turner. "Steering Llama 2 via Contrastive Activation Addition." arXiv:2312.06681. https://arxiv.org/abs/2312.06681

[8] Samuel Marks, Max Tegmark. "The Geometry of Truth: Emergent Linear Structure in Large Language Model Representations of True/False Datasets." arXiv:2310.06824. https://arxiv.org/abs/2310.06824

Footnotes #

This is a deliberately simple construction, but it has a long lineage in the interpretability literature — activation addition (Turner et al. [4]), representation engineering (Zou et al. [5]), inference-time intervention (Li et al. [6]), contrastive activation addition (Rimsky et al. [7]), and mass-mean probing (Marks & Tegmark [8]) all build steering or probing directions from contrasts between activations. While the resulting vector is model- and prompt-specific, extracting one is cheap and well-tooled: libraries such as

andrepeng

can reduce it to a few lines.steering-vectors

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @qwen2.5-coder-7b-instruct 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/lower-token-usage-th…] indexed:0 read:11min 2026-07-21 ·