Inicio / Artículos / Notas prácticas: Agente de texto a SQL de nivel profesional con Claude Code

Notas prácticas: Agente de texto a SQL de nivel profesional con Claude Code

Guía paso a paso para utilizar las notas prácticas: Agente de texto a SQL de nivel profesional con Claude Code: contratos, verificaciones y espacios para código integrable para los equipos que implementan este patrón.

4157 palabras

Úselo como una versión reestructurada dirigida a operadores de las ideas presentadas en “Agente Text-to-SQL de grado industrial con Claude Code, LangGraph, Langfuse, FastAPI y Qdrant”: etapas claras, espacios para código ordenados y notas de recuperación que perduran tras un traspaso de responsabilidades.

Repositorio

El repositorio funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, 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. 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 e impiden continuar después de interrupciones.

Stack tecnológico

La pila tecnológica funciona mejor cuando se trata como una superficie medible. Capture un registro ejemplar, 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 falla un paso, el error debe apuntar a una única responsabilidad y no a un proceso complicado. 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.

LLM y Agente

LLM y Agent funcionan mejor cuando se tratan como una superficie medible. Capture una transcripción exitosa, 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 las completaciones parciales silenciosas. Asigne un presupuesto de tokens por turno y por sesión; las herramientas agenciales amplían el contexto de forma excesiva; los límites máximos evitan que las demostraciones se conviertan en facturas inesperadas.

Embeddings y búsqueda vectorial

Los embeddings y la búsqueda vectorial funcionan mejor cuando se tratan como una superficie medible. Capture un caso exitoso, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo por token o consulta junto con los resultados funcionales. Tener visibilidad del costo desde temprano evita facturas inesperadas cuando el proceso pasa de la versión de demostración a entornos compartidos. Separe la política de particionamiento del contenido de la política de recuperación; cambiar una no debe obligar a reescribir la otra cuando cambian las métricas de calidad.

API y backend

La API y el backend funcionan mejor cuando se tratan 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 sistema. Mantenga el estado del sistema plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso. La API y el backend funcionan mejor cuando se tratan 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 falla un paso, el error debe apuntar a una sola responsabilidad en lugar de a un proceso complicado.

Frontend

Para el frontend, defina las entradas, el responsable de la etapa y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la etapa a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Considere 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 datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial.

Observabilidad y rastreo

Para la observabilidad y el rastreo, 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. Registre los tiempos de ejecución y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el flujo pasa de entornos de demostración a entornos compartidos. Implemente 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.

Evaluación

Para la evaluación, 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. 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 necesidad de leer todo el sistema. Coloque la aprobación humana en aquellos procesos que generan gastos o modifican datos de producción. La conexión establecida en tiempo de compilación no equivale a una solución completa desde el punto de vista empresarial. Para la evaluación, 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.

Infraestructura y configuración

Al trabajar en la sección de Infraestructura y configuración, 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 garantiza que los cambios posteriores en el código sean transparentes. Considere esta etapa como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las comprobaciones de éxito y evite completaciones parciales silenciosas. 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 intente nuevamente un nodo posterior.

Servidor MCP

Al trabajar con MCP Server, primero anote 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. 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 se pasa de entornos de demostración a entornos compartidos. Registre el nombre de la herramienta, el hash de los argumentos, la latencia y el resultado de cada llamada. Depurar bucles del agente sin ese registro desperdicia horas.

Pruebas

Al trabajar en las pruebas, 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. 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 intente nuevamente un nodo posterior. Al trabajar en las pruebas, 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. Prefiera unidades pequeñas y probables sobre scripts extensos. Cuando un paso falla, el fallo debe referirse a una sola responsabilidad y no a un proceso complicado.

Herramientas para desarrolladores

Las herramientas para desarrolladores funcionan mejor cuando se consideran como una superficie medible. Capture una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta etapa 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. 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.

Por qué construyó un agente Text-to-SQL desde cero

La razón por la que construir un agente Text-to-SQL desde cero funciona mejor cuando se trata como una superficie medible radica en que permite capturar un registro ideal, un caso de fallo y las notas de reversión antes de ampliar el alcance. 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 se pasa de entornos de demostración a entornos compartidos. 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.

1. El conjunto de datos UDogRetail: diseñando un entorno de pruebas realista

  1. El conjunto de datos UDogRetail: diseñar un entorno de pruebas realista funciona mejor cuando se trata como una superficie medible. Capture una transcripción 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. Mantenga el estado del grafo plano y tipado; los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso.
  2. El conjunto de datos UDogRetail: diseñar un entorno de pruebas realista funciona mejor cuando se trata como una superficie medible. Capture una transcripción 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 sola responsabilidad en lugar de a un proceso complicado y entrelazado.

2. Visión general de la arquitectura: cómo encajan todas las piezas

En la sección 2. Visión general de la arquitectura: cómo encajan todas las piezas, se deben definir 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. Considere esta etapa como un contrato entre los insumos 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 procesos que implican gastos o modificaciones en datos de producción. La conexión durante la compilación no equivale a una solución completa desde el punto de vista empresarial.

