So I tried oh-my-pi with Qwen3.6-35b-a3b and it was worse

One of the selling points was that its edit mode was more reliable. Actually, my model struggled a lot and would routinely end up with garbled files. Whereas in pi-coding-agent the edits pass about 80-90% of the time and when they fail the file remains untouched.

Also, it seems to inject about 25K tokens of context? Which is a lot on a small local model.

Also it would end up with 60K+ of context after compaction, which is still a lot.

I liked how sleek the UI looked though especially with a Nerd font. But it's not better.

reddit.com
u/Qxz3 — 3 days ago
▲ 7 r/LocalLLM+1 crossposts

How I'm using local models from real-world coding

Just want to share since after many attempts over the past year, I finally have a setup I kinda like and does useful work for me.

I only have 32GB of RAM and a 4070 8GB (laptop), just very ordinary hardware. I found that Qwen3.6-35B-A3B runs reliably at about 15 tokens per second*, which is slow but enough to do useful work while I do other things.

I treat this local model as a "small coding agent", only capable of doing very well-scoped tasks.

For deeper code review, task creation and organization, I currently use GLM 5.2 on openrouter. It costs under 1$ to have this much smarter model comprehensively look at my codebase and generate a detailed task plan for Qwen3.6 to execute on. This means the setup is not 100% local. It's about a 90%-10% split local-cloud, but it's dirt cheap to run.

Concretely, I run pi-coding-agent and llama-server** (from llama.cpp). I review every change Qwen3.6 produces. When I notice the small model gets stuck on some aspects of coding, I do a post-mortem with it to determine where its knowledge gaps lie and I add useful tips to a README file that the next agent picks up on. This really helps, you can see code quality improve and the model not getting stuck as much.

Feel free to ask questions.

* on battery or low-power charging. At full power, around 19 t/s.

** llama-server config:

llama-server -m "C:\***\models\unsloth\Qwen3.6-35B-A3B-GGUF\Qwen3.6-35B-A3B-UD-IQ4_NL_XL.gguf" -c 100000 -fa on -t 20 -b 4096 -ub 4096 --no-mmap --jinja -ctk q8_0 -ctv q8_0 -ngl 99 --n-cpu-moe 38 --no-mmproj --chat-template-kwargs '{"preserve_thinking": true}' --temp 1.0 --top-p 0.95 --top-k 64

reddit.com
u/Qxz3 — 6 days ago

Pro Radii is such a banger

5:48 is such an epic climax to the buildup that starts around 4:06 (arguably at 3:31).

https://youtu.be/qqI5VmT9YDQ?si=nQumMSEcmhZbWaFi&t=246

It's basically dance floor music but at the same time it sounds like nothing you've ever heard.

The song loses a bit of steam after but these 2-3 minutes have to be some of favorites out of their entire discography.

u/Qxz3 — 20 days ago

Gemma 4 printing <channel|> messages in output, no thinking

Trying to use Gemma 4 in pi-coding-agent, specifically the E4B model.

Model: unsloth/gemma-4-e4b-it Q4_K_XL
Prompt: default Jinja template Environment: LM Studio

We see \"<channel|>\" at the end of some messages, suggesting an issue with the template. Also no thinking apparently, nothing appears in grey text.

What could be the problem? Here's the template as it appears in LM Studio:

