Idiomatic Julia code in AI generated code

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 very complex, sonnet if the fix is easy and well described. 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.