EN DE
Illustration: a glowing neural network connects through a port to a hexagonal core that links to three separate modules, with the title “Why AI Makes Architectural Patterns More Important”

Why AI makes architectural patterns more important

Technology Trends
October 20, 2026

By Gari Ciodaro, Co-Founder and CTO of Recall Space GmbH

Agentic flows are valuable because they can adapt. Architectural patterns help us put that flexibility where it belongs, so we can improve an agent without redesigning everything around it. LangChain and LangGraph make this approach practical.

A customer asks for a refund. An agent reads the message, the application checks the order, and a decision comes back. The demo works.

Then the model changes. A new tool is added. The refund policy moves from thirty days to sixty. Suddenly, changes to how the application understands language are tangled up with changes to what the business allows.

AI makes the first version easy. It also makes change constant: models are swapped, prompts are tuned, tools are added, and each revision shifts behavior nobody wrote by hand. The faster the parts change, the more the boundaries between them are worth. That is why AI makes architectural patterns more important, not obsolete. The useful question is how much of the system has to move when one part changes.

Start with what the business needs

Consider a simple refund-triage application. It has two different jobs:

  • Understand the request. Is the customer asking for a full refund, something else, or something unclear? Which words support that interpretation?
  • Apply the policy. Using trusted order data, does the request qualify? In this example, a paid order up to thirty days old is eligible.

The first job benefits from an agent. Customers express the same thing in different ways, and the agent may need a terminology lookup before it can interpret the message. The second job has a rule the business owns. Ambiguous requests go to review; issuing a payment is a separate responsibility.

That separation gives us a domain boundary before we choose a framework.

Give the agent a boundary

Hexagonal architecture gives this boundary a concrete form. The application defines a port: “interpret this request and return an intent with supporting evidence, or tell me you could not.” An adapter implements it using an agentic flow.

The adapter translates the agent’s output into the application’s own terms. Prompts, tool calls and model responses stay inside that capability. The refund policy receives an interpretation it understands.

from typing import Protocol

class RequestInterpreter(Protocol):
   async def interpret(
       self, message: str
   ) -> Request | InterpretationFailure: ...

Request carries intent and a supporting quote; InterpretationFailure makes failure explicit. These Python excerpts omit supporting types and setup to focus on the boundaries.

Domain flow: understand the request, apply refund policy, return a decision. The application core owns the RequestInterpreter port and refund policy. A separate LangChain interpretation adapter implements that port, using a model and read-only tools to return intent and evidence or an explicit failure. Code dependency points toward the core. LangGraph coordinates interpret, apply policy, review if needed, and reapply policy.
The domain defines the responsibility; the port defines the contract. The agent can take different paths inside its adapter. LangGraph coordinates the surrounding workflow.

This is a useful way to think about high cohesion and low coupling: keep the work of interpretation together, and keep its implementation details out of the policy. The agentic flow becomes a unit that absorbs variability.

The tempting alternative is to skip the architecture and vibe code it: wire steps together, accept what works, iterate. But a graph of connected steps does not, by itself, decide who owns the business rules. Hexagonal architecture addresses dependencies; the graph expresses execution. They work together.

It also helps to name what we are trading. Richards and Ford’s first law of software architecture says that everything in software architecture is a trade-off. Adaptability is an architecture characteristic like testability or auditability, and it is not free: an agentic flow buys it and pays in predictability. The boundary does not remove that trade-off; it decides where each side is paid. Adaptability lives in the adapter, where it creates value. Determinism stays in the policy, where the business depends on it.

Where LangChain and LangGraph fit

LangChain provides the adaptive capability. Its create_agent API supplies the model-and-tool loop. In this example, the agent can consult a read-only support glossary when useful. Structured output gives the adapter an intent and a supporting quote to validate, while middleware can limit model and tool calls. We can build on those capabilities without writing another agent runtime.

