Ben Brown Software Engineer II

Role
Software Engineer II
Focus
Enterprise AI engineering & solutions architecture
Engineering
5+ years, C#/.NET and enterprise integration
Open to
AI engineer · AI solutions architect · applied AI

I take enterprise AI from an ambiguous business problem to a tested, governed system.

Discovery and requirements, retrieval and orchestration architecture, prototypes, measurable evaluation, governance, and pilot delivery. Five years of C#/.NET and enterprise integration work sits underneath all of it, which is most of why the AI parts hold up.

Opportunities evaluated

20+

AI use cases assessed across supply chain, HR, payroll, finance, legal, operations, and IT.

Basis · discovery and triage work described in Arc

Estate targeted

300+

Programs across roughly 100 repositories in scope for the documentation architecture.

Basis · scope of the analysis → WK-01

Retrieval quality · personal prototype

0.929

Mean reciprocal rank on a labeled question set; Hit@1 ≈ 86%.

Basis · measured eval set → WK-05

Forecast error

0.13

Weighted absolute percentage error, weekly, across ten branches.

Basis · weekly evaluation across ten branches → WK-04

01 — Selected work

Five records, four of them enterprise.

Status labels here are literal. A proof of concept is a proof of concept, a pilot is a pilot, and an estimate is marked as an estimate every time it appears.

Index of documented work
Record Project Domain Status Core stack
WK-01 Enterprise documentation automation Software estate POC C# · Roslyn · Azure OpenAI · Azure DevOps
WK-02 Erosion & sediment analysis assistant Construction / geospatial POC ArcGIS · ArcPy · Python · Azure OpenAI
WK-03 Legal knowledge assistant Legal operations Pilot Copilot Studio · SharePoint · Power Platform
WK-04 Branch demand forecasting Supply chain MVP
WK-05 Private local knowledge system Personal prototype Prototype Node · SQLite · LanceDB · Ollama

01

WK-01 · Enterprise documentation automation

Analyze the code deterministically. Only then let a model write about it.

A large .NET estate — 300+ programs across roughly 100 repositories — with documentation that had drifted years away from the source. Writing it by hand is a multi-quarter effort that is stale the week it ships.

Status
POC · pilot-oriented architecture
Role
Architecture · Engineering · Estimation
Stack
C# · .NET · Roslyn · JSON · Azure OpenAI · Azure DevOps
Scale
300+ programs · ~100 repositories
Focus
Deterministic extraction before generation

Context

The obvious approach is to paste source files into a chat model and ask for documentation. It fails at estate scale for three separate reasons, and it is worth separating them: the code does not fit in a context window, the model has no ground truth to check itself against, and nothing about the process is repeatable when the code changes next week.

So the interesting question was never "which model." It was "what does the model need to be handed."

Approach

A Roslyn analyzer walks each solution and emits structured metadata as JSON: types, members, signatures, inheritance, call relationships, dependency edges, entry points, attributes. That pass is deterministic. Run it twice on the same commit and you get the same file.

Generation then works from that structured representation rather than from raw repository sprawl, one unit at a time, against prompt templates written per document type. The whole thing runs as an Azure DevOps pipeline step, so documentation is produced from the current commit instead of from someone's memory of the current commit.

Documentation pipeline Repository feeds a Roslyn analyzer, which produces structured JSON metadata. The metadata plus prompt templates feed an Azure OpenAI generation step, which produces documentation that is published by an Azure DevOps pipeline. The analyzer-to-metadata path is marked as the deterministic path. REPOSITORYC# / .NET ROSLYNANALYZER STRUCTUREDMETADATA · JSON AZURE OPENAIGENERATION DEVOPSPIPELINE PROMPT TEMPLATES deterministic cacheable per unit
Fig. 1.1 — The two marked edges are the deterministic half. Everything the model is allowed to state about the code arrives from the analyzer, not from the source.

Why the order matters

The model is not the source of the parameter count. The analyzer is, and its output is a diffable artifact — so when the prose and the code disagree, the disagreement is findable rather than a matter of opinion. Facts and language are produced by different components, which means they fail differently and can be checked differently.

Three consequences fall out of that split. The expensive part becomes cacheable, because metadata only changes when code changes, which makes regeneration incremental rather than a full re-run. When output is wrong you can tell which stage was wrong — extraction or prompt — instead of re-rolling the whole thing and hoping. And the pipeline gets a natural place to hang review, because structured metadata is diffable in a way prose is not.

