# Context Engines for Multi-Brand Agencies: One Memory Per Brand > An agency managing 15 brands has 15 distinct institutional memory problems. One context engine file per brand, with identical namespace structure, is the architecture that scales without cross-brand contamination. - **Category**: Theory - **Read time**: 7 min read - **Date**: June 30, 2026 - **Author**: Feather DB (Engineering) - **URL**: https://getfeather.store/theory/context-engine-multi-brand-agencies --- ## The multi-brand memory problem An agency managing 15 D2C brands has 15 distinct institutional memory problems. Each brand has its own winning hooks, its own brand voice constraints, its own audience insights, its own competitive landscape, and its own campaign history. The memory that is relevant for a skincare brand brief is not relevant for a pet supplement brief, even if both target the same demographic. Most AI tools handle this with prompting: include the brand guidelines document, paste in some campaign notes, specify the tone. This works for individual sessions. It does not build institutional memory that accumulates across campaigns for each brand. Every brief is a cold start with a well-formatted prompt. Context engines solve this with a simple architectural choice: one memory store per brand. Each brand gets its own context database, its own namespace structure, its own accumulated campaign history. The agency manages the collection of stores; each brief queries only the relevant one. ## The architecture: one file per brand Feather DB's embedded format makes this natural. Each brand is a single `.feather` file. Open it when you need it, close it when done. No connection management, no shared schema constraints, no risk of brand A's memory bleeding into brand B's retrieval: ```python import feather_db as fdb # Agency manages a collection of brand databases brand_dbs = { "acme_skincare": fdb.DB.open("brands/acme_skincare.feather", dim=768), "petco_nutrition": fdb.DB.open("brands/petco_nutrition.feather", dim=768), "nova_fitness": fdb.DB.open("brands/nova_fitness.feather", dim=768), # ... 12 more brands } # Brief generation queries only the relevant brand def generate_brief(brand: str, brief_params: str, embedder): db = brand_dbs[brand] results = db.search( embedder.embed(brief_params), k=6, namespace="brand::hooks", scoring=ScoringConfig(half_life=270.0, weight=0.3, min=0.0) ) return results ``` The namespace structure within each file is identical — same four namespaces, same signal types, same decay configuration — but the content is entirely brand-specific. Acme Skincare's winning hooks are not in the search index when you are generating a brief for Petco Nutrition. ## Why isolation matters beyond privacy Brand isolation is not just a privacy concern. It is a retrieval quality concern. If all 15 brands shared a single context engine, a query for "emotional hooks for subscription products" would surface hooks from every brand in the portfolio — regardless of whether those hooks fit the brand voice, the category, or the competitive context of the brand currently in scope. The result would be low-precision retrieval: semantically relevant hooks that are contextually wrong. A transformation hook that worked for a fitness brand will surface for a skincare brief if they share vocabulary. The agency strategist then has to manually filter — reintroducing the manual process that the context engine was supposed to automate. Per-brand isolation eliminates this. Every search result is guaranteed to be relevant to the brand in scope, because the search index only contains that brand's history. ## Namespace structure across all brand files Each brand file uses the same internal namespace structure: ```python BRAND_NAMESPACES = [ "brand::hooks", # winning copy angles + spend data "brand::guardrails", # permanent brand voice and claim rules "brand::competitors", # competitor creative intelligence (45-day half-life) "brand::audiences", # segment insights (90-day half-life) ] SCORING_BY_NS = { "brand::hooks": ScoringConfig(half_life=270.0, weight=0.3, min=0.0), "brand::guardrails": ScoringConfig(half_life=3650.0, weight=0.05, min=0.0), "brand::competitors": ScoringConfig(half_life=45.0, weight=0.45, min=0.0), "brand::audiences": ScoringConfig(half_life=90.0, weight=0.35, min=0.0), } ``` The consistency means the brief generation code is identical across all brands — just swap the database file. The agency builds the tool once and applies it across the entire portfolio. ## Onboarding a new brand Adding a new brand to the agency's context system is a three-step process: - **Create the file and ingest historical data.** Open a new `.feather` file, run the campaign history ingestion pipeline against the new brand's past campaigns. Even a brand new to the agency may have 12–24 months of campaign data worth encoding. - **Ingest brand guardrails.** Pull brand guidelines, claim restrictions, and visual identity rules into the guardrails namespace with permanent half-life configuration. - **Start the loop.** Every new campaign result ingests automatically into the brand's file. The context engine accumulates signal from the first campaign forward. Hawky.ai reports 4–6 minute integration time for connecting an ad account. The context engine build-out from existing campaign history is the longer step, but it is a one-time cost that compounds forward. ## Cross-brand learning without cross-brand contamination Per-brand isolation does not prevent the agency from learning across brands — it just requires explicit handling. If the agency identifies a creative pattern that works across multiple clients (say, a specific testimonial format that consistently reduces CPL in subscription categories), that pattern can be ingested into each relevant brand's context engine as a principle, tagged with its source and evidence: ```python # A pattern identified across brands, ingested explicitly into relevant files agency_learning = ( "Testimonial format: 3-second customer quote with metric overlay." " Reduced CPL 18-23% across 4 subscription brands in Q1 2026." " Best performance in mobile feed placement, 25-44 demographic." ) for brand in ["acme_skincare", "nova_fitness"]: db = brand_dbs[brand] db.add( id=agency_pattern_id, vec=embedder.embed(agency_learning), text=agency_learning, namespace="brand::hooks", meta={"importance": 0.6, "source": "agency_cross_brand"} ) ``` The agency retains editorial control over what cross-brand learning gets applied where. Relevant patterns are explicit additions, not accidental retrievals. The isolation is maintained. ## The 160 hours per brand per month figure Hawky.ai reports 160 hours saved per brand per month across its agency clients. For an agency managing 15 brands, that is 2,400 hours per month of manual creative audit and brief preparation time that the context engine automates. At any reasonable hourly cost for strategist time, the ROI case for deploying a context engine across an agency portfolio is straightforward. ## FAQ ### How should a multi-brand agency structure AI memory? One context engine file per brand client. Each file accumulates campaign history specific to that brand. Brief generation queries only the relevant brand file. This ensures retrieval precision and prevents cross-brand contamination while maintaining a consistent namespace structure across the portfolio. ### Can context engine memory be shared across brands in the same category? Cross-brand patterns should be explicitly ingested as agency learnings into relevant brand files, not shared through a common search index. Explicit sharing maintains editorial control. Implicit cross-brand retrieval reduces precision because context that is relevant in one brand's competitive environment may not be relevant in another's. ### How long does it take to build a context engine for a new brand client? Hawky.ai reports 4–6 minutes to connect an ad account. Historical campaign ingestion depends on data volume — a brand with 18 months of campaign history typically takes a few hours of ingestion pipeline runtime. The context engine starts producing useful retrieval results after the first ingestion batch. ### What happens to a brand's context engine when they leave the agency? Each brand's `.feather` file is a portable, self-contained binary. It can be handed off to the brand or a new agency. The memory is owned by whoever holds the file — there is no SaaS lock-in or data held in a shared cloud environment. --- *This is the machine-readable mirror of the theory post at [getfeather.store/theory/context-engine-multi-brand-agencies](https://getfeather.store/theory/context-engine-multi-brand-agencies). For the full Feather DB documentation, see [getfeather.store/llms-full.txt](https://getfeather.store/llms-full.txt).*