032025-nowAI · BackendFounding Engineer

Agentic contentediting framework

A content-agnostic agentic editing system built on LangGraph and dependency injection. New content types plug in via config alone. The 3-phase split-execution pipeline decouples low-latency SSE streaming from LangGraph's node-update model, while targeted LLM edits replace full-document regeneration and cut token consumption by ~60%.

Token reduction
~60%
Pipeline phases
3-phase split
LLM providers
multi-provider
Frontend coverage
86% achieved

The problem

The platform needed AI-powered editing across multiple content types: structured tables, markdown documents, bullet lists. The naive approach was full-document regeneration on every edit, which was wasteful, slow, and prone to silent rewrites that changed content the user hadn't touched.

Adding a new content type required touching core graph nodes. The system was tightly coupled to its first content format, and every new type was a fork of existing logic.

Constraint
The pipeline had to stream tokens to the frontend via Server-Sent Events in real-time, but LangGraph's node-update model doesn't natively support token-level streaming. These two requirements had to be reconciled without a parallel data plane.

The architecture

A 3-phase split-execution pipeline. Phase 1 (setup graph) resolves the content type and classifies intent using heuristic keyword/modifier matching, deferring to the LLM only on ambiguous inputs. Phase 2 runs token-level streaming via SSE. Phase 3 runs a validation graph with auto-retry on malformed output.

3-phase pipeline: setup, SSE stream, validation with auto-retry
# phase 1: heuristic intent classification
def classify_intent(op, content_type):
    if keyword_match(op):
        return resolve_modifier(op)
    return llm_classify(op, content_type)  # LLM fallback

# phase 2: token-level SSE stream
async def stream_edit(graph, op):
    async for tok in graph.stream(op):
        yield f'data: {tok}\n\n'

# phase 3: validate + auto-retry
await validation_graph.run(result)

Dependency injection lets new content types register via configuration with zero changes to core graph nodes. A targeted-operations protocol (edit, split, delete, insert) replaces full-document regeneration while preserving untouched content verbatim.

Details that mattered

  • Partial-output continuation: detects truncated JSON via item-count vs. schema completeness, narrows the target range, and reissues a continuation prompt with prior output as tonal anchor.
  • Word-level diffs: difflib.SequenceMatcher producing per-field, position-aligned change spans. Removed words are struck through in red, additions highlighted in green.
  • Length preservation: prompt-level per-item character/word counts with ±20% guardrails prevented detail loss during model edits.
  • Multi-turn refinement: conversation-history accumulation so models received full context across iterative edits.
  • Resilient JSON parsing: fence stripping, bracket repair, and regex fallback extractors for malformed or truncated outputs across multiple LLM providers.
Result
~60% reduction in token consumption vs. full-document regeneration. Zero core-node changes when onboarding a new content type. Streaming latency fully decoupled from LangGraph's node-update cycle.