A single-stage "read the repository and explain it" design gives you none of those seams. It gives you one opaque step whose only debugging tool is asking again.

Validation & status

An external technical review of the architecture found no major red flags and considered the approach sound. The impact figures below were built during the POC from hour counts and rates. They are estimates used to size the opportunity, and they have not been audited against realized spend.

It remains a POC with a pilot-oriented architecture. What is left is the unglamorous part: coverage across repositories that do not look alike, a review workflow for generated output, and a named owner for the pipeline.

Table 1.1 — Figures developed during the POC
Measure Value Basis
Estate in scope300+ programs · ~100 reposCounted scope of the analysis
Initial engineering hours potentially avoided600+Estimate — hour counts developed during the POC
Estimated annual value$25K – $50KEstimate — not audited or realized savings
External architecture reviewNo major red flagsThird-party technical review of the design

Tradeoff

The analyzer is the expensive component and it is language-specific. It buys reliability at the cost of portability: a Python or COBOL estate needs a new extractor before any of this works. I would make that trade again for a homogeneous .NET estate. I would not make it for a polyglot one without first checking whether the documentation problem was actually worth an extractor per language.

02

WK-02 · Erosion & sediment analysis assistant

It looked like a document-AI problem. It was mostly a measurement problem wearing a document-AI costume.

Construction packages for large sites — solar farms, data centers — arrive as plan sets and supporting documents. Someone has to read them for erosion and sediment obligations: site conditions, which control measures apply, roughly how much material each one takes, and what that means for a budget.

Status
POC · controlled validation
Role
Discovery · Requirements · Architecture · POC · Validation planning
Stack
ArcGIS · ArcPy · Python · Azure OpenAI · structured outputs
Focus
Deterministic geometry, AI orchestration

Context

The work is slow, it is done under deadline, and two experienced reviewers do not always produce the same numbers. That combination usually means there is real value in automation — and it is also exactly the combination that makes people reach for a language model and ask it to read the drawings.

I ran the discovery with the people who actually do the work, wrote the requirements, evaluated the GIS path, built the technical POC, and put together the validation plan and the business-facing material that went with it.

Architecture

The split is the whole point of the design. Geometry is computed, not inferred: ArcGIS and ArcPy do the spatial work — slopes, areas, lengths, buffers, intersections against site layers — and produce numbers that can be recomputed and defended.

The language model orchestrates around that. It reads the plans and specifications, decides which control measures are in scope, assembles the supporting evidence, and emits structured output where every finding carries a citation back to the document or the computation it came from. Where a required input is missing, the output says the input is missing. It does not fill the gap.

Erosion and sediment analysis pipeline Construction evidence splits into two paths. The upper path sends site layers through deterministic GIS analysis in ArcPy. The lower path sends plans and specifications through document understanding. Both converge into structured findings carrying provenance, which feed language model orchestration, which feeds mandatory human review. The GIS path is marked as the path that owns all measurements. CONSTRUCTIONEVIDENCE GIS · ARCPYSLOPE · AREA · LENGTH DOCUMENTUNDERSTANDING STRUCTUREDFINDINGS LLM ORCHESTRATIONSCOPE · CITATION HUMAN REVIEWBEFORE USE measured read provenance per finding
Fig. 2.1 — The marked path is the only one allowed to produce a number. Anything the lower path cannot support with a citation comes out flagged as missing rather than estimated.

Why not end-to-end

Language models are weak at metric truth from drawings and strong at reasoning over heterogeneous evidence. Ask one to eyeball a linear footage from a plan sheet and you get a confident number with no provenance — which is precisely the failure a quantity estimate cannot survive, because the first thing a reviewer asks is where the number came from.

So the constraint I designed to was simple to state and expensive to honor: every number in the output either traces to a deterministic computation, or it does not appear.

Validation & status

Validation was designed around benchmark cases with known answers, provenance on every finding, explicit missing-data handling, and mandatory human review before anything is used commercially.

It is a POC under controlled validation. There is a plausible high-value business hypothesis attached to it. That hypothesis has not been tested by production measurement, so there is no return figure on this page — and I would be skeptical of a portfolio that quoted one at this stage.

Tradeoff

This design is slower and more expensive per package than a single end-to-end model call, and it depends on GIS layers being clean enough to compute against. That is the cost of being able to defend a number in front of the person whose budget it lands in. For a workflow where nobody has to defend the output, I would not pay it.

03

WK-03 · Legal knowledge assistant

Not every enterprise AI problem needs a custom retrieval stack.

