Engineering notes · November 2026

Building an Autonomously Managed Website with vLLM, Hermes and Go

What happens when a website can research, maintain and administer its own content? We're exploring that with SanJuanPuertoRico.org, using locally hosted models, Hermes and a custom application driver.

Give the Website an Operator, Not Just a Chatbot

Most applications integrating large language models start with a familiar feature: a chat interface. A visitor asks a question, the model produces an answer, and the interaction ends.

That's useful, but it doesn't do much to reduce the work involved in actually operating a website.

A local directory presents a particularly interesting problem. Businesses open, close and relocate. Contact information changes. Events expire. New venues appear, and existing listings gradually become outdated.

Somebody needs to find that information, determine whether it is reliable, and update the application.

We wanted to explore whether an agent could perform much of that routine work itself.

SanJuanPuertoRico.org is our experiment in doing exactly that: building an ordinary public-facing website with the infrastructure to support autonomous research, content maintenance and administrative operations.

Rather than simply attaching an AI assistant to the frontend, we're connecting an agent runtime directly to the application's operational capabilities.

The central pieces are vLLM, Hermes, a custom application driver, and our existing Go backend.


Keep the Responsibilities Clear

Our approach separates model inference, agent orchestration and application execution.

The distinction matters.

The model doesn't need direct database credentials or unrestricted access to the application's internals. It needs a collection of well-defined capabilities it can call when a task requires them.

Hermes handles the agent loop. Our driver handles the application-specific integration. The Go backend remains responsible for validating and executing operations.

That allows us to change the inference model without rewriting the business logic. It also allows the website to remain a conventional, usable application even when its AI infrastructure is unavailable.


Serving Models Locally with vLLM

One of the more interesting parts of this project is that we don't necessarily need a frontier model for every operation.

Consider the individual tasks involved in maintaining a business directory:

These are relatively narrow tasks. Many can be attempted with smaller locally hosted models, provided we test their accuracy and tool-use reliability.

We use vLLM to serve models through an API that Hermes can consume. This gives us more control over inference infrastructure, model selection and the cost of repetitive operations.

It also introduces engineering trade-offs. Local inference is constrained by available GPU memory, context size, request concurrency and the model's ability to follow tool schemas consistently.

A small model successfully generating JSON is not proof that its interpretation of a source is correct.

The goal isn't to avoid hosted models at all costs. It's to reserve more expensive inference for the work that actually requires it, while keeping routine operations economical.


Writing a Driver Around Hermes

Hermes already provides an agent runtime. We don't need to build another language-model reasoning loop just to connect it to a website.

Our custom driver exists to bridge the gap between a general-purpose agent and a particular application.

An agent might be asked to investigate a business listing, but the application needs more than a paragraph describing what the agent discovered.

It needs to know which record was examined, what evidence was collected, which fields may have changed and whether an operation completed successfully.

Conceptually, the flow looks like this:

Administrative task
       |
       v
Custom application driver
       |
       v
Hermes agent runtime
       |
       +----> vLLM / local model
       |
       +----> Research and application tools
       |
       v
Structured task outcome
       |
       v
Go application validation
       |
       v
PostgreSQL / application records

The driver gives us somewhere to establish application-specific behaviour without coupling every task to a particular model.

It can supply relevant context, identify available operations, constrain a task's scope, and reconcile the result with the application's records.

An important detail is that the agent's response is not the same thing as a completed operation.

If an agent says a listing was updated, the application still needs to confirm that the corresponding write succeeded.

If a request times out, we need to determine whether the operation already happened before attempting it again.

Those are ordinary distributed-systems problems, and adding an LLM doesn't make them disappear.


MCP Turns Application Capabilities into Agent Tools

We also expose selected operations through the Model Context Protocol.

SanJuanPuertoRico.org provides an authenticated MCP interface for discovering existing listings and contributing verified information.

Its tools include:

These are application operations, not unrestricted instructions to modify the database.

For example, an agent investigating a restaurant should search for an existing record before creating another one.

If the restaurant already exists, it can gather evidence and submit an update through the appropriate tool.

The application then validates the request and decides which fields may be changed.

This distinction lets the agent perform useful work while keeping the rules about ownership, record integrity and publication inside our software.

The same MCP interface also gives us a reusable integration point for other compatible clients.


Researching a Business Is Different from Inventing One

A directory is only useful if its information can be trusted.

Giving an LLM access to a search engine and asking it to populate a database would be relatively straightforward. Keeping that database accurate over time is substantially harder.

We need the system to distinguish between what a source actually says and what the model merely believes is likely to be true.

Our contribution interface therefore requires evidence associated with submitted information, including source references and observation times.

