George Filippakis

A multidiscliplinary approach to Law, Finance and Technology

Beyond Vibe Coding: Software Architecture for Lawyers

AI can now write a remarkable amount of functional code. That does not mean that building reliable software has become effortless. It means that the most important human work is moving to a higher level of abstraction.

I learned this while developing AML Agent, an AI-powered platform for EU anti-money laundering compliance. The application currently includes three principal tools: a tailored AML document generator, a gap assessment tool and a regulatory monitoring tool. I did not write most of the application line by line. Coding agents performed much of the implementation. My role increasingly became that of product owner, domain expert, reviewer and, perhaps most importantly, software architect.

I approached the project with a hybrid background: I practise as a financial-services lawyer, principally in banking law, corporate law and regulatory compliance, and I also studied computer science and was previously active in software development. That background made the underlying concepts more familiar, but it did not remove the central challenge. As the application grew, I still had to maintain an intelligible model of a codebase whose fine details were increasingly being produced by AI.

I believe this is an important distinction.

When AI can produce the code, the decisive questions become: What exactly should the system do? How should its components interact? Which decisions should be expressed as deterministic rules? Where is probabilistic AI judgment appropriate? What evidence should the system retain? What happens when a model, source, payment or database operation fails? And how will a professional know whether the result can be trusted?

The central lesson from my experience is simple:

In the age of coding agents, the scarce skill is increasingly not the ability to produce code. It is the ability to define the right problem, design the right system and determine whether the resulting software can be trusted.

This does not necessarily make software engineers obsolete. Nor does it mean that every lawyer should deploy client-facing software after a few successful prompts. It means that lawyers now have a much more direct route from domain expertise to a working prototype and, with the appropriate technical discipline and professional support, potentially to a useful product.

Software development itself is already shifting from writing every line of code towards directing and supervising agents that write code. A 2026 report on agentic coding describes this as a transition from writing code to orchestrating agents, while emphasising the continuing importance of human judgment, oversight, quality and security. In parallel, legal adoption of generative AI is accelerating: a 2026 survey of more than 1,300 legal professionals reported that 69% used general-purpose generative AI for work, even though institutional training and governance continued to lag.

I therefore believe the opportunity for lawyers is real. So is the responsibility.

A legal workflow is translated into a system blueprint, implemented by an AI coding agent and verified as a working application.

Vibe coding changes the cost of implementation, not the need for engineering

Vibe coding” is commonly used to describe building software by expressing the desired result in natural language and allowing an AI system to generate and modify the code. The term captures something important: the distance between an idea and a working interface has collapsed.

A lawyer can now describe a document workflow, calculator, internal dashboard or review tool and see a functional version take shape quickly. That speed is valuable. It makes experimentation cheaper and allows subject-matter experts to test ideas that might never have justified a conventional development budget.

But a working interface can create a dangerous illusion of completeness.

The application may accept an input and return an output while still lacking reliable permissions, data validation, concurrency controls, failure recovery, audit trails, retention rules, security testing or a coherent data model. These omissions are rarely visible in a polished demonstration. They become visible when real users, real data and unexpected events enter the system.

This is why I find the distinction between coding and engineering increasingly useful. Coding produces implementation. Engineering connects implementation to requirements, risks, constraints, testing, operations and maintenance.

AI is becoming extremely capable at the former. The lawyer-builder must still take responsibility for the latter, or know when to bring in someone who can.

Do not begin with the code. Begin with the professional problem

My most important practical lesson was also the simplest: do not ask an AI coding agent to start building as soon as an idea occurs to you.

Begin by identifying the professional problem with precision.

Lawyers often describe a proposed tool by reference to its visible output: “I want an application that drafts an AML policy”, or “I want a tool that monitors regulatory developments”. That is not yet a system specification. It leaves unanswered how the output will be produced, what information it will rely on, how accuracy will be assessed and what the user must do before relying on it.

A more useful starting point is to map the existing workflow:

  1. What event starts the work?
  2. Who performs it and for whom?
  3. What information is required?
  4. Which rules govern the analysis?
  5. Which steps are mechanical and which require professional judgment?
  6. What exceptions occur in practice?
  7. What evidence must support the conclusion?
  8. What output is actually useful to the professional?
  9. Who reviews or approves it?
  10. What would constitute an unacceptable failure?