A legal and knowledge workflow where the same questions were answered over and over from documents that already lived in SharePoint, already had the right permissions on them, and were already governed.

Status
Pilot
Role
Discovery · Build · Rollout
Stack
Copilot Studio · SharePoint · Power Platform · existing enterprise access model
Build time
~4 business days to first working implementation
Focus
Choosing the smallest architecture that works

The decision

A custom retrieval stack was on the table. It would have meant weeks of build, a new data path to take through security review, an index to keep in sync, and something for a team to own indefinitely.

The content was already in a governed system. The permissions already worked and were already inherited. The question space was narrow. So I built it on Copilot Studio over the existing SharePoint knowledge, inside the Power Platform, on the identity and access model that was already in place — roughly four business days from start to a working assistant — then put it in front of a small group of real users with a feedback loop attached.

Custom retrieval buys control over chunking, ranking, and evaluation. Those are real things to want, and ranking and evaluation are built out elsewhere on this page. This problem did not need to buy them, and spending three weeks proving that would have been the expensive kind of thorough.

Table 3.1 — Pilot outcome
Measure Value Basis
Time to first working implementation~4 business daysElapsed build time
Pilot usageReal usageSmall controlled pilot with business users
Estimated soft savings~$1,000 / monthEstimated at the time of evaluation — time recovered, not audited cost reduction

04

WK-04 · Branch demand forecasting

The deliverable was not a chart. It was a number a planner could argue with.

Branch-level demand forecasting across ten locations on roughly 12,000 historical records.

Status
MVP
Role
Engineering · Evaluation
Data
~12,000 records · 10 branches
Result
Weekly WAPE ≈ 0.13

Evaluation first

What made this worth doing was agreeing on the measure before arguing about the model. A forecasting demo always looks good, because the person building it chooses which week to show you; a weekly error figure computed the same way every time does not have that luxury.

Weekly WAPE landed around 0.13. In plain terms: across a week's volume, the forecast was off by roughly 13% in aggregate, weighted so that high-volume items count more than low-volume ones — which is what you want, because being 40% wrong about something you sell twice a year does not matter much and being 5% wrong about your top mover does.

That framing is the part that travels. A 13% aggregate miss is a stocking conversation with an operations lead, not a modeling conversation with an engineer. One headline number that a non-technical stakeholder can interpret is worth more here than a better model nobody can argue with.

It is an MVP. It has not been deployed as a production planning input, and the honest next step is a shadow period against whatever the planners do today.

02 — How I work

Eight steps, and each one produces something you can put in a folder.

This is the part that separates an AI program from a sequence of demos. Every step below names its artifact, because a step with no artifact is a meeting.

  1. Discovery

  2. 01

    Intake

    What business problem are we actually solving, for whom, and how would we know it had been solved? If nobody can answer the third part, the work is not ready to start.

    Artifact → problem statement with a named owner and a success measure

  3. 02

    Discovery

    The people who do the work, the workflow as it really runs, where the pain actually sits, what data exists and who owns it, and the security and classification constraints that will decide the architecture later.

    Artifact → workflow map · data inventory · constraint list

  4. 03

    Alternatives

    Decide honestly whether the answer is conventional software, an existing platform capability, automation, deterministic analytics, classical ML, an LLM with retrieval, or a hybrid. Most of the value in this step comes from ruling AI out when it does not belong.

    Artifact → options memo with a recommendation and what would change it

  5. Build

  6. 04

    Proof of concept

    Build the piece most likely to fail, first, and as cheaply as it can be built. The purpose of a POC is to find the wall early, not to produce something impressive.

    Artifact → running prototype of the riskiest component

  7. 05

    Evaluation

    Baselines and success criteria, written down before anyone sees a demo. For retrieval that means a labeled question set and ranking metrics; for forecasting, held-out periods and an error measure a stakeholder can read.

    Artifact → labeled evaluation set · baseline · metric everyone agreed to

  8. 06

    Pilot

    Real users, controlled scope, a feedback path that someone reads. A pilot exists to surface the workflow problems that no amount of offline evaluation will find.

    Artifact → pilot plan · feedback log · usage record

  9. Operate

  10. 07

    Governance

    Access and identity, data classification, privacy, where human review is mandatory, observability, retention, and which models and providers are approved for this class of data. Designed alongside the system, not bolted on after the pilot goes well.

    Artifact → access model · review checkpoints · retention and logging plan

  11. 08

    Production decision

    Measured value against run cost, maintenance burden, reliability, and whether the organization is actually ready to own the thing. "No" is a valid outcome, and it should be cheap to reach — which is the entire reason the first seven steps are ordered this way.

    Artifact → cost and value comparison · go / no-go with reasoning

