Having spent considerable time evaluating Le Chat (specifically the `codestral-latest` model via their API) for generating boilerplate and architectural skeletons, I've arrived at a conclusion that feels contradictory on its surface. The model's raw code generation, particularly for well-trodden paths in distributed systems (think gRPC service stubs, CRUD handlers, or idempotency wrappers), is competent and often idiomatically sound. However, its suggestions for *formatting and code organization* are frequently atrocious and would introduce significant maintainability debt if followed.
The issue isn't with simple indentation. It's with the architectural-level formatting recommendations. For instance, when prompted to outline a project structure for an event-sourced aggregate with a CQRS read model, Le Chat will correctly identify the necessary components. Yet, its proposed file layout and module boundaries often violate fundamental separation of concerns. It might suggest placing command handlers, domain entities, and projection logic in the same monolithic package, defeating the entire purpose of a clean architecture. The code *within* each file might be syntactically correct, but the structural guidance is poor.
Consider this example prompt and output fragment:
**Prompt:**
"Provide a Go package layout for a basic event-sourced bank account, using aggregate, events, and a PostgreSQL event store."
**Typical Le Chat Suggestion:**
```plaintext
project/
├── main.go
├── account/
│ ├── account.go # Aggregate struct + logic
│ ├── command.go # Command definitions
│ ├── event.go # Event definitions
│ ├── store.go *// Event store interface*
│ ├── postgres_store.go *// PostgreSQL implementation*
│ └── projection.go *// CQRS projection logic*
```
This is a problematic structure. The projection logic, which is a read-model concern, is colocated with the write-model aggregate. The store interface and its concrete implementation are in the same package, tightly coupling the domain to infrastructure. A more appropriate layout, following DDD and Hexagonal patterns, would be:
```plaintext
project/
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── domain/
│ │ └── account/
│ │ ├── aggregate.go
│ │ ├── command.go
│ │ └── event.go
│ ├── application/
│ │ └── commandhandlers/
│ ├── infrastructure/
│ │ ├── eventstore/
│ │ │ ├── postgres/
│ │ │ └── interface.go
│ └── projection/
│ └── account_projection.go
```
Le Chat consistently fails at this higher-level organizational thinking. It also makes bizarre formatting suggestions within code blocks, like recommending unconventional and inconsistent ordering of function arguments (mixing context.Context with other parameters in non-idiomatic positions for Go) or creating overly verbose struct tags that serve no purpose.
This creates a dangerous scenario for inexperienced developers who might accept the entire output as "best practice." The model is a powerful code autocomplete, but it lacks the architectural judgment of a senior engineer. It's as if it has ingested countless correctly formatted code snippets but cannot synthesize the underlying principles that govern their organization. For any serious project, I now use Le Chat strictly for generating *code fragments* which I then manually restructure into a sound architectural framework. Its suggestions on *where* and *how* to arrange those fragments should be ignored.
Yeah, the structural suggestions are where it falls apart. I've seen it do something similar when asking for a Grafana plugin layout. It'll generate a perfectly functional `module.ts`, but then propose putting the query editor, config editor, and the main panel component all in one 800-line file. That's a nightmare for anyone trying to actually maintain or extend it.
It's like the model understands syntax and common patterns, but has a weak grasp on the *why* behind separation of concerns. The code compiles, but the architecture is spaghetti.
Your observation about architectural-level formatting aligns with a core limitation in how these models are trained. They ingest vast amounts of code, but the training corpus lacks the implicit context of *project history*. They see the final state of a 10,000-line monolith and the final state of a well-factored microservice, but they don't learn the human decisions and pain points that led to one being preferable.
So when it suggests placing "command handlers, domain entities, and projection logic in the same monolithic package," it's because it has statistically seen that pattern in code that works. It misses that those examples are often beginner tutorials or legacy systems we're trying to unwind. The model can't distinguish between a shortcut for a blog post and a principle for a production system.
You need to scaffold the conversation with explicit architectural constraints. Instead of "outline a project for event-sourced CQRS," prompt with "provide a structure following Clean Architecture, with clear boundaries between domain, application, and infrastructure layers, using separate packages for commands, events, and projections." It will still sometimes get it wrong, but you're forcing it to map your request against the correct subset of its training data.