It's not a technical problem, if you steer the LLMs enough and actually review what they do, you can build proper and clean software with them.
It's an offline coding grader. It works well: You ask for a new module, LLM starts spitting out bloated crap, the code score goes down. LLM keep looping until code score is back up.
Not a substitute for human code review, but keeps things within tight guard rails.
I wonder if it just ends up in reward-hacking, or if it actually substantially changes the quality of the code.
Are these static analysis metrics enough on their own to cause a substantial improvement?
I tried setting some constraints as part of my system instruction prompt to prevent God file creation, and it did end up breaking files up, but it would often just create a new type of mess and do it needlessly.
Without the model doing additional reasoning and search for alternative approaches that were better fitted on top as it was doing this file splitting, it didn't actually seem to improve quality at all.
So I'm curious to know if this would just result in more of that, or if it would actually result in different choices. Because there's more to code maintenance than just splitting things up into modules, etc. Like the main part of it that I suspect will not be captured is the part of thinking about the big picture, brainstorming multiple architectural approaches, and reasoning through the best one.
I notice the LLM reasoning things like: "The maintainability score went down, let me look.... I see I've duplicated existing code which already exists in this module...I see this logic could be consolidated".
I have noticed file splitting is a strategy to improve the "score".
In my experience, I've been doing more the architectural guidance. There is also a rules engine which I have not used, but looks pretty interesting:
``` [constraints] max_cycles = 0 max_coupling = "B" max_cc = 25 no_god_files = true
[[layers]] name = "core" paths = ["src/core/"] order = 0
[[layers]] name = "app" paths = ["src/app/"] order = 2
[[boundaries]] from = "src/app/" to = "src/core/internal/" reason = "App must not depend on core internals" ```