Governance

Good AI architecture includes the controls around the model, not just the model.

I have worked on the intake and governance side of an enterprise AI program as well as the build side. At a public level of abstraction, that means the process for how a use case enters, how it is classified, and what has to be true before it is allowed near real data or real users.

  • Use-case intake and prioritization
  • Data classification, including where cloud models are not permitted
  • Access control and ACL-aware retrieval
  • Approved model and provider patterns per data class
  • Evaluation requirements before a pilot is allowed
  • Human review wherever output carries consequence
  • Source attribution and auditability
  • Retention, logging, and observability
  • Security, legal, and compliance checkpoints
  • Value measurement and explicit production approval criteria

The specific policies are internal and are not reproduced here.

03 — Stack & architecture

What I use, and how far I have actually taken it.

Depth is a word, not a bar. Nobody is 92% Azure OpenAI, and a portfolio that says otherwise is asking you not to look closely.

Depth

Shipped
Ran in production or a live pilot
Prototyped
Built by me in a POC or personal system
Designed
Architected or evaluated, not built by me
Technical capability matrix
Capability Depth Where
Models & inference
Azure OpenAI — prompt templates, structured outputsPrototypedWK-01, WK-02
Azure AI Foundry — model and deployment patternsDesigned
Local inference — Ollama, qwen3:8b, nomic-embed-textPrototypedWK-05
Prompt and model evaluation — labeled sets, baselinesPrototypedWK-04, WK-05
Retrieval & data
Hybrid retrieval — BM25/FTS5 + vector, reciprocal rank fusionPrototypedWK-05
Embeddings and vector stores — LanceDB, SQLitePrototypedWK-05
Azure AI Search — semantic, vector, and keyword retrievalDesigned
SharePoint as a governed knowledge sourceShippedWK-03
Source attribution and citation-bound answersPrototypedWK-02, WK-05
Application engineering
C# / .NET — enterprise applications, APIs, integrationsShippedArc
Roslyn analyzers and structured code metadataPrototypedWK-01
Python — analysis, orchestration, ArcGIS / ArcPyPrototypedWK-02
Node.js, Express, SQLite, server-sent eventsPrototypedWK-05
SQL, enterprise integration, MDM and XSLT toolingShippedArc
Platform, identity & operations
Azure DevOps pipelines, Git / GitHub, CI/CDShippedWK-01, Arc
Copilot Studio and the Power PlatformShippedWK-03
Enterprise authentication and permission-inherited retrievalShippedWK-03
Azure Functions, App Service, Durable Functions patternsDesigned
Managed Identity, Key Vault, RBAC, Application Insights, Log AnalyticsDesigned
Governance & delivery
Use-case intake, classification, human-in-the-loop reviewShippedMethod
Cost and value telemetry, Power BI, Power AutomateDesigned

04 — Career arc

Enterprise software first. The AI work is built on top of it, not instead of it.

Now

Enterprise AI engineering & solutions architecture

Official title: Software Engineer II

Over the last stretch of my career the work moved from writing enterprise applications to deciding whether AI belongs in a given problem at all — and then owning what happens next. In practice that has meant running discovery with supply chain, HR, payroll, accounting and finance, legal, operational business units, enterprise applications, and IT; evaluating more than twenty AI opportunities and moving the survivors through POC, evaluation, and pilot; making the architecture calls; and contributing to the intake and governance process that decides what is allowed to proceed.

The unifying thread is not the model. It is being the person who can sit with a business owner in the morning, write the retrieval architecture in the afternoon, and give an honest answer about which of the two is the real constraint.

Before

Enterprise application & integration engineering

C# and .NET application development, enterprise integrations and APIs, SQL, Azure DevOps and CI/CD, Git, BizTalk-related integration modernization, and Profisee MDM and API work. Five-plus years of building things that have to still be working on Monday.

One project from this period is worth naming because it shows the same instinct as the AI work: during integration-modernization research I built internal XSLT conversion tooling, with estimated potential annual value in the region of $70K–$100K. Estimated and potential — the same caveat that applies everywhere else on this page.

Start

Software engineering fundamentals

05 — Workshop

What I build when nobody is asking me to.

Opinions about retrieval are cheap. Measurements are not. This is where I buy the measurements, on my own hardware and my own evenings.

05

