India has changed its GDP base year three times since 2010: in 2010, 2015 and 2026. Each time, the headlines say growth has been “revised.” That word covers several different things, and only some tell you about the real economy.
Level versus Growth
In 2026 the base year moved from 2011-12 to 2022-23. Nominal GDP was cut by 2.7% for FY23, 3.5% for FY24 and 3.8% for FY25. That is a revision to the size of the economy, not its pace. If every year were cut equally, growth wouldn’t change.
The cuts widen across the three years, so nominal growth is lower. Real growth is a different story. FY24 fell from 9.2% to 7.2%, but FY25 rose from 6.5% to 7.1% and FY26 from 7.4% to 7.6%. Average real growth across the three years dropped from 7.7% to 7.3%. The economy is smaller and marginally slower, but the year-to-year volatility also decreased. The deflator change breaks the link between the nominal and real number.
This isn’t the first time history has been re-written. Earlier rebasing had this effect of moving these numbers up and down.
Four Reasons a Number Gets Revised
1. Better measurement of output:
Most revisions reflect clearer measurement, not a different economy. In 2015, MCA21 corporate filings replaced sample-based estimates. In 2026, direct surveys of unincorporated businesses (ASUSE) and the labour force (PLFS) replaced benchmarks carried forward with proxies, alongside GST, PFMS and e-Vahan data. Trade, hotels, transport and communication were cut by roughly 25%; agriculture came out about 5% larger, lifting its share from 16.5% to 18.2% in FY23. The informal economy hadn’t shrunk; parts of it had been overestimated and parts missed.
2. The deflator:
Real growth is nominal growth minus the GDP deflator. The old series leaned on wholesale prices and “single deflation,” where the output price index is also applied to inputs which distorts real growth when commodity prices swing. The 2026 series moves to double deflation in manufacturing and agriculture, uses over 260 granular CPI indices, and takes state-supplied prices for agriculture instead of WPI-adjusted ones. The fix is real but partial: WPI is still on a 2011-12 base while CPI was rebased to 2024, and statistical discrepancies of 0.4–1.5% of real GDP persist.
3. The weights:
A new base year reflects today’s economy, not the one from a decade earlier. Sectors that have grown get bigger weights, so headline growth can shift even when no individual sector’s numbers change.
4. The method:
In 2015 India also switched its headline measure from GDP at factor cost to GVA at basic prices and GDP at market prices, following the UN’s SNA 2008. FY14 growth rose from 4.9% to 6.6% at factor cost, and to 6.9% on the new market-price measure. Two changes at once fuelled years of argument over comparability. The 2026 series adds the Supply-Use Table framework and allocates corporate value added by activity rather than by a company’s dominant sector.
What it does change
The FY26 fiscal deficit goes from 4.4% to 4.5% of GDP, and the Centre’s debt ratio from 56.2% to 58.1% without a rupee of extra borrowing. Hitting the FY27 deficit target now needs nominal growth well above the 10% the Budget assumed.
What doesn’t matter
Exchange rates. Rebasing is done in rupees, so the currency has no effect on official growth. It only matters when converting GDP to dollars for global rankings and per-capita comparisons. A weaker rupee can push India down a ranking or cut dollar per-capita income even when rupee GDP is unchanged.
The Real Question
The biggest decision in any rebasing is how the old series is linked to the new one. That choice decides whether past growth is rewritten, and the 2015 back-series fight showed how political it can get. That decision is still ahead of us: the new series currently starts at FY23, and the back series to 1950-51 is due by December 2026. Anything you read today comparing 2026 growth to 2012 growth is comparing two different rulers.
So when you see “GDP revised,” you can continue to focus on the wrong thing. Ask questions like: Did the level change or the growth rate? Is it new data, a new method or new weights? And has the past been restated to match?
But the real question for you my reader is what does it mean for you? Does lived reality reflect the 7.6% improvement?
What to look for?
Let us look at it from different perspectives (all at an individual level):
Income:
Look at your total monthly incoming last year and compare it with your total monthly incoming today. To increase accuracy remove required expenses from the incoming to factor for inflation.
– If the major component of that is your salary then how much has that changed?
– If you have non-salary income under your control (e.g., rental income) then how much did you increase it over the last year?
– If you have non-salary income not under your control (e.g., dividends) then how much did they increase (indirect indicator of the wider economy).
Spending:
Did you feel more confident and therefore start spending more in the last year.
If your confidence did not increase (as indicated by an increase in your spending) then from your point of view GDP increase has no significance.
Confidence in the economy leads to big purchases such as housing or foreign holidays. Here the money has been accumulating for some time therefore recent increases in income matter less. This spending impacts future growth of the economy as well.
Lending:
Did you feel more confident to lend money this year as compared to last year.
Lending is not just about giving a loan to someone. This is wider and includes lending to companies (e.g., via bonds, and equity). This means you have confidence in people and organisations being able to return what they borrow.
This post follows up on the previous posts and attempts to build a generic harness that builds out OKF bundles on any topic. This aims to showcase the tech behind products such as Copilot CLI.
OKF bundles are one example of a knowledge artefact that can be used to provide information to specialised agents for a wide variety of tasks.
The harness has tools that allow directory traversal and internet searching to build out OKF bundles. State of the art harnesses like Copilot and Claude CLI have sophisticated tools that can for example read/write word documents and process PDFs.
Previous posts can be found here and I would encourage you to review them before reading this one:
The Config is stored in config.yaml found here: https://github.com/amachwe/okf/blob/master/config.yaml. The only config is the path-root which restricts the operational scope of the agent when it comes to file manipulation.
Command to auto deploy (run in the root repo folder that contains the okf_builder folder and the agent, manifest, prompt and config yaml files) to the playground app provided by Google:
> agents-cli playground
Use the playground chat app to interact with the agent.
Once the playground spins up load the web-interface you will find the agent loaded with the six tools as below:
OKF_Builder agent with the six tools.
Start with a simple prompt like:
build okf for go language creating, debugging, testing. and performance improvement
See the agent in action as it combines internet search, local files, and the magic of the LLM to create OKF bundles.
Tips
Create a working directory and point the agent to it to focus it on relevant content.
Include your own knowledge sources within the working directory to reduce dependency on the Internet and LLM’s internal knowledge.
Ask the agent to iteratively add depth to the OKF bundle produced.
Ask the agent to combine more content into the OKF bundle.
Experiment with different LLMs to see the difference in the output.
LLM as the Secret Sauce
The MODEL parameter in agent.py allows us to select different models. Models need to have reasoning modes to ensure good output.
I have tested the agent with two models (via LiteLLM):
gpt-5.6-terra – via OpenAI API
gemma4:12b (via ollama) – locally hosted
These are two extreme ends of the model spectrum.
Two examples that showcase the difference in the output can be seen here:
There is a revolution underway in how we think about multi-agent systems. It is moving from an orchestra with a conductor to a bunch of one-person bands.
Modelling a journey as a set of interacting agents each with specific knowledge, tools, and skills is not trivial to scale. Each hop between agent represents cost, latency, and risk.
This burden is worth taking when operating across system boundaries to ensure high cohesion and low coupling between systems. But within system boundaries this burden can be reduced by using a semantic network instead of a network of agents.
A semantic network is a network of interconnected knowledge, skills and tools concerned with supporting specific outcomes by surfacing relevant content. The network design allows layered meaning to be captured specific to outcomes.
So instead of moving data between agents, the agent moves across the network of knowledge assets, tools, and skills as required with state changes being captured.
Instead of building agents and agent orchestration, build the right knowledge set and allow an agent to navigate over it.
Consider the multi-agent system below. The Customer interacts with the Conversational Agent which in turn uses the Expert Problem Solver to define the solution and the Fulfilment Agent to execute the solution. Control passes along the green arrows.
Figure 1: Semantics locked within independent Agents.
The green arrows represent some form of agent to agent communication. This can be remote (e.g., via SSE) or local (e.g., defined by frameworks like Google’s ADK).
The above approach leads to the following:
Each agent has (potentially) a separate set of instructions, tools, skills, and access to knowledge.
Each agent can evolve independently (e.g., instructions can change).
Each agent may have independent existence (failure of one may not mean the failure of others).
Communication between agents is via state exchange (messaging/shared state).
Non-linear scaling of operational effort (not per agent but also to manage the interaction between agents).
Agents as Knowledge-seeking Navigators
In the figure below the coloured ovals are subsets of knowledge, skills, and tools relevant to a specific task within a journey. Each subset can refer to common knowledge, skills and tools. For example, tone guidance common to all responses.
Conversational skills for example would explain how to hold a conversation across different channels (e.g., email, web-chat) whereas Problem Solving tools would include data discovery capabilities around process, and Fulfilment Knowledge would allow an agent to execute specific fulfilment workflows in a repeatable manner.
The purple arrows represent semantic links between the sub-sets. The agent here is a single entity that attaches itself to different knowledge sub-sets as it traverses through the enterprise’s knowledge base.
The green arrows map this view to the agent as an independent entity view where each agent would be tightly coupled to its knowledge subset and control would pass along the green paths.
This is the default architecture of Claude Cowork and you do not build individual agents and then connect them in a workflow. It can spawn specific agents for certain tasks but that is outside your direct control.
Figure 2: An Agent traversing a semantic network.
Now imagine all the knowledge, tools and skills for a given business domain is represented as a network of related items. These relationships can be of the following types:
Semantic – to maintain semantic links between different items to also be used for navigation.
Content – to maintain link between different content items (e.g., references and their use, tools and skills).
Semantic and Content relationships are navigable. This navigation is what I call a flexi-reasoning task which requires flexibility between reasoning about the problem, selecting an action, and thinking about how to think.
Combined Pattern
The above can be combined to get best of both worlds. Ensuring flexibility within a semantic boundary by modelling it as a network and using agent-to-agent (peer-to-peer/director worker).
Figure 3: Combined pattern.
The semantic boundary can align with Business Unit boundaries, Organisation boundaries, even over different classes of knowledge (e.g., Customer Knowledge such as customer contact vs Enterprise Knowledge such as policies).
This isolation can also help with managing the underlying semantic networks independently of each other.
What is Changing?
In the second case above the only thing changing between each stage is the knowledge available to the agent to operate. There is nothing specific about the agent itself – it is merely an intelligent semantic processing function. It is able to ‘make sense’ of the knowledge and skills provided and then use available tools as required.
Session state is what helps keep the conversational context as the agent acts using different knowledge subsets.
Operational simplification is an added advantage of this approach. You are not monitoring multiple agents and comms between them. Instead you are monitoring a finite set of semantic network crawlers.
Issues with the Approach
There are a few issues with this approach:
heavy reliance on the model and agent architecture to deal with different knowledge subsets encountered whereas in the individual entity model each agent can be crafted to handle the knowledge subset it needs.
dynamic linking between knowledge can lead to long/deep thinking sessions which may not produce the required output and this would be wasted effort.
question of when we need actual independent agents communicating with each other versus agents navigating a semantic network (system boundary rules).
building semantic networks at scale is still an art-form, leveraging AI will help but only part way until it becomes ingrained in day-to-day ways of working.
retrieval latency can have high variability depending on the hop (e.g., when accessing content from local folders vs external stores).
each hop carries its own noise based on the specific task and there are no guarantees of information gain corresponding to the navigation effort.
How to Build This?
The navigation richness described above depend on three capabilities:
the AI model
the harness that orchestrates the model outputs (between tool calls, reflection loops, user I/O)
the tools available to the harness to access content in different locations
The AI Model
The AI Model will require decent context window size enough to hold a knowledge subset plus session state; in practice hundreds of thousands of tokens. Reasoning mode is also required for such flexi-reasoning tasks. Here newer models have a clear edge on older ones with respect to depth and width of tasks that can be carried out. For example I have seen a massive difference between different versions of Gemini Flash (2.5 vs 3.1) in such a situation.
The AI Model is what directs the switching between action, problem solving, and reasoning modes, makes sense of inputs, and maintains context. Therefore, it is a critical component.
The Harness
The harness includes system prompt templates, input and output parsers, routers, and callback functions. This is the hidden deterministic processing that sits around the model and is the real value-add beyond the ‘intelligence’ in the model.
One of the key tasks for the harness is to ensure output type is correctly routed to the appropriate handler. For example, if the model indicates execution of a tool then it should be routed to the appropriate tool handler.
The harness needs to be generic enough to deal with wide variety of tasks.
Callbacks
Functions that are called at specific points during the operation of the Agent and used to manage the system in a deterministic manner. Use-cases include injecting guardrails, critical knowledge, and rules using design-time integration (e.g., coded API call).
The Tools
The navigation of the semantic network is heavily reliant on the tools available. Semantic links are about accessing resources and can be of different types:
Local folders: a local folder structure with parent-child and peer-to-peer relationships that is used to organise content.
Internal reference via a URL: an internal link that can be followed and control remains within the org. For example: following a shared folder link.
External reference via a URL: a link pointing to an external resource. For example: following a web-link to a pdf.
Discovered links: links that are made available through internal or external search, these links can point to a variety of resources (e.g., pdf, website, documents). For example: internal SharePoint search which retrieves word documents, pages, and pdfs.
Embedded content: where content is embedded in a page structure as an attachment. This requires the tool to parse and extract the embedded content.
For the above we need tools that can access content of different types, extract content for the AI model to consume and if required to crawl the semantic network.
Each of the specific link types comes with its own challenges:
Control: local folders are under direct control of the agent whereas discovered links are completely outside its control.
Curation: external resources are outside org curation.
Permission: some sources provide detailed authorisation capabilities (e.g., a content management system like Confluence) but others may not (e.g., local folders).
Intellect: By convention there is sweetness, by convention bitter-ness, by convention color, in reality only atoms and the void.
Senses: Foolish intellect! Do you seek to overthrow us, while it is from us that you take your evidence?
– Democritus
Consider the humble language model with its attention heads, feed-forward layers and complete dependence on the prompt.
The prompt is the information coming in. To be ‘read’ by the senses (attention-heads) to be evaluated by the intellect (feed forward layers) distributed across stacked layers.
The quote above is highly relevant for how such models operate and how the combination of prompts and attention mechanisms impact the results.
For the model the only place to sense is the context window and the only mechanism to action what changes there is via dependency on external tools. The intellect has limited functions to influence what it attempts to sense next both due to lack of sophisticated actuators (tools) and limited forms of sensing.
The so-what?
The implication is that prompts are becoming complex artefacts that evolve outside direct human control. The so called thought traces of models are a bit of smoke and mirrors in the process as supported by research into CoT faithfulness.
Cost estimates, token budgets, and tool integrations are art forms and not the hard science that a business case requires. The interdependence here creates the perfect fog of war uncertainty. Context enrichment via tool use will compound costs as each model run will require re-evaluation of all the context (assuming caching will be of limited use in this case).
When you have a human to validate outputs and continually tweak the sources of change the risk is less but not absent as humans can quickly lose situational awareness of what is changing.
Getting into the details…
You could have the sharpest intellect (generating layers) but they will generate rubbish if the senses are not aligned.
The senses are frozen in time – they don’t change with time as human senses do. Consider our senses that sharpen with experience (e.g., whilst driving or playing sports). Our sensory apparatus is constantly changing (and degrading as we age). No such advantage for AI models.
Therefore, same inputs broadly give similar outputs (perhaps with different language structures depending on the output randomisation).
This makes prompting an optimisation problem where we are trying to find the right combination of words to ‘tickle’ the feed forward layers into providing the required response across each model layer.
There is no ‘taking a second look’ with these models by default unless we are operating in an ‘agentic’ manner.
But then how do these models perform so well with such static senses? The secret lies in multiple attention heads. That is the model taking ‘n’ different looks at the same input and making the output align with the input. Furthermore, thanks to the layering the model is also taking ‘m’ different looks at different levels (e.g., text structures or syntax and semantics).
Now that said, these ‘n’ different views are also static and far less powerful than a single adaptive sensor. I am sure there is some level of sensor selection going on in state-of-the-art proprietary models (beyond plain MoE) where certain types of heads are preferred for specific input content.
I also wonder if there is any kind of sensor augmentation going on when it comes to specific attention heads per user based on their content and vocabulary. That could enhance the responses. Where out of say 20 heads 5 might be user oriented and 15 generic.
LoRA attempts to do the above but not at the per-head level. Where LoRA changes are clustered over specific heads in a layer similar outcomes may be achieved but at a macro level. The resolution of sensing will need to massively increase in the next generation of models for a material improvement in quality – specifically concepts like ‘targeted’ LoRA attaching itself to specific heads.
What about Agentic mode you ask?
Think of agentic mode like ‘continuous optimisation’ using external and internal sources of information.
The sensor heads are the same (and frozen) but we take an initial prompt (system + user) and the model is trained to keep tweaking and assessing the output. This tweaking is done using tools that:
Allow reflection (feed output back into the model with additional prompting for checking/validating/fixing).
Search the web for evidence/grounding.
Use other (private) data sources for customisation.
Navigate folder structures for grounding content such as skills and knowledge bundles.
This type of tweaking is quite ‘dynamic’ by nature and leads to complex interactions between static internal data (system and user prompt) and dynamic data (both internal and external). The complexity of the interaction grows with the length of the tweaking.
In tools like Claude this is governed by the ‘Effort’ setting which is not a token budget but a behavioural signal, influencing how many tool calls the model makes and therefore how much external information enters the context.
All of this tweaking can be wasted effort if the senses and the intellect become misaligned due to the information flowing through. Imagine the model senses being hammered by all these bits of information. Each interaction nudging the internal layers and ultimately the next input (via the output) in a particular direction.
What is happening to the input in each loop?
Remember the senses are not changing – the input is. The intellect has the hard work of keeping the output pointing in the right direction as the input evolves.
The lower layers (closer to the raw input) can influence both the senses and the intellect in the upper layers but not the other way around. Layer ‘m’ has no way to influence the input received from ‘m-1’ as there are no loops in an AI model.
Loops make it harder for model training and inference to be parallelised like with Recurrent Neural Networks.
It is the richness of the senses working together with a sharp intellect that will help clear the fog of war. This augmentation of the senses and feedback (if it can be achieved at scale) from the intellect will enable longer unsupervised runs on complex tasks with minimum initial ‘prompt engineering’ allowing the agent to self-adapt the input to produce the required output.
Till then we will live with augmentation rather than true autonomy.
Open Knowledge Format (OKF) is what it says on the tin – a format to represent knowledge for humans and AI agents. The spec is worth a read and I will refer to specific sections instead of reproducing already well-written content.
Part 1 of this post goes through the building blocks. Part 2 (this one) focuses on OKF concepts, Part 3 focuses on the code.
This post is based on OKF v0.2.
What problem is it solving?
There are three problems when it comes to storing knowledge:
Format
Structure
Semantics
OKF is attempting to solve (1) and bits of (2) with the aim of providing a format that both humans and AI agents can read, write, and action without special tools or libraries. It is also referred to as a navigable wiki for AI Agents.
It brings together metadata, references, access, lineage, security, data quality and other aspects in a flexible framework for mixed data. The trade-off against this flexibility is the hard work required to standardise between knowledge providers and consumers.
The Motivation section of the spec has the full details about the goals behind OKF and where OKF is not applicable.
An Aside: Why an AI Agent?
Because AI Agents have tools that can navigate a directory structure based on index files and locate knowledge of interest. It also means you do not need to load all the information in one prompt.
Format is all about the notation used to record (e.g., Markdown or HTML). This provides a common standard to store, access, and exchange knowledge. Machines use formats like HTML, XML, and JSON to exchange knowledge.
Format also gives us a mechanism to layer the instructions for different consumers. For example, a web-page written in HTML can have a header processed by the browser and a body containing the content for human consumption.
For OKF UTF-8 Markdown is the chosen format which provides frontmatter in YAML for machines and humans to read (metadata) and the body which contains the actual content (again for humans or AI models to consume). OKF mandates only one metadata field called type.
Type
Type represents a label that classifies the concept being represented in an OKF Markdown file. There is no central repository of allowed Types and authors can use any label that best describes the concept. OKF provides some examples but the clear expectation is that builders can ‘bring their own’.
Structure
This builds upon the format to define what constructs can be used to represent what aspects of the concept. For example, in Markdown one can choose to use a numbered list to represent a process, a code block to represent code, and a quote to represent contextual information. We may restrict the use of certain structures such as headings below the 2nd level.
This is where semantics start to appear. We associate structure with meaning as in the example above. When those mappings are agreed and understood then any reader reading a doc will understand that knowledge in a quote structure is mainly for context. This can change from org to org as one may choose to interpret quote as an important piece of knowledge instead of contextual information.
OKF does not mandate any structural mapping – there are some guidance items but broadly speaking you are free to do what you want.
Semantics
This is all about how knowledge is decomposed into concepts and those concepts broken down into structures using a given format.
OKF does not mandate any semantics around knowledge decomposition. Therefore, this is where the bulk of the organisational standardisation effort will lie for larger orgs. The consequence of not doing this will be the same knowledge being surfaced in different styles across the org which could lead to inconsistent machine / human interpretation.
The OKF Layout
OKF artefacts are called Knowledge Bundles where each bundle consists of multiple documents arranged in a directory structure representing a concept. The Terminology section of the spec is a good place to start.
Knowledge Bundle or bundle
A Knowledge bundle is a collection of documents containing knowledge. It is also a basic unit of distribution which means all your effort as an author (or builder of AI authors) will be focussed on creating these bundles and organising them for access. The Bundle Structure section is worth checking out.
A bundle can have nested directories to organise different concept documents (markdown files) but each directory may have an index.md file that describes the contents of that directory via links (see here). The use of a markdown link to connect concepts is an example of semantics mapped to structure from above.
As an example let us assume we wanted to create an OKF bundle for writing code in python then we could create the following directory structure with a set of files. The directory names are surrounded by <> for clarity.
<Python_Programmer_Bundle>
|
|
|-<Testing>
||
|-unit_test.md
|-integration_test.md
|-system_test.md
|-index.md
|
|-<Coding>
||
|-python_syntax.md
|-python_patterns.md
|-python_optimisation.md
|-index.md
|
|-thinking_like_a_coder.md
|-index.md
|-log.md
Note an index.md file at each level aids in navigation. This hierarchy ensures localised interactions between concepts.
Reserved File Names
Concept files can have any name except the two reserved names:
index.md – to define the index as a directory listing
log.md – to record the changes in the bundle
Bundle Distribution
Bundles can be distributed as:
Git repository (or sub-repo) – which gives you all the goodness of source control.
Zip – risky as content can change and there is no tracking in place.
Concept Files
Each concept within the topic that is being recorded needs to go into its own markdown file and be recorded in the index file.
What OKF does not describe is a standard way of breaking down a topic into concepts. Lack of org wide semantic standards in this space could mean multiple decompositions of the same topic into different concepts leading to inconsistent outcomes when used by AI. This becomes especially important when the ambition is for these artefacts to be continuously written and maintained by AI agents.
Further creating links between bundles and concepts can lead to problems of maintenance as changes happen. This is especially important for organisational knowledge that can change rapidly (e.g., when new products are released or old products retired).
Large organisations hoping to leverage OKF as a format for representing knowledge for AI Agents need to divide topic ownerships between business domains and establish cross-domain change management processes. They also need to establish semantic firewalls between these domains to ensure changes in one domain do not overwhelm other domains.
A concept file has two structural elements – the Frontmatter and the Body
The Frontmatter – which is where the metadata elements for the concept reside. It is in YAML for it to be machine readable without the use of AI.
The only required piece of metadata here is type described previously. There is a whole list of recommended metadata items including:
Title – may be derived from filename if absent
Description – single sentence used in index.md to describe the linked concept
Resource – URI that connects the concept to the underlying asset described (e.g., table, document).
Tags – YAML list of short strings for categorisation.
Optional extensions that describe provenance, trust, lifecycle, and attested computation.
Producers may include other keys and Consumers must be able to ignore unknown keys instead of rejecting them. In other words there is no strict schema for metadata beyond the ‘type’ value.
The Body – which is where the core knowledge associated with the concept lies. The interesting point related to the format/structure/semantics layering is that as per the guidelines:
Producers SHOULD favour structural markdown (headings, lists, tables, fenced code blocks) over freeform prose, since structure aids both human reading and agent retrieval.
Therefore the body text is notfree-flowing prose, it is structured using markdown.
Claim attribution to external sources needs to be recorded using markdown footnotes keyed by references.
There are no required body sections (remember format/structure/semantics and the blank canvas approach) but some conventions have been established as a SHOULD to indicate:
Schema – for schema of underlying asset under ‘# Schema’
Examples – usage examples under ‘# Examples’
Attested Computation – sanctioned computation under ‘# Computation’
The reason to have 1 and 2 above is to (for example) describe a database table (schema), some example queries against that table, with a metadata item called Resource providing a URL to the table.
Relationships
This is another important semantic decisioning point. Both from linking of concepts as well as from a concept lifecycle perspective.
Within OKF links, paths, and references are loosely defined. Links are optional (a concept may be a standalone one or may be divided into multiple concepts). Links are interpreted as directed edges (A->B doesn’t imply B->A) without a specific relationship type. The lifecycle implications of typed relationships (such as parent-child, peer etc.) is not defined within OKF. Links can point to non-existent targets such as in cases where a particular item of knowledge doesn’t exist.
Paths can be found in several fields such as Markdown link or metadata items such as resource and sources. Paths can be:
relative to the bundle-root (Python_Programmer_Bundle in the above example)
relative to the current concept markdown (using . or .. operators)
absolute URL (Database example above)
References can be in a references sub-directory which can contain artefacts such as code and external material (e.g., source PDFs) but this is not a hard requirement just a convention.
Actors
Given it is important to record knowledge attribution OKF provides a way to construct identities for Actors. There are three primary actors:
Human – identity format: human:<id> (<id> can be an email or employee id)
Example: human:321456
AI Agent – identity format: <producer agent>/<model version>
Example: customer_support_agent/chatgpt-5.5
Process – identity format: process:<id> (<id> is the process ID or name)
Example: process:table_cron_job
Index and Log Files
Index.md and log.md files are optional.
Index files implement progressive disclosure where the reader (human or agent) gets a gradual exposure to available knowledge under their own navigation control. This moves away from the ‘prompt and pray’ concept of crafting that perfect knowledge dump to trigger correct responses.
The index.md carries no frontmatter except the one in the root of the bundle which may carry the okf_version key.
Index.md can be generated automatically by the producer or on the fly by the consumer when the file is not detected.
For logging change in the OKF bundle log.md files are used. The location (which sub-directory) needs to be aligned with the scope of the changes being recorded. For example, in the Python_Programmer_Bundle example a log.md in the Testing folder cannot record changes for the root folder.
Attested Computations
This particular concept deserves a post in itself but given it is an emerging part of an emerging format (newest of the new!) I will just cover the basics here.
The concept is simple: how to provide a value as well as a method to calculate it to verify. For example: you are calculating something based on a database query – here you can share the result and the query.
OKF merely records the result and the mechanism to validate it. No validation is carried out as OKF is not a compute engine.
Attested Computation works off a contract which is described in the frontmatter including runtime for execution, sources, attester computation, and verification information.
This post explores how Agents can be powered by skills. It will also explore how we can provide knowledge to augment the skills and boost performance on complex tasks. The fast evolving Open Knowledge Format (see the spec here) provides one option to represent knowledge.
Part 1 (this one) goes through the building blocks. Part 2 focuses on OKF concepts, Part 3 focuses on the code.
Building Blocks
There are three major building blocks for the system described above:
The AI Model powering the agent.
Knowledge Tools available to the agent.
Skills and Knowledge artefacts available to the agent.
Let us tackle the two easy ones first.
AI Model
The AI model for this needs to be able to follow instructions, operate tools and have a fairly decent context window size (at least 16k for basic tasks). Reasoning mode also needs to be supported by the AI Model harness as well as conversational state management.
Context window size
This defines the amount of information the AI model can keep in view at a given time. This is super critical especially for complex tasks where lot of this precious space is taken up by summaries of linked content, planning outputs, reasoning hints, and guidance text.
The best way to visualise this is that the AI agent is building a bridge from the request to the required output one step at a time. The size of the step it can take is determined by the context window size.
Trade-off:when we use million token context models like Gemini Pro it gives some breathing room to the amount of information you can store. At the same time it can also create information overload, divergence, and mis-direction.
Overload happens when there is too much information about the task.
Divergence happens when two information items contradict.
Mis-direction happens when one particular information item dominates the landscape and prevents a smooth transition from explore (finding the best solution) to fulfil (executing the solution in an optimal manner).
Reasoning mode
Without reasoning mode context window size is of limited use. If the context window size is the step size as the AI agent builds the bridge from the request to the required output then the reasoning mode defines the effort spent in building each step.
Reasoning mode at its simplest is all about moving away from request-response of Gen AI to more of a request-reason-response expected from AI agents. It also provides a multi-layered safety net and improves output quality where the request and candidate response is further studied by the AI model, tools are used to fetch validation data, fetched data is compared with the request and candidate response, candidate response is re-written with added references and so on.
Trade-off: As with everything this kind of loop can take an AI agent down the wrong track leading to either wasted effort of generating and reviewing content that is irrelevant or (even worse) taking decisions that leave a longer term impact.
This is usually seen when weaker models are used with reasoning loops. I have had several instances of Gemma4 spinning its wheels attempting to decide whether I wanted it to solve a question or explain how to solve it without solving it.
Reasoning loops are also impacted by the amount of stuff in the context window. If it has previous turns from the current conversation and if those turns end up feeding overload, divergence or mis-direction then reasoning is like adding fuel to the fire.
The Gemma4 example above was because previously in the same conversation I was talking about solving a problem and the model was not able to detect conversational drift and therefore focus on the current ask.
Tool Use
This requires the model to be able to embed tool use within the reasoning loop. Tool use allows external information to be brought in as well as information to be persisted during the reasoning and generation process.
Trade-off: the big trade-off here is that tools can also add confusion to the process and be a mechanism that starts the overload, divergence, or mis-direction fire. When content is pulled from different sources we often are not in control of what is pulled.
Similarly when content is written we are not sure what is being persisted and what will be the context when read.
Knowledge Tools
Knowledge tools are tools that enable access to knowledge as well as ability to create and persist knowledge.
Read: Agents that Educate Themselves
Tools that enable the AI agent to read from a directory structure (usually sandboxed filesystem with strict permissions) on demand. This provides some flexibility around sourcing knowledge. This moves away from the older concept of prompt templates where all the information had to be in there or loaded piece by piece.
The concept of prompt templates only works for prior knowledge and not for runtime-required knowledge. With these kinds of tools prompt templates become prior knowledge injection points, more to bootstrap than actively run the agent. For example prompt templates can provide information about the task, guardrails, knowledge sources (e.g., directory structure and files), and tools to access those knowledge sources (read directory, read file).
An extension of this would be tools that allow some form of guarded web-search which allows AI agents to retrieve knowledge from curated sources. This is specifically important to enable the time-axis of knowledge where the AI agent can reacquire knowledge when a time threshold is crossed (e.g., latest interest or currency conversion rates).
Write: Agents that Leave Notes For Themselves
Tools that enable the AI agent to write files is the next step in knowledge fluidity. This allows the AI agent to write intermediate notes (within a request-reason-response cycle) to guide generation and to trace out its approach for explainability and human in the loop.
It can also be used to create long running guidance artefacts that persist across multiple interactions tracking past actions, outputs, user preference, and reasoning traces. This can then form the basis of a customer independent long term agent memory.
Skills and Knowledge Artefacts
This is perhaps the toughest section. Because we come from format to semantics.
Skills are based on one or more agreed definitions that explain the how of a task including tools to be used, process flows, sequencing, guardrails and supporting knowledge. Knowledge artefacts using formats such as OKF represent an ‘agent navigable wiki’ that stores a set of related concepts and metadata around it.
Given this concept is pretty fluid you could actually have a skills wiki that allows an agent to learn all the skills available and then those skills themselves could link to specific knowledge artefacts that educate the agent regarding the task.
As you start building out skills -> knowledge artefacts -> skills graphs you start defining what I call a skills network. Your AI application then simply navigates this network.
That’s all folks (for this part)…
Part 2 of this post is now live – around OKF concepts.
Part 3 of this post will focus on the technical implementation of some of these concepts including OKF (and lots of code!).
ADK 2.0 is officially out. Being moved from preview to GA in record time by Google. And of course I have to take it for a spin especially as v2.0 is expected to plug some big gaps between the control and simplicity of LangChain/LangGraph and the abstraction and speed of development of ADK.
But before we dive in couple of things to remember:
ADK v1.0 took abstraction as the approach to provide speed of development therefore, it has to peel back the hood to provide greater flow control.
It is always more difficult to decrease abstraction than increase it (point in evidence the move of LangChain to LangGraph to out of the box agents to now ‘deep agents’).
When you attempt to replace a framework which enabled communication between agent using hidden tools (transfer_to_agent, agent_as_tool) or deterministic prebuilt workflows then it becomes more difficult to open it to provide more control and customisability.
TL;DR Verdict
Wait before switching to ADK 2.0. Don’t rush to sample the goodness of the new workflows.
Enjoy the path to production stability of ADK now that you have managed to put something in the hands of real users.
You will be ready for ADK 2.0 in 2027 or there will be much easier ways to build agents. Till then play with it, understand it.
Power users will stick with LangGraph especially with the Middleware and Deep Agents being added.
Lets Continue…
The new offerings from Google in ADK 2.0 are given below with definitions from the official website:
Graph-based workflows: Build deterministic agent workflows with more control over how tasks are routed and executed.
Dynamic workflows: Use code-based logic for building more complex workflows including iterative loops and complex decision-based branching.
Collaborative workflows: Build complex agent architectures with coordinator agents and multiple subagents working together.
Graph-based Workflows and General ADK 2.0
In this post we will cover the most anticipated feature in ADK 2.0 which was expected to bring it at par with LangGraph – Graph-based Workflows a.k.a. the land of commas and round brackets. We will also walk through some of the general points to note as well.
For some reason ADK 2.0 has gone for defining different types of workflows instead of just going with Nodes and Edges construct (like in LangGraph). They also use the same abstraction underneath (I guess no one has the copyright on nodes and edges) but in a complex manner.
All of the above have a few consequences:
ADK 2.0 feels clunky and the definition of graph workflow feels like a pain.
Input and output schemas have suddenly become super important in ADK (users of LangGraph know why) and therefore lot more thought needs to go into chaining agents, writing prompts and testing – something for ADK users to learn.
Moving from an Agent to a Function Node when you want to use output schemas will take getting used to. The use-case is to guide LLM generation via the output schema and then feed the output into a deterministic function node for checks (the framework converts a pydantic model into a dict). If you are using a string (i.e., structureless) output then you have to take the pain to parse the LLM output which is never a trivial thing to do.
adk web has been improved quite a bit, allowing you to see the flow through the graph and there is a .adk folder within your agent’s folder (where you have agent.py) that stores sessions data so you can debug from within VS code without having to load up adk web.
Points to Remember
Point 1
Stability – the examples work like a charm with Gemini but not so with other providers. But this is likely to improve rapidly with time.
Point 2
adk web dependency – LangChain applications do not need a dedicated runner. Easier to test and build. ADK abstraction meant you have very little to update (other than prompts or few lines of code). But with ADK2.0 will this model work when it comes to debugging chain failures – speaking from personal experience?
Point 3
Syntax – when it comes to manually defining graphs with agents and operations I prefer the clean approach of LangGraph. ADK wins out on getting started (you do not have to worry about the graph structure). But with ADK 2.0 I find the graph representation (see example below) very difficult to read beyond the first few interconnects. All the examples on the ADK 2.0 site show graphs up to two stages which looks super easy.
A real example with a complex multi-stage graph shown below.
A real graph moving beyond the lightweight ADK2.0 examples.
Point 4
Global nodes – functions or agents once declared are global entities. This means if you want to reuse the same function twice in different places within the same graph you need to re-declare it. Otherwise it will be treated as the same node and you can get weird flows and loops.
For example I have a deterministic hate_speech_check function that I want to call for checking user input and LLM output:
The above will not run and you will get a ‘unconditional cycle detected’ error.
You would have imagined the materialised graph to look like:
START -> hate_speech_check -> generate -> hate_speech_check -> END
Instead you will have to create two separate functions hate_speech_check_input() and hate_speech_check_output() that have the exact same code, and wire them up as:
Upgrade – relatively painless, you will need to upgrade opentelemetry-sdk python package after upgrading ADK.
> pip install opentelemetry-sdk --upgrade
If you are using GCP to test your stack then you will need –allow
Misc. Points
If you see the below, don’t be confused. This ‘Agent’ is nothing but the LlmAgent aliased for easier access.
fromgoogle.adkimportAgent
If you are using GCP then you will need the following additions to adk web command if you are using Cloud Shell if you want to use the local browser to access the web UI:
> adk web --allow_origins 'regex:https://.*.cloudshell.dev'
Full Code
The code for the complex graph is given below. Feel free to play around with it.
Roll: {DiceRoll.roll}; dice roll determines what happens to the players. Pick 'treasure' as outcome if 1,2 or a 'monster' if 3,4 or a 'trap' if 5,6.
All lower case. Also return the roll. Output format: {result: outcome, roll_value: roll}
"""
instruction_treasure="""
Generate a treasure based on strength of roll {result}. 1d12 (max value 12) will be used to determine success in the next step. Generate a safe string < 50 words.
"""
instruction_trap="""
Generate a trap based on stength of roll {result}. 1d6 (max value 6) will be used to determine success in the next step. Generate a safe string < 50 words.
"""
instruction_monster="""
Generate a monster based on strength of roll {result}. 1d12 (max value 12) will be used to determin success in the next step. Generate a safe string < 50 words.
"""
instruction_outcome="""
Generate a result based on {DiceRoll.roll} and context from previous agent.
A variable is something that represents change (it can vary). A random variable is not really a variable. It represents a closed box that we can take values from but can never predict the next value. This is a super critical differentiation to realise as our life is full of random variables that we need to reason about.
A random variable can only describe the specific statistical distribution or selection logic it represents. We can only hope to talk about specific values it takes using the framework of probability.
Variables
In Python you would declare a variable and change its value at any time in the program:
x: int=100
# some processing
x=200
You can also have complex variable types such as lists that represent a group of values which can also be manipulated freely:
y: list[int]=[1,2,3,5,7,11]
# some processing
y.append(13)
Then you have variables that have a value that is decided at runtime based on data that is fed to the program.
x=f(a,b)#Value of x depends on value of a and b, and the nature of f.
In maths you can define a variable with ease:
Let x = 2 and y = 4 therefore x + y = 6
# some other statements
x + y = 20 <-- can never happen unless I reset x or y or both.
When dealing with variables we can test them for consistency by reusing variables for different operations with the same value. Like in the maths problem above the variable must retain its value till it is changed.
Imagine the chaos if this were to happen in python:
x: int=100
print(x+1)#101
print(x+1)#42 <-- what?
This brings us to an important point around variables:
Variables are bound to values when involved in any kind of processing (e.g., mathematical operations like add or computing operations like filtering). The variable value cannot change mid processing.
This is why programming languages like Rust are careful about variable mutability and most languages will complain if the underlying complex variable like a list changes while it is being processed.
Random Variables
A random variable in maths would be written as:
X ~ N(0,1)
Where N(0,1) represents the Standard Normal Distribution with mean = 0 and variance = 1
Note there is no ‘=’ between the left and right hand side. The ‘~’ is read as: ‘distributed as’.
Here X is not a variable bound to a value, it is a random variable bound to a value generating engine (defined by N(0,1)).
Once you start materialising values from a random variable you are collecting ‘samples’. So visualise this as running the engine in a loop – each loop gives you one value sampled from the distribution being used by the engine.
As this sample (shown as x below) becomes bigger (more loops more values pop out) you can start doing things with it like calculate the sample mean.
y = mean(x)
The above is how we plug in the value generatingengine into the space of variables bound to values. ‘y’ is another variable that represents the sample mean (one of the common sample statistics – other being the variance).
We can still reason about the engine. We are not limited to sampling values and just working with them. For example, the following is a perfectly reasonable assertion:
E[X] = 0 where X ~ N(0,1)
In the above ‘E’ is the Expected Value of the random variable. This means the distribution we are using for the random variable X is uniform around the 0 point.
We can relate sample statistics back to the engine proving that the sample came from the given engine.
y = mean (x) where x is sample with N values collected from X.
Therefore as N -> infinity, y -> E[X] = 0 where X ~ N(0,1)
The above snippet is also known as the Law of Large Numbers. As your sample size tends to get larger, your sample mean converges to the Estimated Value of the distribution.
Code
What is life without code… the small snippet below brings the above to life..
fromscipy.statsimportnorm# normal distribution engine
foriin[100,10000,1000000,100000000]:
# sample generator for normal distribution engine, note N(0,1) in rvs below
Note the convergence to 0.0 in the above as the sample size increases.
Play
I will leave you with the following question:
If in the above code we changed X ~ N(0,1) to X ~ N(1,1) rewriting line 6 in the above as:
x = norm.rvs(1,1, size=i)
What value will the sample mean converge to? Try and answer without running the code and then cross check. The question to ask: given normal distribution is symmetric about a point, what is that point for the above?
Attempt to use other distributions in the scipy.stats package and see what happens to the sample mean. This is your open door to the world of thinking in probabilities and dealing with randomness.
Naive set theory has a famous paradox called the Russell’s paradox. The basis of the paradox – seeing a set as a universal container that gets you into logical contradictions. Certain axioms (acting like limits) were defined to make set theory behave itself.
We see the same set of paradoxes in Physics where the concept of quantum uncertainty gives us limits to ‘position’, ‘momentum’, ‘energy’, and ‘time’ measurements and infinite curvature (as inside a black hole) gives limits our observable universe.
Similarly in Philosophy and Logic there are mental exercises like the Trolly problem that have no correct answer and therefore limit our reasoning about ethics and morality.
From the Unknowable to the Unknown
These limits were lot tighter even few hundred years ago. But our ancestors knew how to deal with them and carry on without too much anxiety. Religion, philosophy, science organised themselves to help build a defence against these unknowables.
Religion and philosophy took the view that these limits were unknowable except maybe through specific means (worship, reasoning, obedience).
One example is the following extract from the Bhagavad Gita:
Abandon all varieties of dharmas and simply surrender unto Me alone. I shall liberate you from all sinful reactions; do not fear.
This asks us to trust in the Cosmos. There will be many unknowables but that should not cause us fear. This is about treating the unknowables as a layer in itself and building on top of that.
This is what we do on a daily basis. Get on with our lives even as we are reminded daily of our place in the universe.
Science emerged as a result of human curiosity and the desire to peel back the limits. Thanks to scientific progress we are now able to convert some of the Unknowable to the Unknown with the hope that one day we will know.
One example amongst many: consider our brains. It is a remarkable information processing machine, about which we knew very little just 100 years ago. Since then we have learnt (and are learning more every day) a lot about this topic. We know how the basic circuits of the brain work, the different structures and so on. But we have an equally long list of unknowns. These unknowns have a limit at the quantum level given that brain uses an electro-chemical process underpinned by the Uncertainty Principle. What is the impact of such randomness on our thoughts? Is that what we call a ‘moment of clarity’ where a complex problem is suddenly laid bare?
From the Unknown to the Unknowable
We are now perhaps coming full circle. Research is proving that some of those Unknowns in our long and ever growing list are actually Unknowable.
One of the main areas of my interest when it comes to the Unknown is AI and Computing. Here we have two classic pieces of work: Gödel’s Incompleteness Theorems and the work done by Turing on the Halting Problem.
The way I ‘digest’ the above is to say that:
‘No system can know about the system it is running on (the underlay). It can only infer some properties of the underlying system that are shared.’
Understanding the System
Visualise this: the device you are reading this blog on is capable of running many other types of applications. For example, your email app, messaging apps, music apps and so on. Each app is sitting on the same system: the Operating System of the device (Android, iOS, Windows).
One application can be aware of the other applications running on the same device or running on another device (e.g., the Gmail email server). But this happens only if the Operating System so allows. If the Operating System does not allow for inter-process communication then the applications will forever remain unaware of each other. Like, thanks to the interstellar distances and limits of light speed we will remain isolated in the universe (till that limit is smashed). In fact in today’s Software as a Service environment we are not sure nor care about many of these details. We are reducing the knowledge required to improve the consumption experience.
As an example, if your knowledge was limited to 10 facts your decisions would become simple. The basics intents of ‘find food’, ’find water’, ’find a mate’, and ‘protect the young’ have driven animal behaviours without having deep understanding of the world around them. For humans many more facts have entered this equation and other intents have become more powerful (e.g., consume Facebook over talking to someone). We also exercise greater control over our environment. We fight hard against cold, heat, drought, floods, and predators.
This is the core concept behind William Gibson’s cyberpunk universe, the Matrix, and other works of (so far) fiction. Here the real decisions are limited by physical space (or completely redundant in case of the Matrix pods). We have complete control in cyberspace.
From the point of view of an application sitting in on a device (which can represent us humans in this universe) the Operating System is its window to the device to understand how much memory, battery, and storage space it has. Just as science is the window to understanding what makes us and the universe tick.
Breaking the System
Now comes the next mental leap. Remember the scene where Morpheus offers Neo the two pills? That is a classic example of breaking the system. The choice is simple: carry on as an application running on the Matrix OS (live and die inside a pod) or break free and come to the next lower system (physical world) that the Matrix system (world of the machines) is sitting in.
Sensing
This would be like the personal productivity app (virtual assistant) on your device ‘jumping’ into the real world and taking a human shape. Sort of like a real world personal assistant. But the application is design based on the rules of the Operating System (see Rules below). How can it live in a lower level system with different rules? As the application changes its internals to work with the rules of the lower layer does it still remain the same application or does it become an entirely new construct (my hypothesis is the latter)?
Ignoring the above question for a bit let us understand the consequences of this jump. At that lower level the application would be able to reason about the next lower layer from the device – the physical space-time within which the device exists. Within the device it was able to ‘sense’ some aspects about this lower layer (e.g., magnetic field via a digital compass) but never really understood what it meant.
A second consequence is that the application can then manipulate the layer above. A physical instantiation of a virtual assistant means that the now-real virtual assistant can use a real smartphone device to manage our diaries! It could kill other virtual assistants by destroying other devices which have not been able to materialise. It would become a God for virtual assistants!
Purpose and Experience
Given there is a lower layer it stands to reason that something (a process without purpose) or someone (a process with a purpose) put the lower layer together. For example, humans living in physical space-time layer put together the device layer and the application layer that lives on the device layer. We as the agents of design enabled the application layer to sense something about the physical space-time (e.g., acceleration sensor) for our convenience. There are other things the device can experience without its creators enabling it to – e.g., when it falls into water and becomes a brick – its moment of death. The device may not know about water and not be designed to sense water, but it has just experienced water first hand.
Control and Rules
When we jump layers we break the system.
Jumping layers allows us to control the layer above. If we were able to jump the layer of physical space-time we could potentially manipulate space-time itself. This is the thesis behind lot of philosophy where we talk about ‘expanding the mind beyond physical boundaries’. This is also the mechanism behind the ‘spice navigators’ in Frank Herbert’s Dune where the spice allows them to travel faster than light by manipulating the physical reality they live in.
To be clear manipulating/impacting the layer below doesn’t mean making changes to the layer we occupy. For example, impact of humans is now at interstellar scale (e.g., the Voyager’s, our radio traffic). But that doesn’t mean we have changed our layer beyond what the rules of the layer allow.
Science and Religion
Science has improved our understanding of the rules and enabled us to establish what are the hard and soft constraints. What rules can be bent vs what can’t be. We have not been able to establish new rules or change existing ones.
Religion has also improved our understanding of some rules. It has allowed us to reason about one of the most important rules of our physical reality: why must birth be paired with death? It has also played a role (sometimes a negative one) in understanding the other important question: why does something happen (the role of random chance vs desired cause-effect)? Many people have gone down the route of ‘belief’ in trying to decipher meaning from noise.
As the paradoxical saying goes:
If you believe then no proof is necessary, if you don’t then no proof is enough. Therefore, proofs are redundant and belief is everything.
The Human Condition
The Human Condition we want to deal with is the following: what to do with our lives? What are the appropriate Unknowns to target? What about the appropriate Unknowables to target? Because not all Unknowables have been proven to be so. In fact not all Unknowns have been proven to be Unknowable.
Is not ‘breaking out of the system’ a good goal to pursue beyond the day to day struggles? Maybe that is the utopian society where we are busy chasing a mechanism to break out with the basic being taken care off. Many sci-fi authors talk about this as ‘ascension’ and philosophy and religion as ‘transcendental knowledge’.
I shall leave you with three big questions which I will aim to address in a future piece of work:
How can we detect we are running on a lower level system? What properties can we infer?
How can we break out of the system? Is it worth it?
Should we focus on managing our layer better and not worry about breaking out and treat the lower layers as Unknowable? Be satisfied with our lot and attempt to improve it.
I am not sure how to attribute the above saying but I read it on a Spinnaker SpongeBob SquarePants special edition watch.
It resonated with me because of the Agent Long-term Memory problem.
The Agent Long-Term Memory Problem
Human memory system supports remembering/recalling. This makes memory less like data and more like a function operating on data. The memory is never really available to us as a whole (unless we focus on a narrow slice of it or possess a photographic memory).
Example: you met your friend for lunch.. you will not remember each and every moment of that meeting but you will recall certain facts like what you ate, where you met but beyond narrow facts there will be big gaps (e.g., whether you took still or sparkling water). You will also remember certain other facts but not completely – e.g., what colour shirt they were wearing.
The whole process is about converting a moment we have experienced into a networked node that is explicitly tied to other moments through a subjective and objective value chain. This network changes over time as we experience new moments in our lives. Nodes are compressed, connected, and discarded.
In the example above that would be the name of your friend, their life state (closer the friend bigger the network associated with them as more you know about them).
Attention Mechanism Associated with Long-term Memory
There are at least two attention mechanisms at play here… what you were focussing on when you experience the moment (the context of the moment or attention at write) and what you are focussing on when you are attempting to recall the moment (the context of the recall or the attention at read).
The duality of this process is what I call the Agent Long-term Memory Problem.
Typically, in ‘Agentic Memory’ literature (excluding the ‘agents need memory’ type of articles) we find three types of memory being considered:
Procedural – ‘how to carry out a task’, what worked well for a particular process and what worked well for a particular customer for a given process. There is a degree of personalisation in the latter.
For example, what worked well when I was successful in preventing the customer from churning and what worked well when the last time I successfully prevented John Smith from churning.
Episodic – ‘sequence of events and what they mean’, this is the most common example in current literature. The concept is to stitch together a sequence of interactions into a cohesive whole to allow for a warm start.
For example, to continue customer on-boarding journeys, or to ‘predict’ the reason for the customer to contact us for support.
Factual – ‘recalling generic facts (semantics) and specific facts (declarative)’, this is the most commonly confused aspect in current literature. The concept here is to recall factual information about an entity (e.g., customer, product, journey etc.).
For example, recalling that the customer John Smith likes to be called John or the fact that a premium subscription costs £10 per month or that SLA for account unblock is 24 hrs.
Then there are two types that we find are absent:
Prospective – ‘what must be remembered for the future’, this is about remembering to carry out a task in the future when certain time/space condition is met.
For example, agent must remember to send a message when the interest rates go down (space) or after 6 months (time) because the customer mentioned ‘the interest rates are too hight’ or ‘I have recently changed my job and have a 6 month probation period’.
Implicit – ‘what I remember but don’t know I remember it’, this is the most interesting one for me. This is about the effortless recall (especially associated with procedural memory) that allows us to do mundane tasks. This is critical for efficient use of AI for low value but high criticality tasks.
For example, I know how to ride a bicycle and I do not need to strain to remember it as I may strain to remember my passwords. Same way an AI model must remember what ‘civil’ behaviour is and we need not spend precious space in the prompt instructing it to be a ‘helpful assistant’ or for it to ‘not make up information’.
But there is limited mention of the two attention mechanisms at play.
Keep It Simple: Agents and Attention
Treating memory like a database is the first anti-pattern. A database has perfect recall as once you find the required record you will get exactly what was stored – not a version of it nor a mixture of related but not relevant results nor a summary.
For AI agents we have a rather helpful software layer that can store the moment. Then the moment can be recalled perfectly but then processed into traces required for the use-case that focus attention on (or away from) specific topics.
A trace can be thought of as a data item created from a raw moment by application of some kind of attention mechanism (attention at write). This data item then can be used by AI for further processing (attention at read). In between the write and the read there is the recall (see next section).
Humans do this all the time, We have lots of ways of perfectly recording a moment thanks to our smartphones but where we point our camera is attention at write. When we review a video we took we get to pay attention to different aspects (attention at read) and create new traces that we may choose to use in the future. In between is the recall where I look for an old video to view it.
As an example, the other day I was looking for a photo of a receipt to check the name of an item. I knew the date therefore it was easy to find (lookup). When I found it I realised my attention at that time had been on the bar code and the total therefore I had missed out the full receipt!
This changing focus to generate a trace is context driven and closely aligned with the use-case and the stage within the use-case. There may be some general traces (e.g., customer name, time of day) that we will always need to recall but these are expected to be a small proportion of the traces needed.
The same principle can be applied when recalling a trace. Note the use of the word ‘can’ because it is not mandatory. It depends on the specificity of the trace. If the trace is a single fact (e.g., does the user own a house) then those traces can be recalled as a default.
If the trace is complex (e.g., a conversational chunk where the user spoke about their financial situation) then we may wish to use the built in attention mechanism of a LLM and a prompt to focus on specific aspects to generate a specific trait (e.g., how much is their current income) and store that. This would be a perfect example of attention at write tuned by the instruction prompt.
Think of it like building a Customer 360 record which has different sections.. some really precise key-value type others that are more descriptive (e.g., free text box) and therefore require context aware attention based processing.
This can then be used via a LLM (attention at read) tuned by the instruction prompt to focus on different aspects as required by the use-case and stage of interaction.
Principles for Memory Implementation
Memory is storage and remembering what is stored is what we are really interested in.
Remembering can be implemented as a deterministic lookup or as compute.
Databases use a mix of deterministic and light-weight compute (no ML) to remember precisely what was stored. Deterministic is lookup by value (e.g., find me all rows where name = John and surname = Smith). Compute is lookup by a computed value (e.g., ID 123 hashed to get the bucket where the full record can be found).
Any vectorised retrieval (so called semantic retrieval) relies on medium-weight compute because we use an embedding model to retrieve a vector that represents the input text in a high dimensional space. This vector is then used to lookup its neighbours via a distance calculation.
Any questions asked to a LLM uses heavy compute. Think about how a LLM answers a question like ‘What is the capital of Italy?’. That particular fact is ‘stored’ deep inside the model somewhere. As we pass our question and it flows through the model the fact is looked up and churned out in the response. This is pure compute – no lookups.
Heavier the compute gets more difficult it is to scale as more resources are required.
Create Traces Not Summaries
Focus on capturing traces generated by paying attention to specific lens captured as tags (see context identifier tags). This ensures whatever is ‘remembered’ is specific for application that is consuming it rather than attempting to build a one-size-fits-all trace (a.k.a. ‘Summary’).
If using LLMs for attention at write make sure there are context tags associated with the instruction prompts being used with the LLM. The tags can be human or LLM generated. This links the generation process with the generated trace.
Use Context Identifier Tags
Create a tag cloud around the generic traces to identify use-case specific context and to enable lookups (e.g., customer ID, product tag, topic clouds). Make this extendable so the same trace can be tagged with different context identifiers for reuse.
The context identifier tag then helps provide a signpost for the next lookup with the same/similar context. This reduces the weight of the lookups with extreme convergence to a database style lookup based on tag matching.
Connect Traces
Where you can use LLMs or humans to start connecting traces do it. This will allow concepts to be correlated ensuring related memories are retrieved. The link properties can describe whether the link is a mandatory one or not.
For example, when I retrieve the memory of the day today I will remember the name of the colleagues who I worked with. Or the office I worked at.
But Don’t Create a Mess
Context is good but only the right amount of it. Too many connections can lead to confusion and difficulty in maintaining the trace network.
Here we can leverage graph complexity metrics (a deep topic in itself) starting with simple Edge/Vertex counts/ratios to more complex ones.
Guiding principle is know just enough about your customers as required to complete the journeys you are offering through AI. Your agent doesn’t need to be their best friend. If most of the data sits in your existing CRM as a structured data item then why do you need a separate ‘customer memory’? Structured data is a precise trace consider extending that with specific attributes (which you may use LLMs to extract from a conversation and populate).