La pila tecnológica que eligió y por qué:

Para la pila tecnológica que eligió y por qué: 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. Registre los tiempos de ejecución 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 entornos de demostración a entornos compartidos. Implemente la aprobación humana en aquellos casos en que se gasten fondos o se modifiquen datos de producción. La configuración en tiempo de compilación no equivale a la completitud del proceso empresarial.

3. Construcción de la pipeline RAG: esquema + recuperación de documentos

Para 3. Construcción de la pipeline RAG — esquema + recuperación de documentos, 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. Guarde 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. Cite los pasajes que realmente sirvieron de base para la respuesta. Sin citaciones, los operadores no pueden distinguir entre alucinaciones y lagunas en el indexado. Para 3. Construcción de la pipeline RAG — esquema + recuperación de documentos, 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 fallo debe indicar claramente cuál es el problema.

una única responsabilidad en lugar de un proceso complicado.

Indexación de esquemas

Al trabajar con la indexación de esquemas, primero anote el contrato: entradas requeridas, 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. 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. 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.

Indexación de la base de conocimientos

Al trabajar en la indexación de la base de conocimientos, 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. La visibilidad temprana del costo evita facturas inesperadas cuando el proceso pasa de la versión de demostración a entornos compartidos. Haga una verificación después de los pasos costosos. La reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

Recuperación

Al trabajar en la recuperación de información, 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 estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Mida la tasa de recuperación con un conjunto fijo de preguntas antes de ajustar los prompts. El cambio constante de prompts rara vez soluciona un sistema de recuperación deficiente. Al trabajar en la recuperación de información, 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 verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.

4. El agente LangGraph: nodos, estado y autocorrección

  1. El agente LangGraph — con sus nodos, estado y mecanismo de autocorrección — funciona mejor cuando se trata como una superficie medible. Capture una transcripción 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 las 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.
class AgentState(TypedDict):
  question: str
  session_id: str
  retrieved_schema: list[str]
  retrieved_docs: list[str]
  generated_sql: Optional[str]
  sql_reasoning: Optional[str]
  sql_assumptions: list[str]
  sql_confidence: float
  validation_error: Optional[str]
  execution_result: Optional[ExecutionResult]
  execution_error: Optional[str]
  retry_count: int
  correction_history: list[CorrectionRecord]
  needs_clarification: bool
  clarification_message: Optional[str]
  final_explanation: Optional[str]
  langfuse_trace_id: Optional[str]

GENERAR

GENERATE 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. 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 versión de demostración a entornos compartidos. Mantenga el estado del gráfico simple y con tipos definidos. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso.

VALIDAR → EJECUTAR

VALIDATE → EXECUTE 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. 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. VALIDATE → EXECUTE 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 falla un paso, el fallo debe apuntar a una sola responsabilidad en lugar de a un proceso complicado.

FORBIDDEN_KEYWORDS = frozenset({
"INSERT", "UPDATE", "DELETE", "DROP",
"TRUNCATE", "ALTER", "CREATE", "GRANT", "REVOKE"
})

El bucle de autocorrección

Para el bucle de autocorrección, 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 etapa 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.

def route_after_execute(state: AgentState) -> str:
  if state["execution_error"] is None:
    return "explain"
  if state["retry_count"] >= settings.max_retries:
    return "clarify"
    return "correct"

5. Hacerlo listo para producción: FastAPI, Docker, Terraform

Para el punto 5: Hacerlo listo para producción — FastAPI, Docker, Terraform. 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 en tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando la tarea pasa de un entorno de demostración a entornos compartidos. Implemente la aprobación humana en aquellos casos en los 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.

La API

Para la API, 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 desde un punto de control conocido sin tener que adivinar el estado oculto. 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 necesidad de leer todo el sistema. Coloque la aprobación humana en las operaciones que generan gastos o modifican datos de producción. La conexión en tiempo de compilación no equivale a una solución completa desde el punto de vista empresarial. Para la API, 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 desde 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.

Docker

Al trabajar con Docker, primero escribe el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de un fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Considera esta etapa como un contrato entre las entradas y los resultados validados. Nombra los artefactos, define las comprobaciones de éxito y rechaza las completaciones parciales silenciosas. Haz 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.

#!/bin/bash
# backend/start.sh
set -e
echo "==> Running Alembic migrations…"
cd /app/backend && alembic upgrade head
echo "==> Starting uvicorn…"
exec uvicorn app.main:app - host 0.0.0.0 - port 8000

Configuración

Al trabajar en la configuración, 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. 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 versión de demostración a entornos compartidos. 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.

class Settings(BaseSettings):
  anthropic_api_key: SecretStr
  voyage_api_key: SecretStr
  postgres_password: SecretStr
  langfuse_secret_key: SecretStr

6. Observabilidad con Langfuse: seguimiento de cada ejecución de agente

