Government AI - Simulating a Government Cabinet with n8n, Ollama and Qdrant

Government AI - Simulating a Government Cabinet with n8n, Ollama and Qdrant
This might be the future of governments
NOTE: All the code used in this post is available at the cabinetAI repo.
NOTE: The workflows are in constant evolution. While I'll try to keep this post updated, please be aware that you might find some slight differences in the workflows.

AI Agents are everywhere. It's a buzzword and a promising technology. While much of the hype is likely not justified, there's no doubt AI Agents have their place in this world.

A key advantage of agents is their ability to narrow an LLM's scope, enabling it to better embody specific expertise and more effectively utilize tools like scoped Retrieval-Augmented Generation (RAG) on targeted subsets of documents. Once these specialized agents have collected and generated sufficient data, one or more orchestrators—typically other LLM agents—can then iterate over the diverse results to produce an output that a single LLM could not achieve independently.

The topic is vast and complex, and delving into its full intricacies is beyond the scope of this blog post. Therefore, I will concentrate on my specific use case here.

Long story short, I pondered whether an AI could effectively assist in governing a state (setting aside the ethical considerations of whether it should), and if so, how. Given that a government is typically a complex machine with numerous interconnected parts, I concluded that an agent-based approach might be the way forward.

As those who follow my work know, and as a member of the EFF, I am a strong advocate for self-hosting and privacy. Consequently, I challenged myself to create something that is both functional and privacy-first.

Tools Choice

n8n

While searching for an intuitive and powerful canvas on which to build my agents, I stumbled upon n8n. Beyond its considerable popularity and robust community and official support, I was particularly attracted by the ability to self-host an almost fully-featured instance.

To achieve this, I simply followed their self-hosting guide, opting for Docker due to its simplicity. A detailed setup guide is beyond the scope of this post, but their tutorial is straightforward enough to make the process quite intuitive.

Ollama

When it comes to running LLMs locally, Ollama is a common, almost default, choice. Of course, this requires a sufficiently powerful machine; otherwise, you would likely opt for the OpenAI API or another provider, adapting the rest of this post by replacing Ollama nodes with the corresponding ones for your chosen service.

For this specific task, I experimented with various models. On my NVIDIA 4070 Ti Super (16GB VRAM), the best-performing model turned out to be a rather exotic one: Llama-3.2-8X3B-MOE-Dark-Champion-Instruct-uncensored-abliterated-18.4B-GGUF. Confused? I certainly was when I first encountered it. Essentially, this is a heavily modified Llama 3.2, an ensemble of eight Llama 3.2 3B LLMs merged into a Mixture of Experts (MoE) model, totaling 18.4B parameters. TLDR: It's relatively lightweight, remarkably intelligent, and very fast compared to models of similar size.

Qdrant Vector Store

I had never worked with a vector store before and, to be honest, wasn't entirely sure what one entailed. From my current understanding, a vector store is a specialized type of database designed to contain—you guessed it—vectors. These vectors are numerical representations that LLMs use to interpret and understand language, by assigning these numbers to text segments and words.

Numerous vector store services are available, many of which are self-hostable. I opted for Qdrant primarily due to its native integration with n8n and its general ease of use. Their self-hosting guide is essentially all you need to get an instance of Qdrant running on your own server and leverage it within your n8n workflows.

Designing the Workflows

While designing my AI Government Cabinet, I soon encountered a few complications. Firstly, I recognized the need for a central workflow to orchestrate user input and manage dispatch to the various 'ministers.' This became the Government Main Flow workflow, which houses most of the logic for managing the different departments and their respective ministers.

The 'ministers' themselves operate similarly to one another; however, each requires distinct instructions and must access both common and specific knowledge bases. For this reason, I created the Government Agent with KB workflow. This workflow is designed to be reusable, employing the same core n8n nodes dynamically configured with different variables for each minister, allowing them to access their designated knowledge.

Regarding the knowledge base, I also needed a simple workflow that could be executed on demand to populate or update the vector store with the desired information. This resulted in the Government KB Ingestor workflow.

The Nerve Center: Government Main Flow

The Government Main Flow is the central nervous system of our AI simulation. It's designed to take a user's query, intelligently delegate it to the relevant AI "ministers," and then synthesize their collective wisdom into a coherent response. It’s a multi-step dance of logic, all orchestrated within n8n.

