An engineering example from building Foundgine
Large language models are remarkably good at interpreting language.
That has led to a natural architectural assumption:
User
↓
LLM
↓
SQL / API / Tool call
↓
System
For simple applications, this can work surprisingly well.
But as soon as an agent has to operate a non-trivial system, a fundamental problem appears:
The model has to infer the meaning of the system before it can reliably act on it.
That distinction is easy to overlook.
A database schema contains structure.
An API contains contracts.
A GraphQL schema contains types and fields.
Documentation contains explanations.
But none of these necessarily provide a complete, executable representation of the system's semantics.
That is the problem Foundgine was designed to explore.
- Syntax is not semantics
Consider a simplified relational model:
Customer
Id
CustomerKey
FirstName
LastName
CustomerBankingRelationship
Id
CustomerId
CustomerBankingRelationshipKey
Contract
Id
CustomerBankingRelationshipId
ContractKey
Transaction
Id
ContractId
TransactionKey
Amount
Balance
An LLM can look at this and infer:
Customer
↓ CustomerId
CustomerBankingRelationship
↓ CustomerBankingRelationshipId
Contract
↓ ContractId
Transaction
That inference may be correct.
But it is still an inference.
The model is reconstructing semantics from implementation details.
That distinction matters.
A column called:
CustomerId
is not the same thing as an explicit semantic statement:
Customer
hasMany
CustomerBankingRelationship
The first is a database implementation detail.
The second describes the domain relationship.
- The problem gets worse when an agent acts
Suppose an AI agent receives:
Create a customer with a banking relationship, a contract and two transactions.
The agent needs to understand more than the names of the tables.
It needs to understand:
Customer
└── CustomerBankingRelationship
└── Contract
└── Transaction
It also needs to understand identity.
For example:
Customer.CustomerKey
CustomerBankingRelationship.CustomerBankingRelationshipKey
Contract.ContractKey
Transaction.TransactionKey
And it needs to understand that the child records depend on values produced by their parents.
Conceptually:
Create Customer
↓
obtain Customer identity
↓
Create CustomerBankingRelationship
↓
obtain relationship identity
↓
Create Contract
↓
obtain contract identity
↓
Create Transactions
This isn't merely SQL generation.
It is planning over a semantic graph.
- Foundgine separates meaning from execution
This became one of the central architectural ideas in Foundgine.
Rather than immediately turning a request into SQL, the pipeline introduces semantic representations between the external request and the physical database:
Domain
↓
Metadata
↓
Semantic Graph
↓
Planner
↓
Query Plan
↓
Execution
↓
Provider
↓
SQL
This separation is important.
The semantic layer can describe concepts such as:
Node
NodeIdentity
Edge
EdgeIdentity
Traversal
Path
Predicate
Projection
Ordering
Cardinality
These aren't PostgreSQL concepts.
They aren't GraphQL concepts either.
They describe what the operation means.
Only later does the system decide how that meaning should be implemented physically.
- Why an intermediate semantic representation matters
Consider:
customer(first: 50) {
id
firstName
customerBankingRelationship {
contract {
transaction {
amount
balance
}
}
}
}
A naïve architecture can think about this as:
GraphQL
↓
SQL
Foundgine instead treats it conceptually as:
GraphQL intent
↓
semantic traversal
↓
graph plan
↓
physical query plan
↓
SQL
The important difference is that the system can reason about:
Customer
→ CustomerBankingRelationship
→ Contract
→ Transaction
before deciding how that traversal should be executed.
This gives the planner a stable vocabulary.
- The semantic model is also useful without AI
This is perhaps the most important point.
It would be easy to describe semantics as:
“metadata for AI.”
That undersells the idea.
The semantic model is useful even if there is no LLM anywhere.
It can drive:
deterministic query planning
relationship traversal
authorization decisions
validation
execution planning
optimization
explainability
AI becomes another consumer.
That distinction is important because it avoids building an “AI layer” that is tightly coupled to a particular model.
- Where LLMs fit
The LLM is extremely good at one part of this pipeline:
Natural language
↓
intent
For example:
“Show me the first 50 customers and their transactions.”
An LLM can interpret the request.
But it shouldn't necessarily be responsible for deciding:
Does Customer have this relationship?
What is the identity of the entity?
Is this relationship one-to-one or one-to-many?
Can this traversal happen?
Which fields are authoritative?
What dependencies exist between mutations?
How should the operation be executed?
Those are properties of the system.
The system should expose them.
The LLM interprets intent.
The semantic layer provides meaning.
The planner determines execution.
That gives us:
LLM
↓
Intent
↓
Semantic Model
↓
Deterministic Planner
↓
Execution
rather than:
LLM
↓
"probably correct" SQL
- A concrete mutation example
This is where the distinction becomes particularly interesting.
Imagine the mutation:
Create Customer
Create Banking Relationship
Create Contract
Create two Transactions
The transaction records cannot be created independently.
They depend on the contract.
The contract depends on the banking relationship.
The banking relationship depends on the customer.
So the operation has a dependency graph:
Customer
│
▼
Banking Relationship
│
▼
Contract
│
├──► Transaction
└──► Transaction
The semantic representation exposes that dependency.
The planner can then construct an executable plan.
The provider can ultimately turn that plan into database operations.
The LLM doesn't need to invent the dependency chain.
It only needs to express the intended operation.
- This is where semantics become especially important for agents
An AI agent has two fundamentally different problems:
Problem 1 — What does the user want?
This is where an LLM shines.
Problem 2 — What does the system allow and mean?
This should not be left entirely to the LLM.
That second problem belongs to the application's semantic model.
This gives us a useful division of responsibility:
Responsibility Best handled by
Interpret natural language LLM
Determine system meaning Semantic model
Validate relationships Semantic model
Determine dependencies Planner
Select physical execution Planner/provider
Execute operation Runtime
Generate final explanation LLM
The LLM remains powerful.
But it is no longer expected to reconstruct the entire system from scratch.
- Why this is different from RAG
RAG is useful because it gives an LLM additional context.
For example:
LLM
↓
Retrieve documentation
↓
Reason
But documentation is still information the model has to interpret.
A semantic model is different.
It can be structured and executable.
Instead of:
"CustomerBankingRelationship is a relationship between..."
the system can represent:
Customer
relationship:
CustomerBankingRelationship
cardinality:
many
identity:
CustomerBankingRelationshipKey
The difference is subtle but important.
RAG gives the model information about the system.
A semantic model gives the software a structured representation of the system.
- The bigger architectural consequence
Once semantics become first-class, the architecture becomes much more interesting:
┌─────────────┐
│ LLM │
└──────┬──────┘
│
Intent
│
▼
┌─────────────────┐
│ Semantic Model │
└────────┬────────┘
│
┌──────────┴──────────┐
│ │
Validation Authorization
│ │
└──────────┬──────────┘
│
Planner
│
▼
Query Plan
│
▼
Provider
│
▼
SQL
The LLM is no longer the architecture.
It is one component inside the architecture.
That's an important distinction for agentic systems.
- What Foundgine actually demonstrates
The repository doesn't prove that:
“LLMs are solved.”
It doesn't prove that:
“A semantic layer makes every AI agent reliable.”
Those would be much larger claims.
What the repository does demonstrate is something narrower and, arguably, more useful:
A software system can make its domain semantics explicit and use those semantics to deterministically plan operations instead of reconstructing system meaning from the physical database representation at every request.
That is already valuable.
And it creates an interesting foundation for AI agents.
Because once a system has an explicit semantic model, an agent no longer has to discover everything through:
documentation
+
database schema
+
API exploration
+
guesswork
It can potentially consume the same semantic representation the runtime itself uses.
- The principle
The lesson from Foundgine is not:
“Use AI to generate better SQL.”
It is closer to:
Don't ask an AI to infer semantics that your software already knows.
Let the model do what models are good at:
language
reasoning
intent
Let the system do what deterministic software is good at:
meaning
constraints
relationships
planning
execution
And connect the two through an explicit semantic layer.
That may be one of the more important architectural patterns for the next generation of AI-powered software.
Top comments (0)