Al trabajar en la sección 6. Observabilidad con Langfuse — rastreando cada ejecución del agente, anote primero el contrato: entradas requeridas, 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 secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el grafo. 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 intente nuevamente un nodo posterior. Al trabajar en la sección 6. Observabilidad con Langfuse — rastreando cada ejecución del agente, anote primero el contrato: entradas requeridas, 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 sola responsabilidad en lugar de a un proceso complicado.

.

@observe(name="generate", as_type="generation")
def generate(state: AgentState) -> AgentState:
# Claude call happens here
# Langfuse auto-captures input, output, latency
lf = get_lf_client()
lf.update_current_observation(
model="claude-sonnet-4–6",
usage={"input": input_tokens, "output": output_tokens},
)

7. Pruebas: pruebas unitarias y de integración

  1. Las pruebas unitarias y de integración funcionan mejor cuando se consideran como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate 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 después de las interrupciones.

Pruebas unitarias

Las pruebas unitarias funcionan mejor cuando se tratan como una superficie medible. Capture una transcripción 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 camino pasa de la versión de demostración a entornos compartidos. Mantenga el estado del gráfico simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso.

@pytest.mark.parametrize("keyword", sorted(FORBIDDEN_KEYWORDS))
def test_forbidden_keyword_rejected(keyword: str) -> None:
  sql = f"{keyword} INTO orders VALUES ('x')"
  result = validate_sql(sql)
  assert not result.is_valid
  assert keyword in result.error_message
  def test_forbidden_keyword_in_cte_still_rejected() -> None:
  sql = "WITH x AS (DELETE FROM orders RETURNING id) SELECT * FROM x"
  result = validate_sql(sql)
  assert not result.is_valid
pytest tests/unit/ -v

Pruebas de integración

Las pruebas de integración funcionan mejor cuando se tratan 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 sistema. Mantenga el estado del sistema plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso. Las pruebas de integración funcionan mejor cuando se tratan 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 referirse a una sola responsabilidad en lugar de a un proceso complicado.

pytest tests/integration/ -v

8. Evaluación del agente con GEval

Para el punto 8: Al evaluar el agente con GEval, defina las entradas, el responsable de la etapa y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la etapa a partir de un punto de control conocido sin tener que adivinar el estado oculto. Considere 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. Imponga 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.

prompt = f"""
Score from 0.0 to 1.0 whether this explanation is faithful to the results.
Results: {json.dumps(rows[:5])}
Explanation: {explanation}
Return only JSON: {{"score": float, "reasoning": str}}
"""
python -m evaluation.harness --complexity simple
python -m evaluation.harness --limit 10

9. El servidor MCP: hacerlo un componente de Claude Code

Para el punto 9: el servidor MCP, que lo convierte en un componente de Claude Code. Antes de modificar el código, se deben definir las entradas, el responsable de la tarea y los criterios de finalización. 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 temprana del costo evita facturas inesperadas cuando la tarea pasa de un entorno de demostración a uno compartido. Se debe autenticar en la pasarela y volver a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

mcp = FastMCP(name="udogretail-text2sql")
@mcp.tool()
def query_tool(question: str, session_id: str = "") -> str:
"""Run a natural-language question through the Text-to-SQL agent."""
…
@mcp.tool()
def schema_tool(keyword: str) -> str:
"""Look up tables and columns matching a keyword."""
…
@mcp.tool()
def history_tool(limit: int = 5) -> str:
"""Fetch the last N query runs from agent history."""
…
{
"mcpServers": {
  "udogretail-text2sql": {
    "type": "stdio",
    "command": ".venv/bin/python",
    "args": ["mcp_server/server.py"],
    "env": {"API_BASE_URL": "http://localhost:8000"}
    }
  }
}

10. Resultados, lecciones y qué haría diferente

Para 10. Resultados, lecciones y qué haría diferente, defina las entradas, el responsable de la etapa y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la etapa desde 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 tener que leer todo el sistema. Coloque la aprobación humana en las conexiones 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. Para 10. Resultados, lecciones y qué haría diferente, defina las entradas, el responsable de la etapa y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la etapa desde 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 etapa falla, el error debe indicar claramente qué parte debe corregirse.

la responsabilidad en lugar de un proceso complicado.

Qué haría diferente:

Al abordar la sección de Qué haría diferente:, anote primero el contrato: entradas requeridas, señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones en el código. 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. 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.

Qué me sorprendió:

Al trabajar en “¿Qué me sorprendió?”, 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.

Lista de verificación operativa

Al trabajar en la “Lista de verificación operativa”, 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.

Documente tanto el camino óptimo como 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.

Punto de control después de pasos costosos. La continuación no debe volver a facturar la misma llamada al LLM cuando un operador vuelve a intentar 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 tribal.

Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el error debe apuntar a una única responsabilidad y no a un proceso complicado.

Punto de control después de pasos costosos. La continuación no debe volver a facturar la misma llamada al LLM cuando un operador vuelve a intentar 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. Prefiera una fiabilidad sencilla a demostraciones ingeniosas pero únicas.

Nota por lotes para 91a3d7beec49: 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.