Here's how it unfolds:

1. The Public Entrance (When chat message received)

Everything kicks off when a user interacts with our AI Government via a chat interface.

  • What it does: This chat trigger node, titled "AI Government Cabinet," is the front door. It welcomes the user with an initial message, setting expectations about this being an early-stage agentic system and mentioning that the AI has some foundational knowledge (like the Italian Constitution and Human Rights Declaration). It also wisely cautions that responses can take a while due to the complex thinking involved.

2. The Chief of Staff (Secretary Agent)

Once a query is in, it's not just thrown at any AI. First, it goes to the "Secretary."

  • What it does: This crucial node is an LLM agent. Its system prompt tasks it with acting as the central dispatcher. It needs to:
    • Analyze the incoming request.
    • Pinpoint which of the nine available ministries (Finance, Foreign Affairs, Home Affairs, Health, Education, Environment, Justice, Defense, and Technology) is best equipped to tackle it.
    • Craft a precise, actionable sub-task for each chosen ministry.
    • Finally, it outputs this delegation plan as a structured JSON object, including a summary of the original request for later review.
  • Under the hood: This agent uses our chosen local LLM, configured for precision with a low temperature (0.2) and set to output in JSON format, which is vital for the next steps.

3. Preparing the Ministerial Briefs (Call to Action Node)

The Secretary's JSON output, detailing which ministers to activate and their tasks, is then processed by a Code node.

  • What it does: This node, aptly named "Call to Action," unpacks the Secretary's instructions. For every minister identified in the delegation, it creates a distinct data packet. This packet includes the specific task_for_minister, the overall_context_for_review, specific guidelines for how the minister should structure its response (e.g., include 'name_of_the_department', 'task_result', 'rationale', 'annotations'), a moderate temperature setting (0.6) for the minister's LLM, and the context window size. If the Secretary decides no delegation is needed, this node flags it.

4. Directing the Flow (Minister Dispatcher Node)

With tasks neatly packaged, the "Minister Dispatcher" takes over.

  • What it does: This is a Switch node that acts like a government switchboard. Based on the minister_to_activate field in each data packet, it routes the task to the correct sub-workflow representing that specific minister. There's a dedicated path for each of our nine ministries.

5. The Ministers Get to Work (Executing the Government Agent with KB Sub-Workflow)

Each path from the dispatcher leads to an "Execute Workflow" node (e.g., Minister of Finance WF, Minister of Home Affairs WF1, etc.). These are the individual ministerial offices.

  • What it does: Despite having different names, these nodes all trigger the same sub-workflow: the Government Agent with KB. The clever part is how they trigger it. Each minister's node injects a unique system_prompt into this sub-workflow, effectively giving that instance of the sub-workflow its distinct personality and area of expertise.
    • For instance, the "Minister of Finance" gets a prompt about managing the national economy and public funds. The "Minister of Education" gets one about overseeing the education system, and so on for all nine specialized roles. They also receive the specific task, overall context, and LLM settings prepared by the "Call to Action" node.

6. Cabinet Meeting: Gathering Reports (Collector Steward & Steganographer Nodes)

As each minister (sub-workflow) completes its analysis and generates a report, we need to gather them.

  • Collector Steward: This Merge node patiently waits for outputs from all the activated minister workflows. Since up to nine ministers could be involved, it's configured to handle multiple inputs.
  • Steganographer: Once all reports are in, this Aggregate node bundles them neatly into a single array named reports.

7. Compiling the Cabinet Brief (Serving Reports Node)

With all ministerial reports collected, a Code node named "Serving Reports" prepares them for the final review.

  • What it does: It iterates through the reports array and concatenates the actual textual output from each minister into one comprehensive string. This single string now contains the combined insights from all relevant departments.

8. The Head of Government's Review (HoG Agent)

This compiled string of ministerial advice is then presented to the "Head of Government" (HoG).

  • What it does: The HoG is another powerful LLM agent. Its system prompt instructs it to act as the ultimate decision-maker. It receives the synthesized reports and action plans from the delegated ministers and is tasked with weaving them into a single, coherent final response, decision, or consolidated action plan that addresses the user's original request comprehensively.
  • Under the hood: The Head of Government also leverages our local LLM, this time configured with a higher temperature (0.7). This encourages more nuanced synthesis and a more elaborate textual response, suitable for a final G2C (Government-to-Citizen) communication.