agent = create_agent(
   model=model,
   tools=[support_glossary],
   response_format=IntentOutput,
)

class LangChainRequestInterpreter:
   def __init__(self, agent):
       self.agent = agent

   async def interpret(self, message):
       result = await self.agent.ainvoke({
           "messages": [
               {"role": "user", "content": message}
           ]
       })
       output = result["structured_response"]
       return to_domain(output, message)

IntentOutput is the agent’s output schema. The adapter’s to_domain helper validates the quote and returns the application’s types. Prompt configuration, error handling and call limits are omitted here.

LangGraph composes it with the business process. A StateGraph connects interpretation, policy and review. If the interpretation is unclear, an interrupt, backed by a checkpointer, lets the workflow pause for a person and resume with their correction. The same policy then runs again.

graph = StateGraph(TriageState)
graph.add_node("interpret", interpret_request)
graph.add_node("policy", apply_policy)
graph.add_node("review", review_request)
graph.add_edge(START, "interpret")
graph.add_edge("interpret", "policy")
graph.add_conditional_edges("policy", next_step)
graph.add_edge("review", "policy")
workflow = graph.compile(checkpointer=checkpointer)

Refund triage execution flow: START leads to interpret, then policy. Policy sends an unresolved case to review on the first pass, or ends when the decision is final. Review pauses for human input, then resumes at policy. Dashed arrows indicate conditional routing.

‍

The nodes call the interpreter, apply the policy, or pause for review. next_step sends an unresolved case to review once; after the reviewer’s correction the policy decides again, and that decision is final. A case that is still unresolved leaves the workflow for manual handling.

LangChain agents themselves run on LangGraph. That shared foundation lets us place a dynamic agent inside a more explicit workflow, choosing the right amount of flexibility for each responsibility.

The boundary still needs engineering judgment. A valid output shape does not prove that an interpretation is correct. Here, the adapter checks the supporting quote, failures go to review, and the agent has no payment tool.

The useful test is what happens when something changes

Now extend the refund window to sixty days. That change belongs in the policy and its tests. Try a new model or improve the glossary tool: that work belongs in the interpretation capability and its evaluations. The rest of the application can keep using the same contract.

Some changes cross the boundary. Supporting partial refunds introduces a new business concept, so both the contract and policy may need to evolve. A good boundary makes that impact visible.

This is the practical value of architectural patterns in AI systems: a contained blast radius for change, clearer ownership, and room to improve the agent independently. The more often the AI parts change, the more often those boundaries pay for themselves. The same approach applies when interpreting a supplier confirmation or classifying a support case.

Give agentic flows room to adapt. Use architecture to make that adaptability useful to the whole system.

Architecture glossary

  • Domain: The business concepts and rules the software models: here, customer requests, orders and refund eligibility.
  • Hexagonal architecture: An approach that keeps business logic independent of technology choices by connecting it to implementations through ports and adapters.
  • Port / contract: An interface owned by the application that defines a capability and its expected inputs and outcomes, including failure.
  • Adapter: An implementation of a port that translates between the application’s concepts and a particular technology, such as a LangChain agent.
  • Cohesion: How closely a component’s responsibilities belong together. High cohesion keeps the work of interpreting a request in one capability.
  • Coupling: How much components depend on each other’s details. Low coupling lets the agent change while the policy keeps using the same contract.
  • Architecture characteristic: A quality the system must support, such as adaptability, testability or auditability. Improving one usually costs another, so the trade-offs are chosen, not avoided.
  • Blast radius: How far the effects of a change or failure can spread. Clear boundaries help contain those effects.

Sources

‍

‍

Meet the Writer

Gari Ciodaro, data science lead at Recall Space

Gari is a scientist trained in physics and mechanical engineering, and a data science leader building agentic systems for supply chain operations at Recall Space. With over 10 years turning large, multi-dimensional data into solutions, he specializes in deep learning and distributed, scalable machine learning across data science, data engineering and ML DevOps.