docs-code-samples

작성자: langchain-ai

Use this skill when migrating inline code samples from LangChain docs (MDX files) into external, testable code files that are extracted by this repo’s snippet…

npx skills add https://github.com/langchain-ai/docs --skill docs-code-samples

docs-code-samples

Overview

This skill documents the workflow for moving inline code samples from LangChain documentation into standalone, testable files that this repo extracts into snippets for use in MDX using Mintlify.

When to use

  • Migrating inline Python, TypeScript/JavaScript, or Java code blocks from MDX to external files
  • Creating runnable, testable code samples for documentation
  • Setting up snippet extraction and Mintlify snippet includes

Directory structure

Code samples live under src/code-samples/ in folders that match the product:

  • langchain/ — LangChain docs
  • langgraph/ — LangGraph docs
  • deepagents/ — Deep Agents docs
  • langsmith/ — LangSmith docs

Example:

src/
├── code-samples/              # Source: testable code with snippet tags
│   ├── langchain/
│   │   ├── return-a-string.py
│   │   └── return-a-string.ts
│   ├── langgraph/
│   │   ├── langgraph-sql-agent.py
│   │   └── langgraph-sql-agent.ts
│   ├── deepagents/
│   │   └── example-skill.py
│   └── langsmith/
│       ├── trace-example.py
│       └── trace-example.java
├── code-samples-generated/    # Snippet output (gitignored)
│   ├── return-a-string.snippet.tool-return-values.py
│   ├── return-a-string.snippet.tool-return-values.ts
│   └── ...
└── snippets/
    └── code-samples/          # MDX snippets for docs (all products)
        ├── tool-return-values-py.mdx
        ├── tool-return-values-js.mdx
        └── ...