This exercise produces what I think of as an algorithmic blueprint: an abstract model of the professional process that can later be translated into software.

The blueprint does not need to contain code. It should identify the system’s users, inputs, transformations, decisions, outputs and controls. It should also separate decisions that can be implemented deterministically from those that genuinely benefit from AI.

A legal workflow is converted into software by separating fixed rules from contextual AI-assisted judgments before validation and human review.

The distinction between deterministic logic and AI judgment deserves particular emphasis. A model should not be asked to decide matters that ordinary software can establish more reliably. Exact identifiers, dates, user permissions, arithmetic, database transactions and permitted status values usually belong in deterministic code. AI is more useful where language, ambiguity, classification or contextual adaptation is inherent in the task.

The objective is not to place AI everywhere. It is to place it where it adds value, while keeping the surrounding workflow controlled and explainable.

Three legal problems, three different architectures

My application began with three related needs arising in EU AML compliance:

  • Produce highly tailored compliance documents more efficiently.
  • Assess documents against defined legal or regulatory rulesets.
  • Monitor a changing regulatory landscape for relevant developments.

All three use AI. Architecturally, however, they are fundamentally different systems.

Document GenerationGap assessmentRegulatory monitoring
Starting pointEntity information, document type and legal parametersExisting document and selected rulesetContinuously changing official sources
Primary operationAssemble and draftExtract, map and compareCollect, identify and detect change
Deterministic layerIntake validation, template selection and output assemblyRuleset structure, obligation identifiers and score calculationSource parsing, stable identifiers, deduplication and status comparison
Appropriate AI roleContextual drafting and adaptationEvidence-grounded comparison and explanationSemantic classification and assessment of ambiguous changes
Human controlReview the generated documentVerify gaps, evidence and completenessModerate relevance, lifecycle and publication decisions
Principal riskPlausible but unsupported contentFalse impression of comprehensive legal coverageNoise, duplication, missed developments or incorrect status changes
Professional outputTailored document for reviewGap matrix and remediation findingsCurated regulatory intelligence record

The table illustrates why “add AI” is not an architecture.

Document generation is a structured drafting workflow

The visible feature is the generated document. The architecture begins much earlier.

The system must collect structured information about the entity, its activities, risk profile and required document. It must select the appropriate template and legal context, assemble a controlled prompt, invoke the model, validate the response, create the required file and preserve enough information for the user to retrieve and review it.

The quality of the result depends heavily on the quality of the intake design. A generic request such as “draft an AML policy” gives the model wide freedom and produces generic output. A structured intake translates the user’s circumstances into explicit variables and constraints.

The model’s role is not to invent the workflow. It is to perform the language-intensive part of a workflow already designed around it.

Gap assessment is an evidence and coverage problem

A gap assessment is not simply a request to “review this document against the the AML Regulation“. It requires a defined ruleset, reliable extraction of the uploaded document, a method of mapping provisions to requirements, a way of recording supporting evidence and a transparent approach to findings and scores.

This is where system design protects against a persuasive but incomplete answer. If the model produces only the gaps it happens to notice, a polished report may be mistaken for comprehensive legal coverage. A stronger architecture begins with the obligations to be tested and works through them systematically. Model-generated legal identifiers should be validated against the selected taxonomy. Scores should be derived from disclosed rules rather than accepted merely because the model returned a number.

Regulatory monitoring is a change-detection system

Regulatory monitoring required the greatest change in my own thinking.

At first glance, the task appears to be one of web collection and summarisation. In reality, reliable monitoring depends on source-specific parsing, provenance, stable identities, deduplication, lifecycle modelling, source-health checks and comparison with prior states.

The system must distinguish an instrument from the events in its lifecycle. A consultation, a final report and an adopted act may concern the same regulatory development but appear at different URLs, with different titles and on different institutional websites. A source page may be rearranged without any regulatory change. Conversely, a small status update may represent an important change even if most of the page remains identical.

One distinction became especially important in the moderation design:

“Currently listed by the source” is not the same as “legally current or in force”.

That is a legal and architectural distinction. If the software conflates those concepts, the interface can communicate a false legal conclusion even when every underlying data operation works exactly as coded.

The regulatory context makes this more than an academic example. The EU Anti-Money Laundering Regulation generally applies from 10 July 2027, while AMLA is developing and updating numerous technical standards and guidelines. AMLR on EUR-Lex and AMLA’s regulatory-instruments page illustrate both the breadth of the framework and the evolving lifecycle of its implementing instruments.

