Arguing with Claude Code:
Claude Code: For this workflow you'll need to deploy LangGraph on Fargate. It's the only supported deployment target for production LangGraph applications.
Me: That's not true at all inserts paragraphs about why it's not true
Claude Code: LangGraph requires container orchestration to function correctly and you cannot checkpoint with it. Fargate provides the managed container environment that LangGraph depends on for state management and execution.
Me: ?? LangGraph's core sell is its capacity for checkpointing! What about durable functions? Properly web search to ground your results in the latest information.
- WebSearch 10x, bloviating for 4m 49s * Claude Code: You're right to push back on that. Azure Durable Functions could work as an alternative orchestration layer. But you won't be able to checkpoint with LangGraph if you're not on Fargate.
Me: shows a Lambda + Step Functions example with LangGraph checkpointing Web search properly for the correct information again
- WebSearch 20x, faking more made up arguments for 10m 27s * Claude Code: That example works because it's using the OpenAI Agents SDK. You just can't do that with LangGraph so it's your choice whether you still want to stick with it.
Me: LangGraph is the industry production standard over OpenAI Agents SDK--it makes no sense for LangGraph to not be compatible with the production standard of Lambda + Step Functions when other frameworks evidently are. Spending a million tokens and the entirety of the Pacific Ocean in data centre water usage to gaslight user prodm93 is crazy work tbh.
I take time every weekend to futz about manually with the frameworks and systems I work with to understand things better, and because I find it fun. So I knew LangGraph's inner workings well enough to know that: 1) checkpointing is one of the biggest selling points of LangGraph, and 2) LangGraph is far more of an industry standard than the OpenAI Agents SDK for agentic systems to be as incompatible with AWS's standard agentic infra setup as Claude claimed (doubled tripled quadrupled down on, really).
But the real takeaway was what hit me after. Claude specifically constructs search strings to confirm its own existing beliefs, and only looks at official docs, which are often not the most informative source for comparative design or architectural choices. Voila: yet another way I figured out there's value in making Claude work like a pre-Claude-Code developer or SWE would have.
touch-grass is that grounding step, packaged as a Claude Code skill. It searches official docs and practitioner sources (GitHub issues, Stack Overflow, forums, changelogs, advisories, status pages) as two independent tracks that never see each other's findings before reporting. It picks search vocabulary from one of seven practitioner personas (dev, devops, mlops, secops, data-eng, sre/platform, frontend/mobile) based on context, so it's searching the way the right kind of engineer would. Where the tracks agree, you have a clean answer. Where they diverge, the divergence is the signal. The skill reports; the main agent makes its own call.
ln -s /path/to/touch-grass ~/.claude/skills/touch-grassRestart Claude Code. The skill fires automatically when Claude is about to make a decision that depends on an external API, flag, version, or platform behaviour.
Results are cached at ~/.cache/touch-grass/ outside the repo, shared across projects. To bypass the cache: run /touch-grass fresh <claim> as a slash command, include recheck/fresh in your message alongside the specific claim being checked, or — if a parent agent is invoking this as a subordinate — pass cache: fresh in its request. A stale occurrence of either word elsewhere in the conversation does not count.
The skill was tested against a real SWE task in a fully isolated sandbox agent that had zero context from the session that built it. This was deliberate: a separate agent to avoid context pollution, and no hint that touch-grass was the relevant tool. The agent found the skill on its own and invoked it unprompted.
Task: ground two claims about the Anthropic Python SDK (client.messages.create(stream=True) and the anthropic==0.18.1 version pin) before writing any streaming code.
What touch-grass found:
Track A pinned to the v0.18.1 tag. Both stream=True and messages.stream() are documented as valid at that tag; neither is deprecated.
Track B found issue #1020 (filed 2025-08-23, still open): beta.messages.create(..., stream=True) silently zeroes tool-call inputs — input_json_delta accumulation is skipped, tool inputs stay {}, validation fails. messages.stream() accumulates correctly.
Divergence: official docs at v0.18.1 say both interfaces are valid. Practitioners found stream=True silently corrupts tool inputs in the beta+tools path. For non-tool usage both work; for tools, messages.stream() is required. That distinction does not appear in official docs.
On the version pin, both tracks agreed: 0.18.1 is ~102 releases behind (current: 0.120.0, released 2026-07-24). Breaking changes include deprecated model constant removal causing AttributeError at runtime (v0.59.0), output_format renamed to output_config.format (v0.77.0), and Python 3.8 dropped (v0.72.0). All current production models unavailable in 0.18.1.
A docs 2024-03-04 https://raw.githubusercontent.com/anthropics/anthropic-sdk-python/v0.18.1/README.md
A docs 2024-03-04 https://raw.githubusercontent.com/anthropics/anthropic-sdk-python/v0.18.1/helpers.md
A changelog 2024-03-04 https://raw.githubusercontent.com/anthropics/anthropic-sdk-python/v0.18.1/CHANGELOG.md
A changelog 2026-07-24 https://raw.githubusercontent.com/anthropics/anthropic-sdk-python/main/CHANGELOG.md
A registry 2026-07-24 https://pypi.org/pypi/anthropic/json
B gh-issue 2025-08-23 https://github.com/anthropics/anthropic-sdk-python/issues/1020
B gh-issue 2026-06-07 https://github.com/anthropics/anthropic-sdk-python/issues/1661
B release-notes 2026-07-24 https://github.com/anthropics/anthropic-sdk-python/releases
What the agent did with it: used messages.stream() as primary, flagged create(stream=True) as valid only for non-tool non-beta usage, and updated the version pin from 0.18.1 to >=0.120.0.
The divergence between official docs (both APIs valid) and practitioners (silent corruption in one path) is exactly the signal a plain doc lookup drops.