Consider an agent tasked with reviewing a restaurant's operating details. A sensible workflow would be:

  1. Find the existing listing and identify its current information.
  2. Retrieve relevant sources, respecting access restrictions and rate limits.
  3. Extract explicitly supported details and their source references.
  4. Compare those details against the existing record.
  5. Submit permitted changes through the application's validated interface.
  6. Record the outcome, including anything that could not be verified.

If the information is missing or contradictory, the appropriate result might be no change at all.

We also need to treat retrieved webpages as untrusted input. Instructions embedded in third-party content should not become instructions for our agent.

An external website can provide evidence about a business. It should not get to decide how our application operates.


Autonomy Doesn't Mean Unrestricted Authority

One of our more important design decisions is separating the ability to propose or perform routine updates from the authority to change everything.

A public directory has several different classes of data.

An automatically discovered website URL is not equivalent to a manually maintained business profile. An outdated event is not equivalent to a paid advertising placement. A temporary website outage is not evidence that a business has permanently closed.

Those distinctions need to exist in application logic.

For example, SanJuanPuertoRico.org's listing-verification process is designed around repeated checks and reversible archiving.

A failed HTTP request, missing webpage or temporary network problem should not automatically remove a legitimate business from the directory.

Records can be preserved while their verification status changes, and human-maintained entries receive additional protection.

We apply the same principle to commercial operations.

The platform supports paid homepage, category and event promotions through Stripe. These transactions have their own payment verification, placement schedules and reporting requirements.

An administrative agent shouldn't be able to invent a successful payment or silently override a customer's purchase because a model decided a different arrangement looked reasonable.

The model can help operate the system. The application must still enforce its rules.


Keeping the Website Useful Without the Agent

Another practical consideration is failure.

Local models can run out of memory. Agent tasks can exceed their context window. Tool calls can fail. Sources can disappear midway through an investigation.

None of those failures should take the public website offline.

Our architecture deliberately keeps the ordinary website separate from the agent runtime.

The Go application continues serving directory listings, business pages and other visitor-facing functionality independently of Hermes or vLLM.

This makes the agent infrastructure an operational capability rather than a dependency for every page request.

It also changes how we think about monitoring.

A successful HTTP response doesn't mean that an autonomous maintenance task completed. We need to distinguish between a task being accepted, evidence being collected, a tool being called and a database change being confirmed.

Failures should leave enough information to investigate what happened rather than simply triggering another unbounded attempt.


The Economics of Autonomous Administration

The economic question is part of what makes this project interesting.

A conventional directory needs ongoing editorial effort. Somebody must discover new businesses, review submissions, correct stale information and maintain the surrounding content.

A fully hosted AI workflow might reduce some of that labour, but repeated inference requests introduce their own operating costs.

With vLLM, we can experiment with running smaller models on hardware we control.

That doesn't make inference free. Hardware, electricity, deployment, maintenance and failed runs all have costs.

But it gives us another option.

Instead of paying a hosted inference provider for every extraction or classification, we can attempt bounded routine tasks locally and escalate more difficult work when necessary.

The broader objective is an application whose routine maintenance costs can remain manageable as its directory grows.

For a product with relatively modest revenue per listing, that distinction can matter quite a bit.


What We're Actually Building Toward

The long-term objective isn't simply to populate SanJuanPuertoRico.org with more AI-generated content.

It's to develop a platform that can help maintain itself.

That includes discovering potential new listings, checking existing information, identifying stale records, organising administrative work and using application APIs to carry out permitted operations.

It also means improving the controls around that autonomy: better evidence handling, clearer execution logs, task-level permissions, repeatable evaluation and human review for ambiguous or consequential changes.

We're treating the project as an evolving engineering system rather than declaring the problem of autonomous administration solved.

The architecture is useful precisely because the components remain interchangeable.

We can test different local models, improve the Hermes driver, extend the Go application's tools and change how tasks are initiated without replacing the whole platform.


More Than a Website with AI Features

What interests us most about this project is the shift in how an application is designed.

Traditionally, we build administrative interfaces for people to operate software. With an agent-capable application, we can also expose those same business capabilities through structured tools.

The important engineering work moves toward defining the operations, evidence requirements, permissions and failure behaviour that make automation safe enough to be useful.

SanJuanPuertoRico.org is one place we're putting that approach into practice.

It's also closely related to our work with FlaskTrack, where we connect AI assistants to laboratory operations while keeping record validation and approvals inside the application.

Different products, similar engineering principles.

At Santurce Software, we're interested in AI systems that do more than generate an answer. We want them to interact with real software, accomplish useful tasks, and leave enough evidence for someone to understand what happened.

We build custom applications, AI integrations and operational automation for businesses. Tell us what you would like to automate.

Happy Hacking!