Prefer one file per doc page or topic: Collocate related snippets in a single code sample file whenever they belong to the same MDX page, tutorial flow, or feature (for example, setup plus invocation, or a do/don't pair). Use multiple :snippet-start: / :snippet-end: pairs in that file rather than splitting into several .py or .ts files. Reserve separate files for unrelated samples or when a page genuinely needs independent test entry points.

More than one snippet in one file: A single code sample file can contain more than one named snippet using different :snippet-start: snippet-name and :snippet-end: pairs. Each snippet must have a unique name. Shared imports, helpers, and :remove-start: test harness code live once in the file; only the fenced regions between snippet tags appear in the generated MDX snippets.

When to split TypeScript samples into separate files: Python samples can usually keep multiple snippets in one file because later definitions overwrite earlier ones at module scope. TypeScript and JavaScript cannot: make test-code-samples runs the entire .ts file, and every snippet's code executes in the same module scope. Split into separate .ts files when snippets would collide, for example:

  • Duplicate import bindings (for example two snippets both import { interrupt } from "@langchain/langgraph")
  • Duplicate const / let / class / function declarations with the same name (for example two snippets both declare const State = ...)
  • Two self-contained snippets that each need their own imports and top-level setup

Keep related snippets in one Python file when possible. For TypeScript, use one file per independently runnable snippet when imports or top-level bindings would conflict. Name sibling files clearly, for example langgraph-interrupts-validate-conditional-edge-pattern.ts and langgraph-interrupts-validate-conditional-edge.ts. Put shared test-only setup in :remove-start: blocks inside each file rather than importing between sample files.

Within a single TypeScript file, :remove-start: blocks and snippet regions share the same module scope when make test-code-samples runs the file. Do not import the same binding in both places. Keep imports that appear in the docs snippet inside the snippet; limit :remove-start: imports to symbols used only by the test harness (for example Command, MemorySaver) that the snippet does not import.

Step-by-step instructions

1. Create the code sample file

Place the file under src/code-samples/ in the folder for the product: langchain/, langgraph/, deepagents/, or langsmith/ (for example, src/code-samples/langgraph/langgraph-sql-agent.py for LangGraph docs).

Use a descriptive filename, for example, return-a-string.py, return-a-string.ts, or traceable-pipeline.java. When a doc page needs several code blocks for the same feature, add them as multiple snippets in one Python file (for example, rubric-configure.py with rubric-configure-py and rubric-invoke-py) instead of creating rubric-configure.py and rubric-invoke.py. For TypeScript, use one file per snippet when module-scope imports or bindings would conflict (see When to split TypeScript samples into separate files above).

2. Add snippet delineators

Wrap the code that should appear in the docs with snippet tags:

Python:

# :snippet-start: snippet-name-py
from langchain.tools import tool

@tool
def get_weather(city: str) -> str:
    """Get weather for a city."""
    return f"It is currently sunny in {city}."

# :snippet-end:

TypeScript/JavaScript:

// :snippet-start: snippet-name-js
import { tool } from "langchain";
// ... tool definition ...
// :snippet-end:

Java:

// :snippet-start: snippet-name-java
public class Example {
  public static void main(String[] args) {
    System.out.println("hello");
  }
}
// :snippet-end:

Go:

// :snippet-start: snippet-name-go
package main

import "fmt"

func main() {
	fmt.Println("hello")
}
// :snippet-end:

Bash (cURL):

# :snippet-start: snippet-name-sh
curl "https://api.smith.langchain.com/api/v1/runs" \
  -H "x-api-key: $LANGSMITH_API_KEY"
# :snippet-end:

Choose a unique snippet-name in kebab-case. All snippet names must include a language suffix: -py for Python files, -js for TypeScript/JavaScript files, -java for Java files, -kt for Kotlin files, -go for Go files, and -sh for bash/cURL files (for example, tool-return-values-py, tool-return-values-js, traceable-pipeline-java, traceable-pipeline-kt, traceable-pipeline-go, traceable-pipeline-sh). This becomes the base of the output filename.

3. Add runnable test code in remove blocks

Wrap any code that makes the sample executable but should not appear in docs.

Run snippet code before exiting. make test-code-samples must execute the snippet body, not skip it. Do not put raise SystemExit(0), process.exit(0), or exit 0 at the top of a file (or before :snippet-start:) so the test passes without running imports, constructors, or API calls. That only checks that the file parses; it does not validate function signatures, option shapes, or import paths.

Place :remove-start: blocks after the snippet when you can, so the harness runs assertions on values the snippet created:

Python (preferred):

# :snippet-start: example-py
from deepagents import create_deep_agent

agent = create_deep_agent(model="google_genai:gemini-3.6-flash")
# :snippet-end:

# :remove-start:
assert agent is not None
print("✓ example validated")
# :remove-end:

TypeScript (preferred):

// :snippet-start: example-js
import { DeepAgentsServer } from "deepagents-acp";

const server = new DeepAgentsServer({
  agents: { name: "careful-agent", interruptOn: { write_file: true } },
});
// :snippet-end:

// :remove-start:
if (!server) throw new Error("server not created");
console.log("✓ example validated");
// :remove-end:

For samples whose docs show a blocking tail (for example await server.start(), asyncio.run(main()), or agent.invoke() with a live model), keep setup and construction in the snippet so types and signatures are checked, then move only the blocking call into a trailing :remove-start: block—or omit it when construction alone is enough:

# :snippet-start: server-example-py
server = AgentServerACP(agent)
# :snippet-end:

# :remove-start:
# Do not call await run_agent(server) here — it blocks on stdio.
assert server is not None
print("✓ server-example validated")
# :remove-end:

Do not short-circuit before the snippet:

# :remove-start:
raise SystemExit(0)  # BAD: snippet below never runs
# :remove-end:

# :snippet-start: example-py
...

The examples below show harness code that invokes behavior when the snippet defines callable helpers:

Python:

# :remove-start:
if __name__ == "__main__":
    result = get_weather.invoke({"city": "San Francisco"})
    assert result == "It is currently sunny in San Francisco."
    print("✓ Tool works as expected")
# :remove-end:

TypeScript:

// :remove-start:
async function main() {
  const result = await getWeather.invoke({ city: "San Francisco" });
  if (result !== "It is currently sunny in San Francisco.") {
    throw new Error(`Expected "...", got "${result}"`);
  }
  console.log("✓ Tool works as expected");
}
main();
// :remove-end:

The extraction script strips :remove-start: / :remove-end: content when extracting snippets.

4. Test the code sample

Before extracting snippets, verify the code sample runs correctly:

# Test the file(s) you added (faster)
make test-code-samples FILES="src/code-samples/langchain/return-a-string.py"

# Or run all code samples
make test-code-samples

For multiple files: FILES="path1 path2". Fix any failures before proceeding—do not extract snippets until the samples pass.

Java files (.java) under src/code-samples/ are run using jbang. To keep CI green, Java samples must:

  • Print at least one line of output so it's obvious the sample ran
  • Exit successfully (code 0) when optional API keys are not set, for example:
    • OPENAI_API_KEY for LLM calls
  • Fail fast (non-zero exit) when a key is required for the sample to run, for example manage-prompts-0-push.java without LANGSMITH_API_KEY

make test-code-samples runs every .java file under src/code-samples/ in lexical path order (after all Python and TypeScript samples). That order is unrelated to section order in the docs. If one sample must run before another (for example creating a hub prompt before pulling it), name the source files so they sort correctly. For example, manage-prompts-pull.java runs before manage-prompts-push.java because pull sorts before push; use prefixes such as manage-prompts-0-push.java and manage-prompts-1-pull.java when you need push to run first.

Go files (.go) under src/code-samples/ are run with go run from src/code-samples/, which shares a single go.mod/go.sum at that directory (add new dependencies there with go get, then go mod tidy, similar to how .ts samples share src/code-samples/package.json). go run <file>.go only compiles that one file, not its sibling files in the same directory, so — like Kotlin — put each snippet variant in its own file (topic-before.go, topic-after.go) rather than multiple snippets sharing one file: two files in the same package cannot both declare func main(). Go samples do not guard on missing keys — let the SDK call fail fast (matching Python's behavior) rather than skipping with a printed message. make test-code-samples runs .go files last, after Kotlin, in lexical path order.

Bash/cURL files (.sh) under src/code-samples/ are run with bash <file>.sh from src/code-samples/. Like Go, put each snippet variant in its own file (topic-before.sh, topic-after.sh) rather than sharing one file. Hide test-only setup (#!/usr/bin/env bash, set -euo pipefail, resolving a real ID/value for a <placeholder> shown in the docs) in # :remove-start:/# :remove-end: blocks so the visible snippet is exactly the illustrative curl command a reader would copy — including no shebang or set -e line. curl does not exit non-zero on an HTTP error status by itself, so when a script pipes a response into jq to extract a value used by a later request (for example resolving a project ID), add a hidden check that the resolved value is non-empty and not the literal string null before continuing, so a bad API response fails the test loudly instead of silently propagating into later requests. make test-code-samples runs .sh files last, after Go, in lexical path order.

Check formatting with:

make lint

Fix any ruff or mypy issues before proceeding. Run make format to auto-fix formatting.

5. Run snippet extraction

From the repo root:

make code-snippets

For LangSmith JVM samples only (faster; updates stems listed in CODE_SNIPPET_LANGSMITH_SOURCES in the Makefile):

make code-snippets-langsmith

This command:

  1. Runs python scripts/extract_code_snippets.py (line-based, Bluehawk-compatible; handles /** in TS strings). Optional env CODE_SNIPPET_SOURCES limits extraction to specific paths under src/code-samples/ (make code-snippets-langsmith sets this).
  2. Runs scripts/generate_code_snippet_mdx.py to produce MDX snippets in src/snippets/code-samples/ (always regenerates MDX from everything under src/code-samples-generated/)

Output files:

  • return-a-string.snippet.tool-return-values.pytool-return-values-py.mdx
  • return-a-string.snippet.tool-return-values.tstool-return-values-js.mdx

6. Update the MDX file to use the snippet

Add an import at the top of the MDX file (after frontmatter):

import ToolReturnValuesPy from '/snippets/code-samples/tool-return-values-py.mdx';
import ToolReturnValuesJs from '/snippets/code-samples/tool-return-values-js.mdx';

Replace the inline code blocks with the snippet components:

:::python

<ToolReturnValuesPy />

:::

:::js

<ToolReturnValuesJs />

:::

Naming conventions

ElementConventionExample
Code fileDescriptive, kebab-casereturn-a-string.py, return-a-string.ts, traceable-pipeline.java, traceable-pipeline.kt, traceable-pipeline.go, traceable-pipeline.sh
Snippet nameKebab-case with language suffix: -py for Python, -js for JS/TS, -java for Java, -kt for Kotlin, -go for Go, -sh for bash/cURLtool-return-values-py, tool-return-values-js, traceable-pipeline-java, traceable-pipeline-kt, traceable-pipeline-go, traceable-pipeline-sh
MDX snippet (Python){snippet-name}.mdx (snippet name ends in -py)tool-return-values-py.mdx
MDX snippet (JS){snippet-name}.mdx (snippet name ends in -js)tool-return-values-js.mdx
Component namePascalCaseToolReturnValuesPy, ToolReturnValuesJs

Script behavior

scripts/generate_code_snippet_mdx.py:

  • Reads *.snippet.*.py and *.snippet.*.ts from src/code-samples-generated/
  • Wraps content in fenced code blocks (```python or ```ts)
  • When a snippet contains a model string, expands it into a Mintlify <CodeGroup> with the seven quickstart provider tabs (Google, OpenAI, Anthropic, OpenRouter, Fireworks, Baseten, Ollama):
    • Python: model="…" or model = "…"
    • TypeScript: model: "…" or model = "…" (including let model = "…")
    • Only the quoted model ID is swapped per tab, so assignment vs property syntax is preserved
    • Put # KEEP MODEL / // KEEP MODEL on the line before a model string to leave that occurrence unchanged
  • Writes to src/snippets/code-samples/{snippet-name}-py.mdx or -js.mdx

To support additional languages, add config entries in that script.

Guidelines

  • Run snippet code in tests:remove-start: harnesses must not exit before the snippet runs. Let imports, constructors, and configuration execute so make test-code-samples catches wrong signatures, renamed options, and broken import paths. Put SystemExit / process.exit only after the snippet (or use them to skip a trailing blocking call such as server.start(), not the whole sample).
  • Collocate related snippets in one code sample file per doc page or feature when possible (Python and Java). Import each generated MDX snippet separately in the MDX file (for example, <RubricConfigurePy /> then <RubricInvokePy /> from the same source file). For TypeScript, split into separate .ts files when snippets duplicate imports or top-level bindings; still import each generated MDX snippet in the MDX file the same way.
  • Do not mock LangChain internals (for example unittest.mock.patch on init_chat_model helpers) so that imports resolve real chat model instances. Do not use fake chat models in docs code samples (for example GenericFakeChatModel, FakeListChatModel, or other langchain_core testing fakes). Wire a real chat model (for example ChatOpenAI) so snippets match what readers run; make test-code-samples requires a valid API key when the sample calls the model.
  • Do not change pyproject.toml when making code sample changes.
  • Always run make test-code-samples FILES="path/to/your/file.py" before make code-snippets to ensure new samples pass.
  • Run make lint once the code sample is written; fix any issues (or run make format to auto-fix).
  • Do not add code samples to linting ignore rules when making lint-related changes—fix the code instead.
  • src/code-samples-generated/ is gitignored; regenerate with make code-snippets or make code-snippets-langsmith when iterating on LangSmith JVM files only.
  • Reference CLAUDE.md and AGENTS.md for docs style and rules.
  • Use :::python and :::js fences for language-specific content; the build produces separate Python and JavaScript doc versions.
  • For python tests, try to correct the type rather than adding # type: ignore[arg-type]

langchain-ai의 다른 스킬

langgraph-docs
langchain-ai
LangGraph 문서에 접근하여 상태 기반 에이전트 및 멀티 에이전트 워크플로우를 구축합니다. 공식 LangGraph Python 문서를 가져오며, 상태 머신, 그래프 기반 에이전트 설계, 인간 개입 패턴을 다룹니다. 쿼리 유형에 따라 관련 문서를 우선시합니다: 방법 질문에는 구현 가이드, 이론에는 개념 페이지, 종단 간 예제에는 튜토리얼, 기술 세부 사항에는 API 참조를 제공합니다. 자동으로 가장 관련성 높은 2~4개의 문서 URL을 선택하고 해당 콘텐츠를 검색하여 답변합니다...
official
langgraph-human-in-the-loop
langchain-ai
그래프 실행을 일시 중지하여 사람의 검토, 승인 또는 검증을 받은 후, 입력을 받아 다시 실행합니다. 세 가지 구성 요소가 필요합니다: 체크포인터(InMemorySaver 또는 PostgresSaver), config의 스레드 ID, JSON 직렬화 가능한 인터럽트 페이로드. interrupt(value)는 데이터를 일시 중지하고 표시하며, Command(resume=value)는 다시 시작하여 일시 중지된 노드에 해당 값을 반환합니다. interrupt() 이전의 모든 코드는 다시 시작 시 재실행되므로, 부작용은 멱등성을 가져야 합니다(insert 대신 upsert 사용). 승인 워크플로우를 지원합니다,...
official
web-research
langchain-ai
웹 리서치와 관련된 요청에 이 스킬을 사용하세요. 포괄적인 웹 리서치를 수행하기 위한 체계적인 접근 방식을 제공합니다.
official
langchain-oss-primer
langchain-ai
LangChain, Deep Agents 또는 LangGraph 에이전트 구축 프로젝트를 시작할 때는 항상 여기서 시작하세요. 다른 스킬을 선택하거나 코드를 작성하기 전에 반드시 거쳐야 하는 시작점입니다.
official
skill-creator
langchain-ai
에이전트의 기능을 확장하기 위한 효과적인 스킬을 만드는 가이드로, 특화된 지식, 워크플로우 또는 도구 통합을 포함합니다. 사용자가...
official
social-media
langchain-ai
플랫폼별 소셜 미디어 게시물을 초안 작성하며, 연구 기반 콘텐츠와 함께 생성된 보조 이미지를 제공합니다. 링크드인 게시물(1,300자, 전문적인 어조)과 트위터/X 스레드(트윗당 280자, 1/🧵 형식)를 지원합니다. 작성 전에 하위 에이전트에 연구를 위임한 후, 결과를 읽어 정확성과 관련성을 확인해야 합니다. generate_social_image 도구를 사용하여 자동으로 눈에 띄는 소셜 이미지를 생성하며, 작은 화면에 최적화된 대담하고 대비가 높은 구성을 사용합니다.
official
deep-agents-memory
langchain-ai
Deep Agents를 위한 플러그형 메모리 및 파일 백엔드로, 임시, 영구 및 하이브리드 라우팅 옵션을 제공합니다. 네 가지 백엔드 유형: StateBackend(스레드 범위, 임시), StoreBackend(세션 간 영구), FilesystemBackend(로컬 개발을 위한 실제 디스크 액세스), CompositeBackend(다른 경로를 다른 백엔드로 라우팅). FilesystemMiddleware는 ls, read_file, write_file, edit_file, glob, grep의 여섯 가지 파일 작업 도구를 제공합니다. CompositeBackend는 최장 접두사 일치를 사용하여 라우팅합니다...
official
deep-agents-orchestration
langchain-ai
서브 에이전트를 조율하고, 다단계 작업을 계획하며, 민감한 작업에 대해 인간의 승인을 요구합니다. task 도구를 통해 전문화된 서브 에이전트에 작업을 위임합니다. 맞춤형 서브 에이전트는 격리된 도구 세트와 시스템 프롬프트를 지원하며, 기본 "범용" 서브 에이전트는 메인 에이전트 구성을 상속받습니다. write_todos를 사용하여 복잡한 워크플로우를 계획 및 추적하고, 보류 중, 진행 중, 완료 상태로 작업을 구성합니다. 호출 간 지속성을 위해 thread_id가 필요합니다. 구현...
official