Notas prácticas: Formación de agentes cualificados
Guía paso a paso práctica: Cómo crear agentes capacitados: contratos, verificaciones y espacios para código adicional para los equipos que implementan este patrón.
Úselo como una versión reestructurada dirigida a los operadores de las ideas presentadas en “Construyendo agentes cualificados”: etapas claras, espacios ordenados para el código y notas de recuperación que perduran tras la transferencia de tareas. La etapa de Resumen funciona mejor cuando se trata como una superficie medible. Registre una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Anote los tiempos y el costo en tokens o consultas junto a los resultados funcionales. La visibilidad temprana del costo evita facturas inesperadas cuando el proceso pasa de la demostración a entornos compartidos.
¿Qué es realmente una habilidad?
En la etapa de “¿Qué es una habilidad?”, 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. 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. Coloque la aprobación humana en aquellos procesos que implican gastos o modifican datos de producción. La conexión establecida en tiempo de compilación no equivale a la completitud del proceso empresarial.
La analogía
En la fase de analogía, 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. Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de correos 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 producto desde el punto de vista empresarial.
En código
En la fase de desarrollo del código, se deben definir las entradas, el responsable de la tarea y los criterios de finalización antes de modificarlo. Los operadores deben poder volver a ejecutar la tarea 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 una tarea falla, el error debe indicar una única responsabilidad y no un proceso complicado. Se debe incluir la aprobación humana en aquellas acciones 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. En la fase de desarrollo del código, se deben definir las entradas, el responsable de la tarea y los criterios de finalización antes de modificarlo. Los operadores deben poder volver a ejecutar la tarea a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Se deben registrar los tiempos de ejecución y el costo en tokens o consultas junto con los resultados funcionales. Tener visibilidad sobre los costos desde el principio evita facturas inesperadas cuando la tarea pasa de un entorno de demostración a uno compartido.
skills/
└── weather-skill/
├── SKILL.md # frontmatter + instructions
---
name: weather-skill
description: Get current weather for a location. Use when the user
asks about weather, temperature, or conditions anywhere.
---
# Get weather skill
.... {other instructions here}
Construyamos un arnés de iluminación
Al trabajar en el proyecto “Construyamos un escenario”, 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. Guarde 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 sistema. Registre el nombre de la herramienta, el hash de los argumentos, la latencia y el resultado de cada llamada. Depurar agentes sin ese historial desperdicia horas.
from dotenv import find_dotenv, load_dotenv
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI
_ = load_dotenv(find_dotenv())
llm = ChatOpenAI(
model="gpt-5.6-luna",
use_responses_api=True,
reasoning={"effort": "low"}, #The reasoning is medium by default so set this to l
)
@tool
def get_weather(location: str) -> str:
"""
Get the weather for a given location
"""
return f"The weather in {location} is sunny"
@tool
def get_exchange_rate(currency_from: str, currency_to: str) -> str:
"""
Get the exchange rate between two currencies
"""
return f"The exchange rate for {currency_from} to {currency_to} is 1.00"
Utilizar habilidades para guiar el uso de herramientas
Al trabajar en la sección “Usar habilidades para guiar la fase”, 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 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. Registre el nombre de la herramienta, el hash de los argumentos, la latencia y el resultado de cada llamada. Depurar bucles del agente sin esa huella desperdicia horas.
skills/
└── weather-skill/
├── SKILL.md
└── forex-skill/
├── SKILL.md
---
name: forex-skill
description: Get live exchange rates between two currencies. Use this whenever the user asks about currency conversion, exchange rates, how much something costs in another currency, or comparisons like "is the dollar strong right now" — even if they don't use the words "forex" or "exchange rate" explicitly (e.g. "how much is 500 SGD in yen", "should I exchange money now or wait"). Always use this instead of guessing from memory, since exchange rates move constantly and Claude's training data has no visibility into current rates.
---
# Forex Skill
Fetches the live exchange rate between two currencies and reports it back in a clear, practical format.
## Instructions
1. **Identify both currencies.** Convert casual references to standard 3-letter ISO codes before calling the tool (e.g. "dollars" → ask which dollar: USD, SGD, AUD, etc.; "yen" → JPY; "pounds" → GBP).
2. **Handle ambiguous currency names.** If the user says something like "dollars" or "pounds" without specifying which country, ask them to clarify before calling the tool — don't assume USD/GBP by default.
3. **Call the `get_exchange_rate` tool**, passing both currency codes:
```python
get_exchange_rate(currency_from="<code>", currency_to="<code>")
```
4. **If the tool call fails or returns an error**, tell the user plainly that the rate lookup failed — don't fall back to guessing a rate from memory.
5. **Call once per currency pair.** For multi-currency questions (e.g. "compare SGD to USD, EUR, and JPY"), call the tool separately for each pair.
6. **Do the math for the user.** If they gave an amount ("convert 500 SGD to JPY"), multiply it out yourself using the returned rate — don't just hand back the raw rate and leave them to calculate it.
## Output format
...
## Examples
...
Experimento 1: Habilidades en archivos
Al trabajar en las Habilidades del Experimento 1 por fases, anote primero el contrato: entradas requeridas, 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. Prefiera unidades pequeñas y verificables a 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. Al trabajar en las Habilidades del Experimento 1 por fases, anote primero el contrato: entradas requeridas, 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. Registre los tiempos y el costo en tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la versión de demostración a entornos compartidos.
from deepagents.backends import FilesystemBackend
from deepagents.middleware import FilesystemMiddleware, SkillsMiddleware
backend = FilesystemBackend(root_dir="../", virtual_mode=True)
agent = create_agent(
model=llm,
tools=[get_weather, get_exchange_rate],
middleware=[
SkillsMiddleware(backend=backend, sources=["./skills/"]),
FilesystemMiddleware(
backend=backend,
tools=["read_file"], # read_file and nothing else
system_prompt=None,
),
],
)
Pruébelo
La etapa “Give it a spin” 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. 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. Mantenga el estado del grafo simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso.
>>> agent.invoke({"messages": [HumanMessage("What is the weather in Singapore?")]})
Singapore is currently **sunny**. It's a good time for outdoor plans.
Experimento 2: Habilidades remotas
La etapa de habilidades remotas del Experimento 2 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. Documente tanto el camino óptimo como el camino 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 de los gráficos simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.
from urllib.request import urlopen
from deepagents.backends import StateBackend
from deepagents.backends.utils import create_file_data
backend = StateBackend()
skill_url = "https://raw.githubusercontent.com/.../langgraph-docs/SKILL.md"
with urlopen(skill_url) as response:
skill_content = response.read().decode('utf-8')
skills_files = {
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
}
agent = create_agent(
model= llm
middleware=[
SkillsMiddleware(
backend=backend,
sources=["./skills/"]
),
FilesystemMiddleware(backend=backend)
]
)
result = agent.invoke(
{
"messages": [{"role": "user", "content": "What is langgraph?"}],
# seeded into the in-state filesystem. needed for the first run
"files": skills_files,
},
)
Experimento 3: Cero herramientas
La etapa de herramientas de Experiment 3 Zero 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. Prefiera unidades pequeñas y probables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado. Exponga 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. La etapa de herramientas de Experiment 3 Zero 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. La visibilidad temprana del costo evita facturas inesperadas cuando el proceso pasa de la demostración a entornos compartidos.
---
name: weather-skill
description: Get current weather for a location. Use when the user asks
about weather, temperature, or conditions anywhere.
---
# Get weather skill
To get the weather of a location, run:
```bash
python skills/weather-skill/scripts/get_weather.py "<location>"
```
Returns JSON with weather condition. Parse and present naturally.
Run this script on each location the user asked for, one at a time.
#skills/weather-skill/get_weather.py
def main():
location = sys.argv[1] if len(sys.argv) > 1 else None
if not location:
print(json.dumps({"error": "location argument required"}))
sys.exit(1)
print(json.dumps({"location": location, "weather": "sunny"}))
if __name__ == “__main__”:
main()
from deepagents.backend import LocalShellBackend
backend = LocalShellBackend(
root_dir=str(Path.cwd()),
virtual_mode=False,
inherit_env=True,
)
middleware = [
FilesystemMiddleware(
backend=backend,
tools=["read_file", "ls", "glob", "execute"],
system_prompt=None,
),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
]
agent = create_agent(model=llm, middleware=middleware) # no tools=
Espera. ¿De verdad se ejecutó?
Para la fase “Espera, ¿se ejecutó?”, define las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea desde 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 datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin necesidad de leer todo el sistema. Aplica la aprobación humana en los procesos que generan gastos o modifican datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial.
Today's weather:
**Sydney:** Sunny
- **Melbourne:** Sunny
La solución está en el registro de eventos, pero no en stdout.
Para la fase de corrección, 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. 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.
from pathlib import Path
import logging
LOG = Path(__file__).resolve().parent.parent / "skill.log"
logging.basicConfig(
filename=LOG, level=logging.INFO,
format="%(asctime)s [pid=%(process)d] %(message)s",
)
logging.info("invoked argv=%r cwd=%s", sys.argv, os.getcwd())
22:29:55,316 [pid=45724] invoked argv=[...get_weather.py, 'Sydney'] cwd=.../notebooks
22:29:55,316 [pid=45724] resolved location=Sydney
22:29:56,795 [pid=45725] invoked argv=[...get_weather.py, 'Melbourne'] cwd=.../notebooks
22:29:56,795 [pid=45725] resolved location=Melbourne
El error que explicó todo el diseño
En la etapa de análisis del error, defina las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea 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 una tarea falla, el error debe indicar una única responsabilidad y no un proceso complicado. Incluya la aprobación humana en aquellas acciones 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 los negocios. En la etapa de análisis del error, defina las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea a partir de un punto de control conocido sin tener que adivinar el estado oculto. Registre los tiempos de ejecución y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad temprana del costo evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos.
.¿Qué es virtual_mode?
Al trabajar en la fase de “¿Qué es virtualmode?”, 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. Guarde 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 encontrarse en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. 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 intenta nuevamente un nodo posterior.
El argumento accidental para todo el diseño
Al trabajar en “The accidental argument for stage”, 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.
Entonces, ¿cuál debería construir?
Al decidir qué parte debe ponerse en fase, primero escribe el contrato: los datos necesarios, 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. Prefiere unidades pequeñas y probables a scripts extensos. Cuando un paso falla, el fallo debe referirse a una única responsabilidad y no a un proceso complicado. Haz 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. Al decidir qué parte debe ponerse en fase, primero escribe el contrato: los datos necesarios, 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. Registra los tiempos y el costo en tokens o consultas junto con los resultados funcionales. Ver la información de costos desde el principio evita facturas inesperadas cuando el proceso pasa de una versión de demostración a entornos compartidos.
Pero, ¿realmente se necesitan habilidades?
Pero, en realidad, el trabajo 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. 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. Mantenga el estado del grafo simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso.
Pensamientos finales
La etapa de Reflexiones Finales 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. 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 ajustes realizados posteriormente. Mantenga el estado de los gráficos simple y tipado; los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso.
Lista de verificación operativa
Al trabajar en la etapa de la Lista de verificación operativa, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista garantiza que los cambios posteriores en el código sean transparentes.
Trate esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina comprobaciones de éxito y rechace las completaciones parciales silenciosas.
Punto de control después de pasos costosos. La continuación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.
Fije las versiones de las dependencias y registre el resumen de la imagen que ejecutó la demostración. La reproducibilidad es mejor que el conocimiento basado en prácticas internas.
Registre los tiempos y el costo en tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la demostración a entornos compartidos.
Punto de control después de pasos costosos. La continuación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.
Antes de promocionar la pila, congele las versiones, capture una transcripción de referencia para el camino crítico y confirme los pasos de reversión. Los entornos compartidos necesitan límites de velocidad, verificaciones de tenencia y un responsable claro para la rotación de credenciales secretas. Prefiera una fiabilidad sencilla a demostraciones ingeniosas pero puntuales.
Nota por lotes para 835597b38be4: mantenga las claves del proveedor fuera del repositorio, establezca un límite para los tokens por sesión y almacene las transcripciones junto a los archivos de evaluación para que los cambios posteriores en el modelo sigan siendo comparables.
Al trabajar en la etapa 0 de las notas de fortalecimiento, anote primero el contrato: entradas requeridas, 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. Prefiera unidades pequeñas y verificables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.
Detalle de fortalecimiento 0/781: 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.
La etapa 1 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ejemplar, 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 cuando el proceso pasa de la fase de demostración a entornos compartidos.
Detalle de fortalecimiento 1/781: mida el tiempo empleado, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en relatos anecdóticos.