# Living Context Engine for Sales Agents and SDR Automation: Memory That Closes Deals > SDR automation generates a feedback signal richer than almost any other AI workload — every reply, every disqualification, every booked meeting is data. A Living Context Engine captures all of it. This is the architecture. - **Category**: Use Case - **Read time**: 12 min read - **Date**: May 15, 2026 - **Author**: Feather DB Engineering (Engineering Team) - **URL**: https://getfeather.store/theory/living-context-engine-sales-sdr-automation --- # Living Context Engine for Sales Agents and SDR Automation: Memory That Closes Deals *Use Case · SDR Automation · May 2026* --- ## The Sales Stack Without Memory Most SDR automation tools in 2026 do one thing well: send a lot of templated outreach. The templates are tuned by a human, the prospects are bucketed by a basic ICP match, and the AI's role is to vary the surface (subject line, opener) within the template. The substrate underneath — every reply, every objection, every booking — is captured in the CRM and disconnected from the AI that's generating the next outreach. The pattern is identical to support and marketing AI: a system that generates output, a system that records outcomes, and no connective tissue between them. The result is SDR AI that feels generic — because it is — and that improves only when a human updates the templates. A Living Context Engine connects the two systems. Outreach generation reads from the same substrate that outcome capture writes to. Every reply tunes the next message. ## The Graph Shape ### Node Types NodeContentHalf-life ProspectName, role, company, ICP signals180 days AccountCompany-level info, tech stack, size365 days OutreachMessage sent, channel, sequence step60 days ReplyProspect response (positive / neutral / negative)180 days ObjectionExtracted concern: pricing, timing, fit, etc.365 days (high importance) Won patternMessage + reply + booking sequence that worked730 days (high importance) Lost patternSequence that failed, with reason365 days Talk trackApproved value-prop framing for a buyer persona730 days ### Edge Types - `sent_to` — Outreach → Prospect - `responds_to` — Reply → Outreach - `belongs_to` — Prospect → Account - `contains_objection` — Reply → Objection - `derived_from` — Outreach → Talk track / Won pattern - `generalizes` — Won pattern → Talk track - `contradicts` — Lost pattern → Talk track (when a track stops working) ## The Loop in Action ### 1. Outbound preparation A new prospect lands in the queue. The agent calls `context_chain`: ```python chain = db.context_chain( embed(prospect.profile), k=10, hops=2, edge_types=["belongs_to", "derived_from", "generalizes", "contains_objection"], ) ``` The returned subgraph: similar prospects (semantic match), their accounts, the outreach that landed bookings with them, the talk tracks those outreaches derived from, and — critically — any objections from similar-profile prospects. ### 2. Message generation The agent generates the outreach knowing what worked for this prospect type, what objections to preempt, and which talk track to lean on. The agent isn't "creative" — it's *contextually grounded*. The substrate carries the team's earned knowledge of what closes. ### 3. Update — every send writes back The Outreach node is added with `sent_to` edge to the Prospect. The talk track it derived from gets an `derived_from` edge. ### 4. Decay — replies are the signal When a reply lands, it's added as a Reply node with `responds_to`. An LLM-judge call extracts any objections (added as Objection nodes with `contains_objection` edges). If the reply leads to a booking, the entire chain (Outreach → Reply → Booking) becomes a Won pattern with very high importance, edged `generalizes` to the Talk track it used. If the prospect goes silent or disqualifies, a Lost pattern is created. Importance multipliers compound. A talk track that produces three Won patterns in a quarter has its importance multiplier raised. The next outreach generation for similar prospects retrieves it more reliably. ## What Compounds ### Persona-Specific Talk Tracks By month two, the substrate has distinguished talk tracks that work for VP-of-Engineering prospects from those that work for VP-of-Marketing. Not because anyone tagged them — because the Won patterns segregate by persona via the typed edges to Prospect profiles. ### Objection Pre-Emption When you've sent enough outreach to similar profiles, the Objection nodes for that profile accumulate. The agent generating new outreach retrieves the connected objection cluster and addresses the top concern proactively. Reply rates climb because the substrate carries the team's history of "what these prospects worry about." ### Account-Level Coherence When a second contact at the same Account is approached, the agent retrieves the entire prior history with that Account — every prior contact, every reply, every meeting booked or missed. The outreach is contextual at the Account level, not just the Prospect level. ### Lost-Pattern Awareness Talk tracks that stop working — because the market shifted, because a competitor moved, because the product changed — produce Lost patterns. Their `contradicts` edges suppress the affected Talk tracks via importance decay. The team doesn't have to manually retire outreach that has stopped working. ## An End-to-End Snapshot ```python def generate_outreach(db, prospect, llm): chain = db.context_chain( embed(prospect.profile + " " + prospect.company), k=10, hops=2, edge_types=["belongs_to", "derived_from", "generalizes", "contains_objection"], ) won_patterns = [n for n in chain.nodes if n.metadata.get("kind") == "won_pattern"] objections = [n for n in chain.nodes if n.metadata.get("kind") == "objection"] talk_tracks = [n for n in chain.nodes if n.metadata.get("kind") == "talk_track"] outreach = llm.generate_outreach( prospect=prospect, winning_examples=won_patterns, likely_objections=objections, approved_tracks=talk_tracks, ) out_id = add_node(db, outreach.text, kind="outreach") db.link(out_id, prospect.node_id, edge_type="sent_to") for tt in talk_tracks[:1]: db.link(out_id, tt.id, edge_type="derived_from") return outreach, out_id def on_reply(db, outreach_id, prospect_id, reply_text, llm): reply_id = add_node(db, reply_text, kind="reply") db.link(reply_id, outreach_id, edge_type="responds_to") for objection in llm.extract_objections(reply_text): obj_id = add_node(db, objection, kind="objection", importance=1.5) db.link(reply_id, obj_id, edge_type="contains_objection") return reply_id def on_booked(db, outreach_id, prospect_id): won_id = add_node(db, f"won pattern: {outreach_id}->{prospect_id}", kind="won_pattern", importance=2.5) db.link(won_id, outreach_id, edge_type="derived_from") # boost the talk track that produced it for nid, etype in db.neighbors(outreach_id, types=["derived_from"]): reinforce(db, [nid], signal_strength=2.0) ``` ## What You'll Measure - Reply rate trends upward across months. The substrate accumulates Won patterns. - Booking-from-reply rate trends upward. Objection pre-emption gets sharper. - Time-to-first-booking for new SDRs collapses. They inherit the institutional memory instead of building it from scratch. ## Why This Is a Generational Shift SDR automation in 2024–2025 was templates plus AI surface variation. SDR automation with a Living Context Engine is genuinely different: the AI's outreach is informed by the team's full history of what works and what doesn't, updated in real time, decaying when patterns expire. The teams that build this substrate first will outpace the ones running templated AI by orders of magnitude on the metric that matters — booked meetings per outreach sent. --- *Related: [The Context Engine Loop](/theory/context-engine-loop-intelligence) · [Closing the Loop in Feather DB](/theory/closing-the-loop-feather-db).* --- *This is the machine-readable mirror of the theory post at [getfeather.store/theory/living-context-engine-sales-sdr-automation](https://getfeather.store/theory/living-context-engine-sales-sdr-automation). For the full Feather DB documentation, see [getfeather.store/llms-full.txt](https://getfeather.store/llms-full.txt).*