Notas prácticas: Crea tu propio Claude Code con Langchin: Un análisis en profundidad
Guía paso a paso práctica: Crea tu propio Claude Code con Langchin: Un análisis en profundidad de los contratos, las verificaciones y los espacios para código reutilizable para equipos que implementan este patrón.
Esta guía reconstruye el proceso desde las materias primas hasta un sistema funcional para: Construye tu propio Claude Code usando LangChain: Un análisis profundo de los Deep Agents de LangChain. El enfoque está en pasos operativos claros, verificaciones explícitas y código que se puede incorporar directamente a un repositorio sin necesidad de adivinar la intención. En la etapa de visión general, se deben definir las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Mantén la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema.
La arquitectura de un agente de programación
Al trabajar en “La arquitectura de una etapa”, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Documente junto con ello el camino óptimo y el camino de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Haga un punto de control después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador vuelve a intentar un nodo posterior.
Parte 0: El bucle desde cero — sin frameworks, sin trucos mágicos
Al trabajar en la Etapa 0: el bucle, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Prefiera unidades pequeñas y probables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Haga una verificación después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.
def run_agent_loop(client, user_message, tools, tool_functions, max_turns=20):
messages = [{"role": "user", "content": user_message}]
for _ in range(max_turns):
# 1. Ask the model what to do next.
response = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024, tools=tools, messages=messages
)
messages = [*messages, {"role": "assistant", "content": response.content}]
# 2. Plain text and no tool request? The job is done.
tool_uses = [b for b in response.content if b.type == "tool_use"]
if not tool_uses:
return "".join(b.text for b in response.content if b.type == "text")
# 3. Run each requested tool and hand the results back. 4. Repeat.
results = [
{"type": "tool_result", "tool_use_id": call.id,
"content": tool_functions[call.name](**call.input)}
for call in tool_uses
]
messages = [*messages, {"role": "user", "content": results}]
raise RuntimeError(f"agent loop did not finish within {max_turns} turns")
Parte 1: El bucle — el motor que impulsa todo
Al trabajar en la etapa 1 “El bucle”, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Considere esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina comprobaciones de éxito y evite completaciones parciales silenciosas. Haga puntos de control después de pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior. Al trabajar en la etapa 1 “El bucle”, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el grafo.
pip install deepagents langchain-anthropic
from deepagents import create_deep_agent
def get_weather(city: str) -> str:
"""Get the weather for a given city."""
return f"It's always sunny in {city}!"
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
tools=[get_weather],
system_prompt="You are a helpful assistant.",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
Parte 2: Las herramientas — darle manos al agente
La etapa de las herramientas en la Parte 2 funciona mejor cuando se trata como una superficie medible. Capture una transcripción exitosa, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el de recuperación juntos. Las reintentos, los controles humanos y el manejo de correos no entregados forman parte del producto, no son mejoras posteriores. Exponga las herramientas con esquemas limitados y etiquetas explícitas de efectos secundarios. Los hosts necesitan saber qué llamadas modifican el estado antes de aprobarlas automáticamente.
¿Por qué no dejar simplemente que el modelo ejecute cualquier comando?
El enfoque “¿Por qué no simplemente dejar que la etapa funcione?” funciona mejor cuando se trata como una superficie medible. Capture un registro exitoso, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una sola responsabilidad y no a un proceso complicado. Asigne un límite de tokens por turno y por sesión; las herramientas agenciales amplían el contexto de forma excesiva; los límites estrictos evitan que las demostraciones se conviertan en facturas inesperadas.
Construyéndolo con Agentes Profundos
La etapa de “Building it with Deep” funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Considere esta etapa como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace completaciones parciales silenciosas. Mantenga el estado del grafo plano y tipado; los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso. La etapa de “Building it with Deep” funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación; los archivos de entorno, los almacenes de datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el grafo.
import subprocess
from langchain_core.tools import tool
MAX_OUTPUT_CHARS = 20_000 # roughly 5k tokens
@tool
def run_tests(path: str = ".") -> str:
"""Run the project's pytest suite and return its output.
Output is truncated to the last 20k characters (failures appear at the
end). The run is killed after 5 minutes.
"""
try:
result = subprocess.run(["pytest", path], capture_output=True,
text=True, check=False, timeout=300)
except subprocess.TimeoutExpired:
return "pytest timed out after 300s"
output = result.stdout + result.stderr
if len(output) > MAX_OUTPUT_CHARS:
return ("[... output truncated to the last 20,000 characters ...]\n"
+ output[-MAX_OUTPUT_CHARS:])
return output
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
tools=[run_tests], # merged in alongside the built-ins
system_prompt="You are a coding assistant. Always run tests after editing.",
)
Parte 3: Planificación — pensar antes de actuar
En la fase de planificación de la Parte 3, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Incluya la aprobación humana en aquellos casos que impliquen gastos o cambios en los datos de producción. La configuración en tiempo de compilación no equivale a la completitud del proceso empresarial.
Parte 4: Gestión de contexto — superar el límite de memoria
En la etapa de gestión de contexto de la Parte 4, se deben definir las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Es preferible utilizar unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el error debe indicar una única responsabilidad y no un proceso complicado. Se debe incluir la aprobación humana en aquellos casos en que se gastan fondos o se modifican datos de producción. La configuración en tiempo de compilación no equivale a la completitud del proceso empresarial.
Desarrollándolo con agentes avanzados
En la fase de Construcción con Deep, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Trate esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace las completaciones parciales silenciosas. Incluya la aprobación humana en aquellos casos que impliquen gastos o cambios en los datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial. En la fase de Construcción con Deep, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin necesidad de leer todo el sistema.
Parte 5: Subagentes — divide y vencerás
Al trabajar en la fase de división por subagentes de la Parte 5, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Documente tanto el camino óptimo como el de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no de mejoras posteriores. Haga un punto de control después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador vuelve a intentar un nodo posterior.
code_searcher = {
"name": "code-searcher",
"description": "Searches the codebase to find where specific logic lives. "
"Use this for any open-ended 'where is X?' question.",
# ⚠️ NOTE: the key is `system_prompt`, NOT `prompt` (see correction below).
"system_prompt": "You are an expert at navigating codebases. Use the grep "
"and glob tools to locate relevant files, then report a "
"concise summary of what you found and where. Do not make "
"any edits.",
}
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
tools=[run_tests],
system_prompt="You are a coding assistant.",
subagents=[code_searcher],
)
Parte 6: Seguridad y participación humana — los frenos
Al trabajar en la sección de Seguridad y etapas del Parte 6, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación ayuda a mantener honestas las futuras modificaciones del código. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Haga una verificación después de los pasos costosos. El sistema de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intente nuevamente un nodo posterior.
Construyéndolo con Deep Agents
Al trabajar en la fase de “Building it with Deep”, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Considere esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina comprobaciones de éxito y evite completaciones parciales silenciosas. Haga puntos de control después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intente nuevamente un nodo posterior. Al trabajar en la fase de “Building it with Deep”, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el grafo.
from deepagents import create_deep_agent
# Import path for backends can vary by version - check the current
# "Backends" page in the Deep Agents docs.
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
system_prompt="You are a coding assistant working inside this project.",
backend=LocalShellBackend(), # enables the `execute` shell tool
)
from langgraph.types import Command
result = agent.invoke({"messages": [...]}, config)
result["__interrupt__"] # the pending action + allowed decisions — show your user
# You decide; the loop picks up exactly where it paused:
agent.invoke(Command(resume={"decisions": [{"type": "approve"}]}), config)
# ... or {"type": "reject"} — the tool is never run, and the model is told so.
Parte 7: Memoria y persistencia — recordar entre sesiones
La sección 7 sobre memoria y persistencia funciona mejor cuando se trata como una superficie medible. Capture una transcripción exitosa, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el de recuperación juntos. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Mantenga el estado del grafo simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.
Construyéndolo con Deep Agents
El enfoque Deep Stage funciona mejor cuando se trata como una superficie medible. Capture un caso exitoso, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Mantenga el estado del grafo simple y tipado; los bloques anidados ocultan qué nodo escribió qué campo y causan problemas al reanudar después de interrupciones.
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
tools=[run_tests],
system_prompt="You are a coding assistant.",
checkpointer=InMemorySaver(), # remembers state within a session
)
# A "thread_id" ties messages together into one ongoing conversation.
config = {"configurable": {"thread_id": "project-alpha"}}
agent.invoke(
{"messages": [{"role": "user", "content": "Start refactoring the auth module."}]},
config=config,
)
# Later, same thread_id - the agent remembers the earlier turn:
agent.invoke(
{"messages": [{"role": "user", "content": "Now update the tests too."}]},
config=config,
)
Uniendo todo
La etapa de “Unirlo todo” funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Considere esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace completaciones parciales silenciosas. Mantenga el estado del grafo plano y tipado; los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso. La etapa de “Unirlo todo” funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación; los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el grafo.
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
from langchain_core.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
# --- A custom tool (Part 2) — token-budgeted, see Part 2 for the full body ---
@tool
def run_tests(path: str = ".") -> str:
"""Run the project's pytest suite and return its (truncated) output."""
import subprocess
try:
result = subprocess.run(["pytest", path], capture_output=True,
text=True, check=False, timeout=300)
except subprocess.TimeoutExpired:
return "pytest timed out after 300s"
output = result.stdout + result.stderr
return output if len(output) <= 20_000 else "[... truncated ...]\n" + output[-20_000:]
# --- A specialized subagent (Part 5) — note the `system_prompt` key ---
code_searcher = {
"name": "code-searcher",
"description": "Finds where specific logic lives in the codebase. "
"Use for open-ended 'where is X?' questions.",
"system_prompt": "You navigate codebases using grep and glob, then report a "
"concise summary of what you found. You never make edits.",
}
# --- A system prompt that teaches good behavior (Parts 2 & 3) ---
SYSTEM_PROMPT = """You are a careful coding assistant.
Workflow:
1. Plan the task as a to-do list before doing anything.
2. Use your built-in read, grep, and glob tools to explore - never the raw shell
equivalents like cat or grep.
3. Make focused edits.
4. ALWAYS run the tests after editing, and fix anything that breaks.
5. Delegate broad codebase searches to the code-searcher subagent.
"""
# --- Assemble the agent (Parts 1, 4, 6, 7 handled by the harness) ---
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6", # Part 1: the loop, model-agnostic
tools=[run_tests], # Part 2: custom hands
system_prompt=SYSTEM_PROMPT, # Parts 2 & 3: behavior + planning
subagents=[code_searcher], # Part 5: delegation
backend=LocalShellBackend(root_dir=".", virtual_mode=False), # Part 6: shell access
interrupt_on={"execute": True, # Part 6: the brakes —
"write_file": True, "edit_file": True}, # approval before anything destructive
checkpointer=InMemorySaver(), # Part 7: memory across turns
)
# Part 4 (context management) and built-in planning come on automatically.
config = {"configurable": {"thread_id": "my-project"}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "The login tests are failing. Fix them."}]},
config=config,
)
print(result["messages"][-1].content)
La parte honesta: qué es fácil y qué es difícil
En cuanto a la parte importante, se debe definir la etapa, los insumos, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Se debe documentar tanto la ruta óptima como la ruta de recuperación. Las intentonas repetidas, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son algo que se añade posteriormente. Se debe incluir la aprobación humana en aquellos casos en que se gastan fondos o se modifican datos de producción. La configuración en tiempo de compilación no equivale a la completitud del proceso empresarial.
Conclusión
En la fase de cierre, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el error debe indicar una única responsabilidad y no un proceso complicado. Incluya la aprobación humana en aquellas tareas que implican gastos o modificaciones en datos de producción. La configuración en tiempo de compilación no equivale a una solución completa para el negocio.
Lista de verificación operativa
La fase de la lista de verificación operativa funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance.
Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas al pasar del entorno de demostración a los entornos compartidos.
Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.
Añada una prueba de funcionamiento básica que ejerza la ruta crítica en CI con fixtures, y no con APIs pagadas en tiempo real, siempre que lo permitan los presupuestos.
Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un único lugar que los operadores puedan auditar sin tener que leer todo el grafo.
Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.
Antes de promocionar la pila, congele las versiones, capture una transcripción de referencia para la ruta crítica y confirme los pasos de reversión. Los entornos compartidos necesitan límites de velocidad, verificaciones de tenencia y un propietario claro para la rotación de secretos. Prefiera una fiabilidad sencilla a demostraciones ingeniosas pero puntuales.
Nota de lote para 9ef98d98a69a: mantener las claves del proveedor fuera del repositorio, establecer un límite para los tokens por sesión y almacenar las transcripciones junto a los archivos de evaluación para que los cambios posteriores en el modelo sigan siendo comparables.
Para la nota de reforzamiento de seguridad en la etapa 0, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el error debe indicar una única responsabilidad y no un proceso complicado.
Detalle de reforzamiento de seguridad 0/891: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.
Al trabajar en la fase 1 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la fase de demostración a entornos compartidos.
Detalle de fortalecimiento 1/891: mida el tiempo empleado, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener la modificación basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.
La fase 2 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el camino de recuperación. Los intentos repetidos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.
Detalle de endurecimiento 2/891: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.