forefetch Get a key
The guide
forefetch, step by step.

Everything from zero to measured numbers on your own pipeline. You will need an API key: email us for one.

Your agents constantly look things up: "what's our refund policy?", "what did the last agent find?". Every lookup is a pause in your pipeline. forefetch is a memory service that learns your pipeline's rhythm and has the answer ready before the agent asks. You wire it in with a few calls, and it shows you, in numbers, on your own pipeline, how much waiting it removed.

Why bother: what we've measured so far

Plug it in

You get two things from us: the address https://api.forefetch.com and your own API key. The key is your private space on the server: your own memory engine, your own database file; no other tenant's data can touch yours.

pip install forefetch-client            # one dependency (httpx)

If your team runs on Agno: one line

from forefetch_client.agno import remember_team

team = Team(members=[triage, resolver], ...)        # your team, exactly as it is today
team = remember_team(team, "https://api.forefetch.com", api_key="yourkey",
                     knowledge={"Resolver": policy_docs})   # <- the whole integration

That's it. Every member gets its own isolated memory stream; relevant knowledge is retrieved into each member's context before it runs; every answer feeds the prediction engine (never quoted back as a fact); upstream members' conclusions arrive downstream as labeled hints; sessions close themselves when a team run ends. Your prompts, models, and delegation logic are untouched. The scorecard is one call away: team.forefetch["resolver"].report().

Any other framework: a ten-line wrapper

Below is the same integration written out by hand: LangGraph, CrewAI, or plain functions, the pattern is identical. A complete support pipeline: triage reads the ticket, resolver fixes it. Everything forefetch-related is marked: the agents are plain Agno.

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from forefetch_client import MemoryClient

BASE, KEY = "https://api.forefetch.com", "yourkey"

# ---- your agents, exactly as you'd build them without forefetch ------------------
triage = Agent(name="triage", model=OpenAIChat(id="gpt-4o-mini"),
               instructions=["Read the ticket. State the problem type and root cause."])
resolver = Agent(name="resolver", model=OpenAIChat(id="gpt-4o-mini"),
                 instructions=["Resolve the ticket. Use the CONTEXT lines in the prompt."])

# ---- forefetch setup: one memory stream per agent --------------------------------
triage_mem   = MemoryClient(BASE, api_key=KEY, stream="triage")
resolver_mem = MemoryClient(BASE, api_key=KEY, stream="resolver")

# load each agent's knowledge ONCE: docs, policies, past resolutions
resolver_mem.remember([
    "refund policy: duplicate charges are refunded in full within 5 business days",
    "ticket #1042 resolved: customer double-charged on invoice, refunded the duplicate",
])

# ---- the whole integration is this wrapper ---------------------------------------
def run_agent(agent, memory, task: str) -> str:
    """Memory in before the agent runs; memory out after it acts."""
    ctx = memory.retrieve(task, k=4, full_suggestions=True)
    #   ctx["items"]     -> this agent's own relevant rows (policy, past ticket...)
    #   ctx["wire_frac"] -> 1.0 means it was ALL already here before we asked
    hints = memory.suggest(k=3)
    #   context the agent didn't ask for, each labeled with why it's offered, e.g.
    #   {"kind": "handoff", "from_stream": "triage", "text": "triage concluded: ..."}
    context = [i["text"] for i in ctx["items"]] + \
              [f"[{h['kind']} from {h.get('from_stream', 'memory')}] {h['text']}"
               for h in hints]
    prompt = task + "\n\nCONTEXT:\n" + "\n".join(f"- {c}" for c in context)

    answer = agent.run(prompt, stream=False).content        # your framework, unchanged

    memory.observe(f"{memory.stream} concluded: {answer[:400]}", derived=True)
    #   ^ the important one: this is how forefetch learns your rhythm and gets the
    #     NEXT thing ready: it returns instantly, the work happens in the background.
    #     derived=True marks it as the agent's OWN answer: prediction fuel, never
    #     quoted back as a fact (facts you observe yourself leave it False)
    return answer

# ---- run a ticket through the pipeline -------------------------------------------
ticket = "I was charged twice for invoice INV-2291."

finding = run_agent(triage, triage_mem, f"triage this ticket: {ticket}")
triage_mem.flush()      # triage's observe ships in the background; flush before the
                        # next agent runs so the server has seen triage's conclusion

fix = run_agent(resolver, resolver_mem, f"resolve this ticket: {ticket}")
#   by this point the resolver's suggest() already carried triage's finding, labeled
#   "handoff from triage": forefetch noticed that resolver always runs after triage
#   and primed it while triage was still talking to the LLM

triage_mem.end_session()          # ticket done: close the episode and pre-warm
resolver_mem.end_session()        # each agent's NEXT session with its usual first needs

That's the entire integration: your prompts, models, and pipeline logic stay untouched. The same wrapper connects forefetch to any framework (LangGraph, CrewAI, plain functions): retrieve + suggest before the agent runs, observe after it acts, end_session when the task truly ends.

Two rules of thumb:

  1. Observe real events: conclusions, decisions, tool results. A pipeline that only retrieves gives forefetch nothing to learn from.
  2. end_session() means the task is really done: next-session predictions are built from what finished sessions did first.

Read your scorecard

resolver_mem.report()
{
  "anticipation": true,
  "streams": [
    {"stream": "resolver", "rows": 214, "retrievals": 96, "scored": 92,
     "mean_hit_frac": 0.71, "fully_ready": 61}
  ],
  "wire": {"retrievals": 96, "full_serves": 58, "pushed_rows": 388, "wire_serve_rate": 0.60},
  "handoffs": {"triage->resolver": {"count": 31, "p": 0.94}}
}

Three numbers matter:

Expect low numbers for the first few tickets: forefetch needs ~3 repetitions to trust a handoff pattern and a few finished sessions to predict session starts. Then they climb.

Prove it to yourself (please do this)

Your key also works on a second address running the same server with all prediction turned off: a genuinely ordinary, reactive memory:

https://api.forefetch.com          # prediction on
https://reactive.forefetch.com     # same code, prediction off

Run the same tickets against both. On the reactive one, mean_hit_frac stays at 0 and every retrieve ships everything. The difference between the two report()s is what forefetch bought your pipeline: measured by you, not claimed by us.

What we'd love back

  1. The two report() outputs (prediction on and off), plus a rough sketch of your pipeline: how many agents, typical session length.
  2. One sentence on whether the labeled hints helped your agents: or ever got in the way.
  3. Whatever annoyed you. The missing API, the confusing step, the number you wanted to see.

If forefetch buys your pipeline nothing, that finding is exactly as valuable to us as a win : this project has cut its own features over honest measurements before.

Honest limits (design-partner build, not an SLA product)

Contact

Yashvardhan Goel: [email protected]