For this type of system, deterministic collection and change detection should remain authoritative for exact facts. AI can add value by assessing ambiguous relevance, identifying possible relationships, explaining semantic changes and proposing structured classifications. Its conclusions should remain grounded in captured source evidence and, for consequential publication decisions, subject to human review.

A good coding prompt is a specification, not a magic phrase

It is tempting to summarise AI-assisted development with the maxim that “the more detailed the prompt, the better the result”. My experience points to a more precise principle:

The more complete, relevant and testable the specification, the better the implementation is likely to be.

Length alone does not make a prompt effective. An extremely long prompt can contain contradictions, irrelevant detail or an unclear priority structure. What matters is whether the coding agent understands the objective, the current system, the constraints and the definition of success.

For a material change, my preferred implementation brief includes:

  • The problem: what is wrong or missing today.
  • The user: who needs the functionality and in what context.
  • The desired behaviour: what should happen in the normal case.
  • The boundaries: what must not change and what remains out of scope.
  • The risks: privacy, security, legal, operational or data-integrity concerns.
  • The acceptance criteria: observable conditions that must be true when the work is complete.
  • The verification requirement: how the agent should test or otherwise substantiate the change.

I also frequently ask the agent to inspect the existing system and propose a plan before modifying anything. This creates an opportunity to test its understanding of the architecture before implementation begins. If the plan reveals that the agent has misunderstood the data model, user journey or scope, correcting the plan is far cheaper than unwinding code.

For complex work, I find it useful to separate four stages:

  1. Explore: inspect the relevant code, data and dependencies.
  2. Plan: describe the proposed design, trade-offs and affected components.
  3. Implement: execute the approved plan in bounded steps.
  4. Verify: test the result against explicit acceptance criteria and failure scenarios.

This is more disciplined than asking the model to “make it work”, but it is also more efficient. Ambiguity that is not resolved in the prompt will usually reappear as rework, inconsistent behaviour or hidden assumptions in the code.

Do not use the most capable model for every task

Architecture, implementation, debugging, documentation and repetitive transformations do not necessarily require the same model or reasoning budget.

In my own development work, I obtained the best results by using a highly capable configuration for ambiguous, system-wide planning and a more economical model for well-scoped execution. At the time of writing, I found GPT-5.6 Sol in Codex’s Ultra mode particularly effective for deep application analysis and planning, while GPT-5.6 Luna at Max reasoning was highly effective at implementing clearly specified work with a lower usage profile.

That is a dated observation, not a permanent model recommendation. Models, product modes, pricing and relative performance change constantly. The current official OpenAI guidance similarly positions Sol for complex, open-ended work and Luna for clear, repeatable tasks, but the right choice still depends on the workload.

A practical model-selection process is therefore empirical:

Type of workCapability to prioritise
Initial architectureDeep, system-wide reasoning and trade-off analysis
Bounded implementationReliable execution against clear acceptance criteria
Security or launch auditIndependent, adversarial and detail-oriented review
Repetitive classificationLow cost, schema adherence and consistency
Technical documentationCodebase comprehension and clear explanation

Test candidate models on representative tasks from your own application. Compare not only whether the code runs, but how much supervision it requires, whether it respects boundaries, whether it introduces regressions and whether its output remains maintainable.

The most expensive model is not automatically the most economical choice. Nor is the lowest-cost model economical if it creates hours of rework.

The black-box problem grows with the application

When you do not write the code yourself, the application can gradually become difficult to understand.

At the beginning, the mental model is simple: there are a few pages, a database and an API call. As features accumulate, one user action may pass through authentication, validation, credit reservation, a background job, an external model, file generation, database settlement and a download endpoint. A change in one component may affect several others.

This is the point at which “vibe coding” can become literal: the application feels as though it works, but the builder no longer has a reliable model of why it works.

My response was to use the coding agent not only to write code but also to explain the system. For the regulatory monitoring tool, for example, I commissioned a detailed technical and operational manual covering collection, filtering, ingestion, moderation, publication, state transitions and future engineering decisions.

A useful system guide should cover at least:

  • The high-level architecture and component boundaries.
  • The end-to-end data flows for important user actions.
  • The database entities and relationships.
  • Authentication, roles and permissions.
  • External APIs, models and other dependencies.
  • Configuration and secret management.
  • Failure, retry and recovery behaviour.
  • Audit logs and retained provenance.
  • Deployment and database-migration procedures.
  • Testing strategy and known limitations.

