Idiomatic Julia code in AI generated code

I find AI coding tools such as Claude Code incredibly useful, especially when combined with tools like Kaimon.jl. However, I also find that the code they generate is often surprisingly non-idiomatic Julia.

Beyond aesthetics, this has practical consequences. The generated code frequently misses opportunities for classic Julia strengths such as multiple dispatch, leveraging existing package functionality, and introducing concrete types or type information early in the design. Instead, it often produces code that feels more like a direct translation of patterns from Python, JavaScript, or other ecosystems.

How do you deal with this limitation?

Has anyone had success steering these models toward more idiomatic Julia? For example, can we point them at curated examples of “blessed” Julia code, style guides, or particularly well-designed packages that they can learn from and emulate?

In my experience with agentic coding, this is hard to do something about. Ingesting a comprehensive style guide big enough to rid them of Python-isms would take up a good chunk of the context window, which is probably better spent elsewhere.

I recommend two approaches to this:

  • Put a brief list of instructions addressing only the most annoying tendencies in your AGENTS.md
  • Have the agent work in small chunks of work and review each chunk. This way, you can steer it better.

One option which I haven’t tried yet, but maybe could work, is to have a review-julia skill, which has this more comprehensive Julia design guide. You can then point a cheaper agent (e.g. gpt-5.6 luna) to review the bigger agent’s work with that skill.

Edit: FWIW, I do a bunch of agentic coding in Python as well and I also find that agents coding Python have some bad design patterns I repeatedly need to rid my code of. An example that I constantly struggle with is that they prefer to defer checks to where data is used instead of where it’s loaded. E.g. they do

def process_element(d: dict[str, int], key: str)
    value = d.get(key)
    process_1(value)
    process_2(value)
    if value is None:
        raise TypeError("Should not be None")
    ...

def process_1(value: Union[Int, None]):
    if value is None:
        raise TypeError("Should not be None")
    ...

def process_2(value: Union[Int, None]):
    if value is None:
        raise TypeError("Should not be None")
    ...

I’ve read that the idea of separating these models into two, one human language trained, and one computer language trained (with a third to translate between the two), often yields worse results than the monolithic human language one. But for this specific aspect, it does sound like a version of Claude that is tuned more towards (for instance) Julia would be ideal… As unlikely as that sounds…

It would be fantastic if people could share their (currently) most successful Julia-idiomatic related agent-instructions and/or Julia review skill.

Aside from asking agents to do some API documentation, help with some macros, and standardising instructions and prompts. I basically hand wrote all of PortfolioOptimisers.jl until Opus 4.8 came out.

I think i did a pretty good job creating an agentic workflow bit by bit that now works incredibly well. I’m adding a ton of features, fixing bugs, improving the user experience, documenting, etc. Here is a step by step guide of what I would do if i were starting from scratch. I had to go back and redo some stuff that in hindsight could have been avoided. However, you should periodically audit your workflow to make improvements as models change or as you get a better idea of what you want your code to do and look like.

It’s important to note that it’s best if you start with a clearly defined skeleton of your standards and code practices. You can use an AI to work with you to refine them. This should be ongoing as the codebase evolves.

  1. Install GitHub - mattpocock/skills: Skills for Real Engineers. Straight from my .agents directory. · GitHub and plugins/cursor-team-kit/skills/thermo-nuclear-code-quality-review/SKILL.md at main · cursor/plugins · GitHub /grill-with-docs is great for single or 2-session fixes. /wayfinder is extremely OP at large changes, but also works great for smaller stuff.
  2. Run /grill-with-docs in the bare repo. This will ask you a ton of questions to establish a common lexicon and grammar. This is the CONTEXT.md file, which is going to be the first place an agent looks before asking you questions. I think i might break this up into a map where each section contains only its relevant information as it’s getting long.
  3. Set up a STANDARDS.md. To start with you might want to plop your standards directly, but ideally you want it to be an index of where each standard is defined. This should give the agent instructions on how you want things done. Mine has the files it must run tests on, pointers to how i want docstrings written, code subtyped, tests written, etc.
  4. Set up your CLAUDE/AGENTS.md. This establishes general etiquette and points the agents to the places they need to check out for contextual answers and instructions so they can make high quality additions. It also bounds the etiquette, i had claude ping people without my asking and i find that distasteful.
  5. Matt’s skills (step 1) come with an /improve-codebase-architecture skill. Use it as the basis for creating /improve-codebase-security (security issues), /improve-codebase-maintainability (easier maintenance), /improve-codebase-ergonomics (for user experience improvements). You can also use it to modify /thermo-nuclear-code-quality-review so it generates `html` in the same style, or merge the skills into one (i haven’t tried this yet). You should probably do this after all the above files have been created so they know to use them in case they need.
  6. Set up a code quality CI ratchet. I made one that uses CodeComplexity.jl, another that uses JET.jl, another one that sweeps files and additions to ensure their docs are up to date and their code is correct, another that tracks coverage, another that tracks file size. I will probably turn it into a package, as it’s been really useful for improving code quality in general.
  7. Use the best model you have available for any grilling or research session if the task is complex. Opus 5 works great, but Fable 5.1 makes fewer bone-headed moves/asks fewer dumb questions. It can be very noticeable if the task is complex and/or touches many files.
  8. When making a PR run /improve-codebase-architecture and /thermo-nuclear-code-quality-review (or the merged skill). Fix any issues you agree with, tell it not to relitigate things you need for your codebase or deliberate choices you’ve made. Repeat until it starts finding the same things over and over, that maybe you think are worth doing but not just now. Move on to /improve-codebase-security, /improve-codebase-maintenance, and finally /improve-codebase-ergonomics. Each time run each skill and fix issues until it keeps finding the same things. I used to run them in parallel, but i’ve found that they often find the same issues, and by fixing the one higher in the hierarchy, you end up fixing the ones below it. You should use good models for these. The best you have available if you can, but Opus 5 is really good here as well. You can use lesser models for the implementation. I typically use Opus 5 for everything unless the features or fixes are complex. You can repeat the entire loop ad infinitum, but that can get boring, burn through tokens, and give diminishing returns. If you are running up to your reset and haven’t hit your token limits, it never hurts to run these on your entire codebase. They are genuinely awesome at improving it, provided you have the set up i’ve described.

It seems that recent discussions on this forum indicate growing interest in two directions for Julia native language models. The first is pretraining a model from scratch in Julia, as explored in the recent and fairly recent threads by @mantzaris. The second is fine-tuning / post training existing models. I believe, this approach has become even more attractive with the new generation of releases. In particular, Qwen3.8-27B and especially Qwen3.8 Flash Next appear to represent a huge step forward in both reliability and efficiency, although I’d maintain that @Palli’s estimates regarding the feasibility of running genuinely useful workloads on 2GB of VRAM or on a mobile device remain somewhat optimistic. Also Qwen models for various reasons look a bit risky, thus, I sustain again that focusing on i.e. Trinity seems to be probably much safer approach as of now and a great opportunity to practice and to set up an infrastructure. As for your proposals, if I understand them correctly: separation, orchestration, and cross-validation, they resemble a bit what I outlined a few weeks or months ago in my posts here about NeuroREPL. It has turned out that related ideas have already been validated in practice. Examples include the Sakana AI models and the self-improving coding harness behind Prime Agent.