WK-05 · Private local knowledge system

A local RAG system with an evaluation set, because that is the only way to know whether a retrieval change helped.

Status
Personal prototype · runs entirely on my own hardware
Role
All of it
Stack
Node.js · Express · SQLite · FTS5 · LanceDB · Ollama · Vite · React · Capacitor · Tailscale
Models
qwen3:8b · nomic-embed-text — local, no cloud model in the path
Retrieval
Hit@1 ≈ 86% · MRR ≈ 0.929

Retrieval

Retrieval is hybrid. SQLite FTS5 provides BM25 keyword search, LanceDB holds embeddings produced by nomic-embed-text for vector search, and the two ranked lists are combined with reciprocal rank fusion. Generation runs locally through Ollama on qwen3:8b, and answers cite the passages they were built from. If the system cannot cite, it says it does not know.

Hybrid retrieval path A labeled evaluation set supplies questions. Each query fans out to BM25 keyword retrieval in SQLite FTS5 and to vector retrieval in LanceDB. Both ranked lists are combined by reciprocal rank fusion, which builds the context passed to a local model running on Ollama, which returns a cited answer. The fusion step is marked as the measured critical path. EVAL SET QUERYUSER BM25 · SQLITE FTS5KEYWORD RANK VECTOR · LANCEDBNOMIC-EMBED-TEXT RRFFUSED RANK OLLAMAQWEN3:8B · LOCAL CITEDANSWER questions context
Fig. 5.1 — Every change to this path is judged against the labeled eval set at the left. That is the difference between tuning retrieval and guessing at it.

Around it

An Express API with health and reindex endpoints, streaming responses over server-sent events, and a Vite and React front end. Graceful degradation is deliberate: if the embedding model or the vector store is unavailable, the system falls back to keyword retrieval and says so, instead of returning an error page. There is Capacitor and Android experimentation for a mobile client, and Tailscale so I can reach it from outside the house without exposing anything to the public internet.

Measurement

There is a labeled question set with known correct source documents. Current numbers: Hit@1 around 86%, MRR around 0.929 — the right document is ranked first about 86% of the time, and when it is not, it is usually second. Every retrieval change is judged against that set.

This is a laboratory, not a product, and I would not describe it as anything else. It is where I learn what ranking behavior actually looks like, what an 8B local model can and cannot do, how orchestration fails when a component goes away, and what graceful degradation means when there are four moving parts. A fair amount of what I bring to enterprise retrieval architecture I learned here first.

Table 5.1 — Retrieval evaluation
Measure Value Basis
Hit@1≈ 86%Labeled question set with known source documents
Mean reciprocal rank≈ 0.929Same set, same run
Retrieval strategyHybrid + RRFBM25 and vector lists fused by reciprocal rank

06 — About

About

On demos — I started in enterprise software: integrations, APIs, the systems that have to still be working on Monday morning when nobody is watching. That background is most of why I am skeptical of AI demos. A demo has no error budget, no access model, no owner, no retention policy, and nobody asking what it costs per month at real volume.

What I do now is the work between "someone thinks AI could help here" and "this runs, and we can show that it helps." Most of that work is unglamorous. Talking to the people who actually do the job. Finding out what data exists rather than what data people believe exists. Deciding whether the answer is a language model or a stored procedure. Building the risky part first. Writing down, before anyone is emotionally invested, how we will know it worked.

The interesting decisions in enterprise AI are almost never about the model. They are about what the model is allowed to be the source of truth for.

That is the thread running through the records above. In the documentation work, a deterministic analyzer owns the facts and the model owns the prose. In the geospatial work, GIS owns the measurements and the model owns the reasoning. In the legal assistant, the platform owned everything and my main contribution was recognizing that and not building more. Knowing which component should be authoritative is, as far as I can tell, most of the job.

I am careful about the words on this page, and that is deliberate rather than modest — every caveat above is there even where the sentence would read better without it. That precision is the same discipline that stops an AI system from quietly becoming something nobody in the organization can defend.

The roles this points at: AI engineer, senior AI engineer, AI solutions architect, applied or generative AI engineer, AI technical lead, or RAG and AI platform work. What I want out of the next one is ownership of the whole path — discovery through production decision — rather than a seat at only one end of it.

Contact

Contact details are not published on this page yet.

I am interested in enterprise AI work where the same person owns discovery, architecture, and whether the thing actually gets used.

Set in the system UI sans and ui-monospace. Hand-written HTML, CSS, and JavaScript. Last revised 2026-08-20.