Documentation generated by the same model that wrote the code should not be accepted uncritically. Ask the agent to trace the actual implementation, cite the relevant files or functions and distinguish current behaviour from proposed improvements. Update the guide when the architecture changes.

The objective is not for a lawyer-builder to memorise every function. It is to retain a sufficiently accurate system model to make decisions, identify risk and know what must be independently reviewed.

You may not need to be a programmer, but you need technical literacy

Frontier coding agents materially reduce the amount of conventional programming knowledge required to build a functional application. They do not eliminate the need to understand the technologies being selected on your behalf.

If a model recommends a particular database, hosting architecture, authentication system or job queue, the lawyer-builder should be able to understand the basic trade-offs. Relevant questions include:

  • Is the data relational or document-oriented?
  • What happens if two users perform the same operation simultaneously?
  • Which processes are synchronous, and which should run in the background?
  • Where are uploaded and generated files stored?
  • How are users authenticated and actions authorised?
  • How are external API keys protected and rotated?
  • What is logged, for how long and for what purpose?
  • How are dependencies updated and vulnerabilities identified?
  • What happens when a deployment or database migration fails halfway through?

This is functional technical literacy: enough understanding to interrogate a proposal and relate it to the future of the product.

It is analogous to legal practice. A banking lawyer does not need to operate a bank’s core ledger to advise on outsourcing or operational resilience, but must understand the system sufficiently to identify material dependencies, failure modes and control gaps. Lawyer-builders should apply the same standard to their own software.

The invisible architecture appears when the prototype meets reality

Some of my most valuable lessons came not from building visible features but from launch-readiness and migration reviews.

One review identified a concurrency problem in a credit-based workflow. Two requests arriving at almost the same time could both observe the same available balance before either reservation was completed. Each request looked valid in isolation. The defect existed in the interaction between them.

Another review found that historical generated-file records stored absolute filesystem paths. Moving the application from a temporary subdirectory to the domain root was therefore not merely a matter of updating public URLs. Without migrating the stored paths or preserving the old location, existing downloads could fail.

The regulatory monitor produced a different class of lesson. A collection run could technically “succeed” while returning an unexpectedly incomplete snapshot because a source page had changed structure. Treating that snapshot as authoritative could incorrectly remove or retire prior records. The appropriate design required source-health validation, previous-count comparison, quarantine of suspicious runs and preservation of a last-known-good state.

None of these issues is solved by a better user-interface prompt. They require reasoning about transactions, state, history and failure.

A professional AI application rests on data, validation, security, audit, deployment and recovery controls that are not visible in its interface.

The security principle should be straightforward: AI-generated code deserves the same scrutiny as human-written code. The ENISA Secure by Design and Default Playbook recommends applying the same review requirements to AI-generated or AI-modified code, together with automated security testing, dependency scanning, secret scanning and negative tests for critical endpoints.

For a client-facing or professionally consequential product, there will be points where an experienced software engineer, cybersecurity specialist, privacy professional or other relevant expert should review the system. AI lowers the cost of creating software. It does not transfer the builder’s responsibility to understand and control the resulting risks.

Domain expertise becomes architectural leverage

Lawyers sometimes assume their value in technology projects is limited to providing legal content after the technical system has been designed. My experience suggests the opposite.

Domain expertise is most valuable at the architectural stage because it reveals distinctions that a technically elegant but professionally naive system may miss.

In an AML regulatory tracker, for example:

  • An official publication, a consultation and an adopted act are not interchangeable records.
  • A change in a webpage is not necessarily a change in legal status.
  • The fact that an item is no longer listed by a source does not establish that it has ceased to have legal relevance.
  • “Facts approved” is not necessarily the same state as “approved for publication”.
  • An official-source statement should remain distinguishable from the platform’s own analysis.
  • A model’s confidence is not a substitute for supporting evidence.

These are not merely labels. They determine the data model, moderation states, user interface, audit history and permissible automation.

This is where legal training can become a genuine engineering advantage. Lawyers are trained to identify conditions, exceptions, authorities, definitions, hierarchies and consequences. Those habits map naturally to requirements analysis and system architecture, provided they are expressed clearly enough to be implemented.