9. Delivering the Government's Position (Split Out Node)

Finally, the polished response from the Head of Government is prepared for delivery.

  • What it does: A "Split Out" node extracts the main text from the HoG's output, which becomes the final answer sent back to the user in the chat.

Auxiliary Machinery: The Knowledge Keepers

It's worth noting there's an "Execute Workflow" node named Ingest Gov KB that's not directly in the request-response path. This is designed to run the separate Government KB Ingestor sub-workflow. As a comment within the n8n workflow file indicates, this is our tool for feeding new documents and knowledge into the government's (and thus the ministers') knowledge base – a critical function for keeping our AI informed!

The Specialists: Government Agent with KB

Alright, we've seen the main conductor, the Government Main Flow. Now, let's zoom in on the individual players, the specialists in the cabinet. Each "Minister" in our AI government is actually an instance of a powerful sub-workflow. This is where the deep thinking and knowledge retrieval for specific domains happen.

Think of the Government Agent with KB as the blueprint for each of your AI ministers. When the Government Main Flow decides, for example, that the "Minister of Health" needs to weigh in, it doesn't just send a simple instruction; it activates this sophisticated sub-workflow, equipping it with everything it needs to act like a health expert.

Here’s a breakdown of what makes each minister tick:

1. Receiving the Mandate (When Executed by Another Workflow)

This sub-workflow springs to life when called by our main government flow.

  • What it does: This trigger node is designed to receive a batch of critical information that defines the minister's current assignment. This includes:
    • system_prompt: The specific role and personality definition for this minister (e.g., "You are the Minister of Finance...").
    • overall_context: The broader situation or query being discussed.
    • guidelines: Specific instructions on how the minister should format its response.
    • task: The precise question or action item assigned to this minister.
    • minister_id: A unique identifier for the minister (e.g., "Minister of Finance & Economic Planning"), crucial for memory.
    • temperature & context_size: LLM parameters passed down from the main flow, allowing dynamic control over the minister's response style and an understanding of the data volume.

2. The Minister's Core AI (Minister Blueprint Agent)

At the heart of this sub-workflow lies the "Minister Blueprint" – a Langchain Agent node. This is the minister's primary "brain."

  • What it does: It takes the task (the specific question it needs to answer) as its main input. The system_prompt, overall_context, and guidelines received from the trigger are injected into its system message, effectively programming its persona and objective for the current job.
  • It's equipped with:
    • An LLM (its reasoning engine).
    • Memory (to recall past interactions within its specific role).
    • A suite of tools (to access relevant knowledge bases).

3. The Reasoning Engine (Ollama Chat Model)

The "Minister Blueprint" agent needs an LLM to think and generate responses.

  • What it does: This node connects to our self-hosted LLM. The temperature and context_size for its operations are dynamically set by the values passed into the sub-workflow, offering great flexibility.

4. Ministerial Memory (Simple Memory Node)

To ensure consistency and context awareness for each specific ministerial role, the agent is equipped with memory.

  • What it does: A "Simple Memory" (Buffer Window Memory) node is used. Critically, the sessionKey for this memory is set to the minister_id. This is a neat trick: it means that the "Minister of Finance" will have its own separate memory from the "Minister of Education," allowing each to build up a relevant conversational history for their specific domain without interference.

5. Access to Departmental Archives (The RAG Setup - Tools & Vector Stores)

This is where the "KB" (Knowledge Base) part of the workflow's name truly comes into play. The "Minister Blueprint" agent is given several tools to retrieve information using Retrieval-Augmented Generation (RAG). This allows it to consult specific datasets relevant to its department.

  • The Concept: Each minister can access a "Generic" knowledge base shared by all, plus one or more knowledge bases specific to their portfolio.
  • How it's built:
    • Vector Store Tools (RAG Generic, RAG Justice, RAG Tech, etc.): For each knowledge source, there's a toolVectorStore node. These nodes are what the "Minister Blueprint" agent sees as callable tools. For example, RAG Justice is described as "Data useful for the Justice department," and RAG Generic is for "Generic documents that each agent should read and understand." There are dedicated RAG tools for:
      • Generic knowledge
      • Justice & Legal Affairs
      • Home Affairs & Internal Security
      • Technology & Digital Infrastructure
      • Health & Public Welfare
      • Foreign Affairs & International Relations
      • Environment & Climate Action
      • Finance & Economic Planning
      • Defense & National Security
      • Education & Human Development
    • Connecting to Qdrant (Generic Vector Store, Justice Vector Store, etc.): Each toolVectorStore node is paired with a vectorStoreQdrant node. These nodes point to the actual collections in your Qdrant vector database (e.g., govt_gen for generic, govt_just for justice, govt_internal for internal affairs, and so on for each department). This is how the agent knows where to look for specific information.
    • Understanding the Query (Embed User Query): To search these vector stores, the agent's query needs to be converted into vectors. An embeddingsOllama node, named "Embed User Query," handles this using the mxbai-embed-large:latest model. This embedding model is connected to all the Qdrant vector store nodes.
    • Summarizing Retrieved Information (RAG Summarizer): When a RAG tool retrieves documents, they might be lengthy. Another LLM node, the "RAG Summarizer" (using our local LLM with a specific 16000 token context size), is connected to all the toolVectorStore nodes. This suggests it's used to summarize the retrieved documents before they are passed back to the "Minister Blueprint" agent, making the information more concise and easier for the main agent to use.

Putting It All Together

So, when a minister is activated:

  1. It receives its specific persona (system_prompt), the task, and the overall_context.
  2. The "Minister Blueprint" agent takes this on.
  3. If the task requires information not immediately available, the agent can use its specialized RAG tools. For example, if the "Minister of Health" needs data on a specific disease, it might query the "RAG Health" tool.
  4. The query is embedded, relevant documents are fetched from the corresponding Qdrant collection (e.g., govt_health), potentially summarized by the "RAG Summarizer," and then returned to the "Minister Blueprint."
  5. The agent uses this retrieved information, its core instructions, and its dedicated memory to formulate a response to the task.
  6. This response is then sent back to the main Government Main Flow to be collected by the "Collector Steward."

This sub-workflow is the powerhouse behind each specialized minister. By parameterizing the system prompt and providing access to distinct knowledge bases via tools, you've created a highly modular and scalable way for different AI agents to develop and leverage domain-specific expertise. It’s a solid foundation for a multi-talented AI cabinet!

Feeding the Digital Archives: Government KB Ingestor

Okay, we've explored the main government orchestrator and the specialized minister agents. But where do these ministers get their knowledge? That's the job of our next workflow: the Government KB Ingestor. This one isn't part of the live chat interaction; instead, it's a crucial background process, manually triggered, designed to load and update the knowledge bases our AI cabinet relies on—think of it as the government's archival and library update system. It meticulously processes documents for each 'department,' transforming raw text files into a structured, searchable knowledge base, ensuring they are correctly embedded and stored in their respective Qdrant vector stores.

Here's how this vital process works:

1. Kicking Off the Ingestion (When clicking ‘Test workflow’)

The process begins with a manual trigger.

  • What it does: This allows an operator (that's you!) to start the knowledge ingestion process whenever new documents are ready or updates are needed.

2. Defining the Departments (List deps with files & Split departments)

Before any files are touched, we need to know which departments we're dealing with.

  • List deps with files: A Code node defines a list of department identifiers (e.g., "gen" for general, "just" for justice, "health" for health). This list includes "gen", "just", "health", "tech", "internal", "foreign", "finance", "edu", "env", and "defense".
  • Split departments: This node takes the list of department identifiers and processes them one by one, ensuring each department's knowledge base is handled systematically.

3. A Fresh Start for Each Department's Knowledge (The Loop Begins)

For each department identifier provided by the "Split departments" node, the following steps are performed:

  • Wiping the Slate Clean (Delete Collection):
    • An HTTP Request node sends a command to your Qdrant instance to delete the existing collection for the current department (e.g., govt_just if "just" is being processed). This ensures that we're always working with a fresh set of information if we're re-ingesting.
  • Rebuilding the Archive (Recreate Collection):
    • Immediately after deletion, another HTTP Request node creates a new, empty collection in Qdrant for that department. The collection name is dynamically formed (e.g., govt_just).
    • Crucially, this step defines the vector parameters for the collection: a vector size of 1024 and Cosine distance for similarity searches. This matches the mxbai-embed-large:latest model's output.
  • Gathering the Source Material (Read Govt Files):
    • This node reads all .txt files from a specific directory structure, like /files/govt/{{department_name}}/, where {{department_name}} is the current department identifier from the loop (e.g., /files/govt/just/).
  • Extracting the Text (Extract from All Files):
    • The raw file data is then processed to extract the actual text content from each file.
  • Consolidating Departmental Texts (Aggregate Documents):
    • All the text extracted from the files for the current department is aggregated into a single data item. This consolidated text is what will be processed for embedding.

4. Processing and Storing the Knowledge

Once all the text for a single department is aggregated, it's time to prepare it for the vector store:

  • Breaking it Down (Token Splitter):
    • The aggregated text for the department is fed into a "Token Splitter." This node breaks down the large block of text into smaller, manageable chunks, configured here with a chunk size of 512 tokens. This is essential for effective embedding and retrieval.
  • Structuring for a Digital Library (Data Chunker):
    • The text chunks from the splitter are then processed by a "Data Chunker" node (a documentDefaultDataLoader type). This formats the chunks into the standard Document objects that Langchain and n8n's vector store nodes expect.
  • Creating the Embeddings (Embeddings Ollama):
    • The prepared document chunks are then passed to an "Embeddings Ollama" node. This node uses the mxbai-embed-large:latest model (running on your local Ollama instance, of course) to convert each text chunk into a numerical vector representation – its embedding.
  • Filing in Qdrant (Qdrant Vector Store):
    • Finally, the document chunks, now paired with their embeddings, are inserted into the freshly created Qdrant collection for the specific department (e.g., govt_just). This node is configured for "insert" mode.

This loop (from deleting the collection to storing embeddings) repeats for every department defined in the initial list, ensuring each gets its own dedicated and up-to-date knowledge base in Qdrant.

Separate Utility: Testing the RAG

The workflow file also contains a distinct, disconnected set of nodes designed for testing the Retrieval-Augmented Generation (RAG) functionality.

  • What it is: This section starts with a "Testing KB" chat trigger, allowing you to interact with an "AI Agent." This agent is equipped with memory, an LLM (your chosen local model), and a RAG tool named "Answer questions with a vector store."
  • How it's different: For this testing setup, the RAG tool is connected to a "Pinecone Retriever" node pointing to a Pinecone index named govtdocs, rather than Qdrant. It also has its own "Embed User Query" and "RAG Summarizer" nodes.
  • Purpose: A sticky note clarifies, "Use this to test if the RAG works." This provides a handy, isolated environment within the same workflow file to quickly verify if your RAG setup (or an alternative one using Pinecone) is retrieving and utilizing information correctly.

This Government KB Ingestor workflow is the backbone of your AI cabinet's knowledge. By systematically processing and embedding documents into department-specific vector stores, you ensure that each minister agent has access to the precise information it needs to perform its duties effectively. And keeping it as a manually triggered process gives you full control over when and how these knowledge bases are updated – essential for maintaining a well-informed AI team!


Conclusion: The Path Forward

We've taken a deep dive into the architecture of an experimental AI Government Cabinet, built with a focus on self-hosting, privacy, and modular agent-based design using n8n, Ollama, and Qdrant. From the main orchestrating flow that delegates tasks, to the specialized minister agents equipped with their own knowledge bases, and finally, the ingestion process that keeps that knowledge fresh – it's a complex but fascinating endeavor.

This project highlights the potential of using locally-run LLMs and agentic workflows to tackle intricate tasks. While this is an early exploration into whether AI could (not necessarily should) assist in governance, the principles of structured delegation, specialized knowledge access, and synthesized decision-making are applicable to many complex problem domains.

The journey of building and refining such a system is ongoing. There's always more to learn, more to optimize, and more ethical considerations to ponder. If you're interested in exploring the nitty-gritty details, experimenting with the workflows, or even contributing your own ideas, I encourage you to check out the project on GitHub.

You can find all the workflow files and further documentation at the cabinetAI repo

What are your thoughts on using AI in such complex systems? What challenges or opportunities do you foresee? I'd love to hear your perspectives as this exploration continues.