Back to Theory
Theory6 min read · June 30, 2026

From Brief to Results: The Context Loop Creative Teams Are Missing

Most creative workflows are open loops: brief → creative → campaign → results, with no connection back to the next brief. Closing that loop with a context engine is the structural change that compounds performance over time.

F
Feather DB
Engineering

The open loop problem

The standard creative-to-campaign workflow has a structural flaw. Brief goes to creative team. Creative team produces variants. Variants go to campaign manager. Campaign runs. Results come back to analyst. Analyst files the results. Next brief starts with no connection to what the analyst filed.

This is an open loop. The results do not feed back into the next brief in any systematic way. They feed back into the analyst's memory, or into a spreadsheet, or into a deck that gets presented once and then archived. The next brief starts from whatever the current team remembers plus whatever they can pull up in a search through prior campaign files.

The compounding value of campaign data leaks out of the workflow at the "results filed" step. Every brief is partially a cold start.

What a closed loop looks like

A closed context loop has a specific mechanical structure. The results from each campaign do not just go into a reporting system — they go into a context engine that is queryable at brief time. The next brief starts by querying that engine for semantically relevant, recently effective, evidenced creative history. The AI generating the brief receives that context as structured input.

The loop becomes: brief → creative → campaign → results → context engine → next brief. No information leaks at the results stage. Every campaign makes the next brief better.

Four stages of closing the loop

Stage 1: Results ingestion

At campaign end, ingest the creative and its performance data into the context engine. The creative text becomes the vector. Performance data — CTR, CPL, spend, ROAS, audience segment — becomes metadata. Spend becomes the importance weight.

def close_loop(db, campaign_result, embedder):
    hook_vec = embedder.embed(campaign_result["hook_text"])
    importance = min(1.0, campaign_result["spend"] / 100_000)

    meta = fdb.MetaRecord()
    meta.set_attribute("ctr", campaign_result["ctr"])
    meta.set_attribute("cpl", campaign_result["cpl"])
    meta.set_attribute("spend", campaign_result["spend"])
    meta.set_attribute("importance", importance)
    meta.set_attribute("audience", campaign_result["audience_segment"])

    db.add(id=campaign_result["id"], vec=hook_vec,
           text=campaign_result["hook_text"],
           namespace="brand::hooks", meta=meta)

Stage 2: Edge construction

Connect the result to the context that produced it. If the campaign brief referenced a competitor move or an audience insight, link those records to the result with typed edges:

    if campaign_result.get("competitor_context_id"):
        db.link(from_id=campaign_result["id"],
                to_id=campaign_result["competitor_context_id"],
                rel_type="responded_to", weight=0.8)

    if campaign_result.get("audience_insight_id"):
        db.link(from_id=campaign_result["id"],
                to_id=campaign_result["audience_insight_id"],
                rel_type="informed_by", weight=0.75)

Stage 3: Brief-time retrieval

def open_brief(db, brief_text, embedder):
    query_vec = embedder.embed(brief_text)
    chain = db.context_chain(
        query_vec, k=5, hops=2,
        namespace="brand::hooks",
        scoring=fdb.ScoringConfig(half_life=270.0, weight=0.3, min=0.0)
    )
    return chain.nodes  # hooks + performance evidence + competitive context

Stage 4: Structured context delivery

Format the retrieved context chain for the brief generation model. Distinguish winning hooks from evidence from competitive context, with performance numbers inline:

def format_context(chain_nodes):
    hooks    = [n for n in chain_nodes if n.hop == 0]
    evidence = [n for n in chain_nodes if n.hop == 1]
    context  = [n for n in chain_nodes if n.hop == 2]

    lines = ["## Proven hooks from brand history"]
    for h in hooks:
        ctr = h.meta.get_attribute("ctr") or "n/a"
        lines.append(f"- {h.text[:120]} [CTR: {ctr}]")
    lines.append("## Supporting evidence")
    for e in evidence:
        lines.append(f"- {e.text[:100]}")
    lines.append("## Competitive context")
    for c in context:
        lines.append(f"- {c.text[:100]}")
    return "\n".join(lines)

What the closed loop produces

Hawky.ai runs this loop for D2C brand clients. The measurable outputs: 27% CPL reduction, 20% CTR uplift within 7 days, 160 hours saved per brand per month. The hour savings come specifically from eliminating the manual creative audit step — the process of going back through campaign history at brief time is automated by the context engine retrieval.

The CPL and CTR improvements reflect the quality difference between briefs grounded in evidenced creative history and briefs generated from session context. When the creative team receives a brief with proven hooks attached — hooks with spend data, CTR, and competitive context — their output is more targeted and less likely to repeat fatigued angles.

Why this compounds

The closed loop is a compounding system. Each campaign adds to the context engine. The context engine makes the next brief better. The better brief produces better creative. The better creative generates better results. Those results add to the context engine with higher evidence weight.

After 6 months of running the loop, a brand has a context engine with enough signal to surface non-obvious patterns: which emotional angles perform best with which audience segments, which competitive contexts predict which creative responses, which offer structures drive the best LTV versus CPL tradeoff. None of this is explicitly programmed. It emerges from accumulating campaign data in a system designed to make it queryable.

The integration

pip install feather-db

The full loop — ingestion, edge construction, brief-time retrieval, context formatting — is under 200 lines of Python. No server, no managed infrastructure. One .feather file per brand, stored wherever your agent runs. The same file works with LangChain, CrewAI, a direct Feather DB call, or the MCP integration for Claude Desktop.

FAQ

What is a creative brief context loop?

A context loop connects campaign results back to the next brief systematically. Results are ingested into a context engine at campaign end. The engine is queried at the start of each new brief, surfacing relevant, evidenced creative history. Each cycle feeds the next, compounding performance over time.

How long does it take to see results from closing the brief loop?

Hawky.ai reports 20% CTR uplift within 7 days of deployment. Even a small number of ingested campaigns provides better context than the current-session approach. The improvement compounds as more campaign data accumulates.

What is the minimum data needed to close the loop?

Any completed campaign with creative text and performance data (CTR, CPL, spend) is sufficient to start. Five to ten campaigns give enough signal for meaningful retrieval differentiation. The context engine is useful from the first ingested result.

Does the loop require a specific framework or model?

No. Feather DB is framework-agnostic. The retrieval layer works with any LLM for brief generation. You can use GPT-4o, Claude, or Gemini for the generation step — the context engine just supplies the structured, evidenced context as a prompt input.