feat(website): add 'LangGraph Subgraphs: When to Split a Graph' blog post - #840
Closed
blove wants to merge 1 commit into
Closed
feat(website): add 'LangGraph Subgraphs: When to Split a Graph' blog post#840blove wants to merge 1 commit into
blove wants to merge 1 commit into
Conversation
…post Publishes the post drafted on blove/langgraph-subgraphs-post, updated for what #838 changed and for two claims that needed sharpening. The post's thesis is that a subgraph gives you an observable boundary, not a state one, and that "subgraph" and "tracked subagent" are different things. Until #838 the repo could only demonstrate half of that: both graphs that populate `subagents()` invoke their compiled child from inside a `@tool` body. `cockpit/langgraph/subgraphs` is now the plain-node counterpart, so the post cites it as the other half of the pair. Two substantive edits beyond the draft: - Added how the state boundary is actually drawn. LangGraph passes state through the keys the two schemas *share*, so the boundary is the shape of the overlap rather than a wall — a child with no `messages` key cannot reach the transcript because no channel exists, not because anything blocks it. - Corrected the transcript section. The draft implied `filterSubagentMessages` is the lever for keeping child tokens out of `messages()`. It isn't, for a plain subgraph node: the filter sits inside a branch guarded by `isSubagentNamespace()`, which only matches `tools:`, so a `research:<uuid>` namespace never reaches it. `transcriptNodeNames` is the lever for that shape. Also noted the failure mode is mid-stream with a clean end state, which is why a final-state assertion cannot catch it. Every technical claim re-verified against the code: `streamSubgraphs ?? true`, `filterSubagentMessages` default-off and its guard placement, the attribution heuristic (exact `description`, then substring either direction, then unmapped pending/running fallback), first-`tools:`-segment-only namespace parsing, and the namespaced-terminal-evidence guard test. Tightened that last claim: the test asserts outcome `interrupted`, while phase is still `complete`. Excludes the handoff doc from the source branch — it covers a broader blog sequence and there is no top-level handoff convention under docs/superpowers. Verified: website builds; post prerenders at /blog/langgraph-subgraphs-when-to-split with its OG image; blog + sitemap specs pass (26/26); all four outbound links return 200 in production. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Author
|
Superseded by #839, which landed the same post from a later, more developed draft while this was in flight — it already covers the state-boundary mechanism, cites One correction from here isn't in #839 and I'm opening it separately: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Publishes the post drafted on the local
blove/langgraph-subgraphs-postbranch, rebased onto main and updated for what #838 changed.Why now
The post's thesis: a subgraph gives you an observable boundary, not a state one — and "subgraph" and "tracked subagent" are different things. Until #838 the repo could only demonstrate half of that. Both graphs that populate
subagents()(examples/chatandcockpit/chat/subagents) invoke their compiled child from inside a@toolbody, because the tool call is what the tracker registers.cockpit/langgraph/subgraphsis now the plain-node counterpart, so the post can cite both mechanisms instead of describing one and asserting the other.Edits beyond the draft
How the boundary actually gets drawn. LangGraph passes state into and out of a subgraph node through the keys the two schemas share. The boundary is the shape of the overlap, not a wall — a child with no
messageskey can't reach the transcript because no channel exists for it, not because anything blocks it.Corrected the transcript section. The draft implied
filterSubagentMessagesis the lever for keeping child tokens out ofmessages(). It isn't, for a plain subgraph node:A
research:<uuid>namespace never enters that branch, so the option is a no-op for that shape.transcriptNodeNamesis the lever. I also added that the failure mode is mid-stream with a clean end state — the parent's finalvaluesevent rewrites the message list from authoritative graph state, so the stray bubble vanishes on its own and a final-state assertion cannot catch it. That's not theory: it's what I measured against a live model while building #838 (message count transiently 3, settling to 2).Claim verification
Re-checked every technical claim against the code rather than trusting the draft:
streamSubgraphsdefaults true, option namedstreamSubgraphsfetch-stream.transport.ts:154,agent.types.ts:115filterSubagentMessagesoptional, off by defaultdescription→ substring either direction → unmapped pending/running fallbacksubagent-tracker.ts:130-175, exactly as describedtools:segment is readextractToolCallIdFromNamespacestream-manager.bridge.spec.ts:478subagents()guides/subgraphs.mdx:114One claim tightened: the draft said the parent message "settles as
interruptedrather than complete." The test assertsphase: 'complete', outcome: 'interrupted'— phase is complete. Reworded to "outcomeinterruptedrather than a clean completion."Scope note
Excludes
HANDOFF-blog-sequence.mdfrom the source branch — it covers a broader blog sequence rather than this post, and there's no top-level handoff convention underdocs/superpowers/(onlyaudits/,context/,plans/,specs/).Verification
nx build websitegreen; post prerenders at/blog/langgraph-subgraphs-when-to-splitwith its OG image, and appears in the blog index and sitemap.blog.spec.ts+sitemap-dates.spec.ts: 26/26 pass.apps/websitehas no Nx test target, so these never run in CI. Unrelated to this change and left alone.🤖 Generated with Claude Code