{%- macro format_type_argument(type_value) -%}
    {%- if type_value is string -%}
        {{- '<|"|>' + (type_value | upper) + '<|"|>' -}}
    {%- elif type_value is iterable -%}
        [
        {%- for item in type_value -%}
            <|"|>{{- item | upper -}}<|"|>
            {%- if not loop.last %},{% endif -%}
        {%- endfor -%}
        ]
    {%- else -%}
        {{- format_argument(type_value) -}}
    {%- endif -%}
{%- endmacro -%}
{%- macro format_parameters(properties, required) -%}
    {%- set standard_keys = ['description', 'type', 'properties', 'required', 'nullable'] -%}
    {%- set ns = namespace(found_first=false) -%}
    {%- for key, value in properties | dictsort -%}
        {%- set add_comma = false -%}
        {%- if key not in standard_keys -%}
            {%- if ns.found_first %},{% endif -%}
            {%- set ns.found_first = true -%}
            {{ key }}:{
            {%- if value['description'] -%}
                description:<|"|>{{ value['description'] }}<|"|>
                {%- set add_comma = true -%}
            {%- endif -%}
            {%- if value['nullable'] %}
                {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
                nullable:true
            {%- endif -%}
            {%- if value['type'] and ('string' in value['type'] or 'STRING' in value['type']) -%}
                {%- if value['enum'] -%}
                    {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
                    enum:{{ format_argument(value['enum']) }}
                {%- endif -%}
            {%- elif value['type'] and ('object' in value['type'] or 'OBJECT' in value['type']) -%}
                ,properties:{
                {%- if value['properties'] is defined and value['properties'] is mapping -%}
                    {{- format_parameters(value['properties'], value['required'] | default([])) -}}
                {%- elif value is mapping -%}
                    {{- format_parameters(value, value['required'] | default([])) -}}
                {%- endif -%}
                }
                {%- if value['required'] -%}
                    ,required:[
                    {%- for item in value['required'] | default([]) -%}
                        <|"|>{{- item -}}<|"|>
                        {%- if not loop.last %},{% endif -%}
                    {%- endfor -%}
                    ]
                {%- endif -%}
            {%- elif value['type'] and ('array' in value['type'] or 'ARRAY' in value['type']) -%}
                {%- if value['items'] is mapping and value['items'] -%}
                    ,items:{
                    {%- set ns_items = namespace(found_first=false) -%}
                    {%- for item_key, item_value in value['items'] | dictsort -%}
                        {%- if item_value is not none -%}
                            {%- if ns_items.found_first %},{% endif -%}
                            {%- set ns_items.found_first = true -%}
                            {%- if item_key == 'properties' -%}
                                properties:{
                                {%- if item_value is mapping -%}
                                    {{- format_parameters(item_value, value['items']['required'] | default([])) -}}
                                {%- endif -%}
                                }
                            {%- elif item_key == 'required' -%}
                                required:[
                                {%- for req_item in item_value -%}
                                    <|"|>{{- req_item -}}<|"|>
                                    {%- if not loop.last %},{% endif -%}
                                {%- endfor -%}
                                ]
                            {%- elif item_key == 'type' -%}
                                type:{{ format_type_argument(item_value) }}
                            {%- else -%}
                                {{ item_key }}:{{ format_argument(item_value) }}
                            {%- endif -%}
                        {%- endif -%}
                    {%- endfor -%}
                    }
                {%- endif -%}
            {%- endif -%}
            {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
            type:{{ format_type_argument(value['type']) }}}
        {%- endif -%}
    {%- endfor -%}
{%- endmacro -%}
{%- macro format_function_declaration(tool_data) -%}
    declaration:{{- tool_data['function']['name'] -}}{description:<|"|>{{- tool_data['function']['description'] -}}<|"|>
    {%- set params = tool_data['function']['parameters'] -%}
    {%- if params -%}
        ,parameters:{
        {%- if params['properties'] -%}
            properties:{ {{- format_parameters(params['properties'], params['required']) -}} },
        {%- endif -%}
        {%- if params['required'] -%}
            required:[
            {%- for item in params['required'] -%}
                <|"|>{{- item -}}<|"|>
                {{- ',' if not loop.last -}}
            {%- endfor -%}
            ],
        {%- endif -%}
        {%- if params['type'] -%}
            type:{{- format_type_argument(params['type']) -}}}
        {%- endif -%}
    {%- endif -%}
    {%- if 'response' in tool_data['function'] -%}
        {%- set response_declaration = tool_data['function']['response'] -%}
        ,response:{
        {%- if response_declaration['description'] -%}
            description:<|"|>{{- response_declaration['description'] -}}<|"|>,
        {%- endif -%}
        {%- if response_declaration['type'] and ('object' in response_declaration['type'] or 'OBJECT' in response_declaration['type']) -%}
            type:{{- format_type_argument(response_declaration['type']) -}}}
        {%- endif -%}
    {%- endif -%}
    }
{%- endmacro -%}
{%- macro format_argument(argument, escape_keys=True) -%}
    {%- if argument is string -%}
        {{- '<|"|>' + argument + '<|"|>' -}}
    {%- elif argument is boolean -%}
        {{- 'true' if argument else 'false' -}}
    {%- elif argument is mapping -%}
        {{- '{' -}}
        {%- set ns = namespace(found_first=false) -%}
        {%- for key, value in argument | dictsort -%}
            {%- if ns.found_first %},{% endif -%}
            {%- set ns.found_first = true -%}
            {%- if escape_keys -%}
                {{- '<|"|>' + key + '<|"|>' -}}
            {%- else -%}
                {{- key -}}
            {%- endif -%}
            :{{- format_argument(value, escape_keys=escape_keys) -}}
        {%- endfor -%}
        {{- '}' -}}
    {%- elif argument is iterable -%}
        {{- '[' -}}
        {%- for item in argument -%}
            {{- format_argument(item, escape_keys=escape_keys) -}}
            {%- if not loop.last %},{% endif -%}
        {%- endfor -%}
        {{- ']' -}}
    {%- else -%}
        {{- argument -}}
    {%- endif -%}
{%- endmacro -%}
{%- macro strip_thinking(text) -%}
    {%- set ns = namespace(result='') -%}
    {%- for part in text.split('<channel|>') -%}
        {%- if '<|channel>' in part -%}
            {%- set ns.result = ns.result + part.split('<|channel>')[0] -%}
        {%- else -%}
            {%- set ns.result = ns.result + part -%}
        {%- endif -%}
    {%- endfor -%}
    {{- ns.result | trim -}}
{%- endmacro -%}

{%- set ns = namespace(prev_message_type=None) -%}
{%- set loop_messages = messages -%}
{{ bos_token }}
{#- Handle System/Tool Definitions Block -#}
{%- if (enable_thinking is defined and enable_thinking) or tools or messages[0]['role'] in ['system', 'developer'] -%}
    {{- '<|turn>system\n' -}}

    {#- Inject Thinking token at the very top of the FIRST system turn -#}
    {%- if enable_thinking is defined and enable_thinking -%}
        {{- '<|think|>' -}}
        {%- set ns.prev_message_type = 'think' -%}
    {%- endif -%}

    {%- if messages[0]['role'] in ['system', 'developer'] -%}
        {{- messages[0]['content'] | trim -}}
        {%- set loop_messages = messages[1:] -%}
    {%- endif -%}

    {%- if tools -%}
        {%- for tool in tools %}
            {{- '<|tool>' -}}
            {{- format_function_declaration(tool) | trim -}}
            {{- '<tool|>' -}}
        {%- endfor %}
        {%- set ns.prev_message_type = 'tool' -%}
    {%- endif -%}

    {{- '<turn|>\n' -}}
{%- endif %}

{#- Loop through messages -#}
{%- for message in loop_messages -%}
    {%- set ns.prev_message_type = None -%}
    {%- set role = 'model' if message['role'] == 'assistant' else message['role'] -%}
        {{- '<|turn>' + role + '\n' }}

            {%- if message['tool_calls'] -%}
                {%- for tool_call in message['tool_calls'] -%}
                    {%- set function = tool_call['function'] -%}
                    {{- '<|tool_call>call:' + function['name'] + '{' -}}
                    {%- if function['arguments'] is mapping -%}
                        {%- set ns_args = namespace(found_first=false) -%}
                        {%- for key, value in function['arguments'] | dictsort -%}
                            {%- if ns_args.found_first %},{% endif -%}
                            {%- set ns_args.found_first = true -%}
                            {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
                        {%- endfor -%}
                    {%- elif function['arguments'] is string -%}
                        {{- function['arguments'] -}}
                    {%- endif -%}
                    {{- '}<tool_call|>' -}}
                {%- endfor -%}
                {%- set ns.prev_message_type = 'tool_call' -%}
            {%- endif -%}

            {%- if message['tool_responses'] -%}
                {#- Tool Response handling -#}
                {%- for tool_response in message['tool_responses'] -%}
                    {{- '<|tool_response>' -}}
                    {%- if tool_response['response'] is mapping -%}
                        {{- 'response:' + tool_response['name'] | default('unknown') + '{' -}}
                        {%- for key, value in tool_response['response'] | dictsort -%}
                            {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
                            {%- if not loop.last %},{% endif -%}
                        {%- endfor -%}
                        {{- '}' -}}
                    {%- else -%}
                        {{- 'response:' + tool_response['name'] | default('unknown') + '{value:' + format_argument(tool_response['response'], escape_keys=False) + '}' -}}
                    {%- endif -%}
                    {{- '<tool_response|>' -}}
                {%- endfor -%}
                {%- set ns.prev_message_type = 'tool_response' -%}
            {%- endif -%}

            {%- if message['content'] is string -%}
                {%- if role == 'model' -%}
                    {{- strip_thinking(message['content']) -}}
                {%- else -%}
                    {{- message['content'] | trim -}}
                {%- endif -%}
            {%- elif message['content'] is iterable -%}
                {%- for item in message['content'] -%}
                    {%- if item['type'] == 'text' -%}
                        {%- if role == 'model' -%}
                            {{- strip_thinking(item['text']) -}}
                        {%- else -%}
                            {{- item['text'] | trim -}}
                        {%- endif -%}
                    {%- elif item['type'] == 'image' -%}
                        {{- '\n\n<|image|>\n\n' -}}
                        {%- set ns.prev_message_type = 'image' -%}
                    {%- elif item['type'] == 'audio' -%}
                        {{- '<|audio|>' -}}
                        {%- set ns.prev_message_type = 'audio' -%}
                    {%- elif item['type'] == 'video' -%}
                        {{- '\n\n<|video|>\n\n' -}}
                        {%- set ns.prev_message_type = 'video' -%}
                    {%- endif -%}
                {%- endfor -%}
            {%- endif -%}

        {%- if not (message['tool_responses'] and not message['content']) -%}
            {{- '<turn|>\n' -}}
        {%- endif -%}
{%- endfor -%}

{%- if add_generation_prompt -%}
    {%- if ns.prev_message_type != 'tool_response' -%}
        {{- '<|turn>model\n' -}}
    {%- endif -%}
{%- endif -%}```
reddit.com
u/Qxz3 — 1 month ago

How to force the agent to read AGENTS.md

I have an AGENTS.md file in my project giving essential instructions to the coding agent. I don't want to start every new session with "read AGENTS.md". Should I use a different file name or else how do I get agents to read it before doing anything else in the folder?

u/Qxz3 — 1 month ago
▲ 0 r/LLM

LLMs don't think, they ramble

Typical confused Claude (Sonnet 4.6) revealing how it "thinks" (or rather, doesn't):

>Your procedure requires the two travelers to depart from the midpoint simultaneously — "as a single event" you said. And here's where the issue actually lives: if the two travelers departing is a single event (same place, same time), that part is fine — coincident events are agreed upon by everyone. No simultaneity convention needed there.

>So actually, your construction is more robust than I was crediting. Let me think about where it does or doesn't work...

See how it begins the sentence in a way that leads to an objection:

>And here's where the issue actually lives:

And then midway through it actually has no tokens to complete it coherently, turning it into the incoherent:

>And here's where the issue actually lives: (...) that part is fine

So it is apparent that Claude (and LLMs in general, this is just one example) does not produce coherent arguments or thoughts before writing anything. It merely begins paragraphs and sentences with argument-like introductions, in an effort to guide the sequence of tokens towards a plausible, argument-like completion. If no such argument is actually possible, however, the process fails and turns into gibberish.

reddit.com
u/Qxz3 — 2 months ago