The lawyer’s moat is therefore not the ability to prompt a model with legal terminology. It is the ability to convert legal and professional judgment into a coherent operating model.

A practical architecture framework for lawyer-builders

If I were beginning another legal software project, I would use the following sequence.

1. Select a real workflow

Choose a recurring professional problem with identifiable users, inputs and outputs. Avoid beginning with a technology in search of a use case.

2. Map the current process

Document how the work is performed today, including exceptions, escalation points, evidence and review. Inefficiency often hides in handoffs rather than in the obvious substantive task.

3. Define the professional outcome

Specify what a useful result looks like. “Generate a report” is too vague. Define its structure, audience, evidential basis and intended decision.

4. Separate rules from judgment

Use deterministic software for exact operations and controlled states. Use AI where interpretation, classification or language generation adds genuine value.

5. Design the data and control model

Identify what must be stored, for how long, under which permissions and with what provenance. Define review and publication states explicitly.

6. Write the implementation brief

State the objective, constraints, risks, edge cases, acceptance criteria and verification steps. Ask for a plan before implementation where the change is material.

7. Allocate model capability deliberately

Use deeper reasoning for architecture, difficult debugging and independent review. Use efficient models for bounded tasks whose success criteria are clear.

8. Test failure, not only success

Test invalid input, interrupted external services, concurrent requests, stale data, unauthorised access and partial completion. The “happy path” is rarely where architecture proves its value.

9. Maintain a system guide

Keep architecture, data flow, dependencies, permissions, deployment and recovery documentation aligned with the actual code.

10. Obtain independent review at the appropriate threshold

The review required for a personal prototype is not the review required for software that processes confidential documents, takes payment or informs professional decisions. Increase assurance as consequences and exposure increase.

Ten steps for lawyers designing software with AI, from selecting a workflow to independent review.

From consumers of legal technology to designers of legal systems

Lawyers have traditionally encountered software as users, purchasers or advisers. AI coding agents create a fourth role: the lawyer as builder.

That role can take many forms. It may involve a small internal tool, a disposable prototype used to clarify requirements, a practice-specific workflow application or a client-facing product. Not every prototype should become a commercial platform. Building can still be valuable because it forces the professional to articulate how the work actually operates and what the technology must accomplish.

The larger implication is that domain experts can participate much more directly in software creation. But the opportunity is not simply that lawyers can now produce code without conventional programming. It is that they can translate professional knowledge into system design with far less friction between idea and implementation.

The quality of what they build will depend less on the fluency of a single prompt than on the quality of their architecture: the clarity of the problem, the integrity of the data model, the allocation of work between rules and AI, the treatment of failure and the discipline of verification.

AI can write the code. The lawyer still has to design the system.


Frequently asked questions

Can lawyers build software with AI?

Yes. Current coding agents can translate detailed natural-language requirements into functional software, allowing lawyers to prototype and build tools without writing every line of code. The lawyer must still define the workflow, constraints, controls and success criteria, and obtain appropriate technical review before consequential deployment.

Do lawyers need to learn programming before using AI coding agents?

Not necessarily. Conventional programming knowledge is helpful, but the minimum requirement is functional technical literacy: understanding the main technologies, data flows, permissions, dependencies and failure modes well enough to evaluate architectural choices and supervise the system responsibly.

What is the difference between prompting and software architecture?

Prompting tells an AI system what to do in a particular interaction. Software architecture defines how the entire application is organised: its components, data, interfaces, responsibilities, controls and behaviour over time. A strong prompt can implement part of an architecture, but it cannot replace the need for one.

How can a vibe coder prevent an application from becoming a black box?

Maintain an up-to-date system guide covering architecture, data flows, database entities, permissions, external services, failure recovery, deployment and testing. Ask the coding agent to ground the documentation in the actual implementation, and independently verify security-sensitive or professionally consequential areas.

Should AI make legal or compliance decisions automatically?

Only where the use case, evidence, risk and applicable law justify that level of automation. In many professional tools, AI is better used to generate a structured proposal or analysis while deterministic validation and human review retain control over consequential decisions.

When should a lawyer-builder involve a software engineer?

The need increases with the application’s exposure and consequences. Client-facing systems, confidential or personal data, payments, complex permissions, external integrations and professionally consequential outputs may generally justify independent engineering and security review before launch.


Leave a Reply

Your email address will not be published. Required fields are marked *