Notas prácticas: Cómo convertí mi galería de fotos en un agente de IA autónomo
Guía paso a paso para utilizar las notas prácticas: Cómo convertí mi galería de fotos en un agente de IA autónomo: contratos, verificaciones y espacios para código listos para uso por los equipos que implementan este patrón.
Esta guía reconstruye el proceso desde las materias primas hasta un sistema funcional para: Cómo convertí mi galería de fotos en un agente de IA autónomo — La guía completa. El enfoque está en pasos operativos, verificaciones explícitas y código que se puede insertar directamente en un repositorio sin tener que adivinar su propósito. 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. 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.
Introducción
Al trabajar en la etapa de introducción, 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. Trate 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 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.
Por qué la búsqueda tradicional de fotos está rota
Al trabajar en la etapa de “¿Por qué la búsqueda tradicional de fotos?”, 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. Ver la información sobre costos desde el principio evita facturas inesperadas cuando se pasa de entornos 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.
El enfoque del álbum falla en la práctica
Al trabajar en la etapa de “The album approach collapses”, 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. 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 etapa de “The album approach collapses”, 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. 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.
La búsqueda por palabras clave solo te lleva hasta cierto punto
La búsqueda por palabras clave funciona mejor cuando se trata como una superficie medible. Captura un registro exitoso, un caso de fallo y la nota de reversión antes de ampliar el alcance. Considera esta etapa como un contrato entre las entradas y las salidas validadas. Nombra los artefactos, define las verificaciones de éxito y rechaza las completaciones parciales silenciosas. Mantén el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y rompen la continuidad después de las interrupciones.
Búsqueda en la galería cloud: buena, pero a un costo
La búsqueda en la galería Cloud 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. 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. 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.
La verdadera brecha: falta de comprensión semántica
La verdadera ventaja de este enfoque radica en que 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 confidenciales 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 en formato plano y tipado; los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso. La verdadera ventaja de este enfoque radica en que 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 verificables en lugar de scripts extensos; cuando un paso falla, el fallo debe referirse a una sola responsabilidad y no a un proceso complicado.
El concepto: Búsqueda semántica, explicada de forma sencilla
En la etapa de Búsqueda Semántica del Concepto, 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. Considere 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.
¿Qué papel juega el lenguaje?
Para la etapa “¿De dónde proviene el lenguaje?”, 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. Registre los tiempos de ejecución y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos. Implemente la aprobación humana en aquellas tareas que generan gastos o modifican datos de producción. La configuración en tiempo de compilación no equivale a una solución completa desde el punto de vista empresarial.
Elegir las herramientas adecuadas (y por qué llevó semanas)
En la etapa de Elección de las Herramientas Adecuadas, defina los datos de entrada, 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. Autentique en la pasarela y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias. En la etapa de Elección de las Herramientas Adecuadas, defina los datos de entrada, 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.
CLIP ViT-B/32 vía FastEmbed: los ojos del sistema
Al trabajar con la etapa CLIP ViT-B 32 vía FastEmbed, primero escribe 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. Considera esta etapa como un contrato entre las entradas y las salidas validadas. Nombra los artefactos, define las verificaciones de éxito y rechaza las completaciones parciales silenciosas. Mide el recuerdo en un conjunto fijo de preguntas antes de ajustar los prompts. El cambio constante de prompts rara vez soluciona un sistema de recuperación deficiente.
from fastembed import ImageEmbeddingModel, TextEmbeddingModel
# Loaded once, reused forever
image_model = ImageEmbeddingModel.from_pretrained("Qdrant/clip-ViT-B-32-vision")
text_model = TextEmbeddingModel.from_pretrained("Qdrant/clip-ViT-B-32-text")
# After embedding:
image_vector = embed_image("sunset_photo.jpg") # shape: (512,)
query_vector = embed_text("beautiful sunset") # shape: (512,)
# Cosine similarity — just a dot product on normalised vectors
similarity = np.dot(image_vector, query_vector)
# If image is a sunset → similarity ≈ 0.85 (strong match)
# If image is food → similarity ≈ 0.15 (weak match)
Qdrant Edge: la memoria
Al trabajar con la etapa de memoria de Qdrant Edge, 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. 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. Haga un punto de control después de los pasos costosos. La reanudación no debe volver a facturar la misma llamada al LLM cuando un operador vuelve a intentar un nodo posterior.
from qdrant_edge import(
Distance,
EdgeConfig,
EdgeShard,
EdgeVectorParams,
)
config = EdgeConfig(
vectors={
VECTOR_NAME: EdgeVectorParams(
size=EMBED_DIM,
distance=Distance.Cosine
)
}
)
_shard = EdgeShard.create(path=str(SHARD_DIR), config=config)
Uniendo todo
Al trabajar en la fase de “Ponerlo todo junto”, 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 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 datos secretos y las banderas de funcionalidad deben estar 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 la fase de “Ponerlo todo junto”, 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 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 referirse a una sola responsabilidad y no a un proceso complicado.
OpenClaw: el cerebro
La etapa cerebral de OpenClaw 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. 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 después de las interrupciones.
Configuración del entorno
La etapa de configuración del entorno 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 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.
Paso 1: Clonar el repositorio y crear un entorno virtual
La etapa de Clonar en el Paso 1 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 plano y tipado; los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso. La etapa de Clonar en el Paso 1 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 única responsabilidad en lugar de a un proceso complicado.
# Clone the repo
git clone https://github.com/vatsala-singh/AI-Powered-Photo-Search-and-Tagging-Agent.git
cd AI-Powered-Photo-Search-and-Tagging-Agent
# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate # Mac/Linux
# .venv\Scripts\activate # Windows
Paso 2: Instalar las dependencias
En el Paso 2, para instalar la etapa, 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. 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.
pip install -r requirements.txt
Paso 3: Comprender la estructura del proyecto
En la Etapa 3, “Entender la fase”, 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. Registre los tiempos de ejecución y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos 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.
AI-Powered-Photo-Search-and-Tagging-Agent/
│
├── main.py # FastAPI app + OpenClaw agent entry point
├── config.py # All configurable parameters in one place
├── requirements.txt
│
├── pipeline/
│ ├── embedder.py # CLIP embedding logic (image + text)
│ └── indexer.py # Batch photo processing and indexing
│
├── store/
│ └── qdrant_client.py # Qdrant Edge setup and collection management
│
├── tools/
│ ├── search.py # Semantic search tool
│ ├── tag.py # Zero-shot auto-tagging tool
│ ├── duplicates.py # Near-duplicate detection tool
│ └── albums.py # Smart album grouping tool
│
├── test/
│ ├── embedder_test.py
│ ├── indexer_test.py
│ ├── search_test.py
│ └── qdrant_edge_client_test.py
│
└── qdrant-edge-data/ # Auto-created at runtime
├── storage/ # Qdrant's internal shard data
├── models/ # Cached CLIP model weights
└── photos/ # Collection data
Etapa 4: Echar un vistazo a config.py
En la fase de “Vista rápida” del Paso 4, 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 generan gastos o modifican datos de producción. La conexión establecida en tiempo de compilación no equivale a la completitud del proceso empresarial. En la fase de “Vista rápida” del Paso 4, 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.
# config.py
CLIP_IMAGE_MODEL = "Qdrant/clip-ViT-B-32-vision"
CLIP_TEXT_MODEL = "Qdrant/clip-ViT-B-32-text"
EMBEDDING_DIM = 512 # CLIP ViT-B/32 output dimension
COLLECTION_NAME = "photos"
QDRANT_PATH = "./qdrant-edge-data"
BATCH_SIZE = 32 # Images per indexing batch
TOP_K = 10 # Default search results returned
TAG_THRESHOLD = 0.20 # Min similarity score for a tag to apply
DUPLICATE_THRESHOLD = 0.97 # Min similarity to flag as duplicate
Paso 5: Iniciar el servidor
Al trabajar en la etapa del Paso 5 “Iniciar”, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de un fallo parcial. Esa lista de verificación ayuda a mantener honestas las futuras modificaciones en el código. Considere esta etapa como un contrato entre los datos de entrada y las salidas validadas. Asigne nombres a los artefactos, defina 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.
uvicorn main:app --reload --port 8000
Paso 6: Verificar la configuración
Al trabajar en el Paso 6, Verificar la etapa, 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.
# Quick sanity check - should return {"status": "ok"}
curl http://localhost:8000/health
curl http://localhost:8000/api/status
Construyendo la tubería de incrustación de imágenes
Al trabajar en la etapa de Creación del Embedding de Imágenes, 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 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 etapa de Creación del Embedding de Imágenes, 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 verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.
El generador de embeddings
La etapa de incrustación 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. 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. Separe la política de fragmentación de la política de recuperación; cambiar una no debe obligar a reescribir la otra cuando cambian las métricas de calidad.
# pipeline/embedder.py
from fastembed import ImageEmbeddingModel, TextEmbeddingModel
from PIL import Image
import numpy as np
from config import CLIP_IMAGE_MODEL, CLIP_TEXT_MODEL
# Load once, reuse for the lifetime of the process
# Models are large (~150MB each) — we never want to reload them per request
_image_model = ImageEmbeddingModel.from_pretrained(CLIP_IMAGE_MODEL)
_text_model = TextEmbeddingModel.from_pretrained(CLIP_TEXT_MODEL)
def embed_image(image_path: str) -> np.ndarray:
"""Convert an image file to a 512-d CLIP embedding."""
image = Image.open(image_path).convert("RGB")
embeddings = list(_image_model.embed([image]))
return np.array(embeddings[0]) # shape: (512,)
def embed_text(query: str) -> np.ndarray:
"""Convert a text string to a 512-d CLIP embedding."""
embeddings = list(_text_model.embed([query]))
return np.array(embeddings[0]) # shape: (512,)
El indexador
La etapa de indexación 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 cuando el proceso pasa de la versión de demostración a entornos compartidos. Mantenga el estado del grafo simple y tipado; los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso.
# pipeline/indexer.py
import os
import uuid
from pathlib import Path
from datetime import datetime
from PIL import Image
from pipeline.embedder import embed_image
from store.qdrant_client import get_shard
from tools.tag import generate_tags
from config import BATCH_SIZE
SUPPORTED_FORMATS = {".jpg", ".jpeg", ".png", ".webp", ".bmp", ".tiff"}
def index_folder(folder_path: str) -> dict:
"""
Recursively index all images in a folder into Qdrant Edge.
Returns a summary: total found, indexed, skipped.
"""
folder = Path(folder_path)
shard = get_shard()
image_paths = [
p for p in folder.rglob("*")
if p.suffix.lower() in SUPPORTED_FORMATS
]
total = len(image_paths)
indexed = 0
skipped = 0
batch = []
for i, path in enumerate(image_paths):
try:
vector = embed_image(str(path))
tags = generate_tags(str(path))
img = Image.open(path)
point = {
"id": str(uuid.uuid4()),
"vector": vector.tolist(),
"payload": {
"filename": path.name,
"filepath": str(path.absolute()),
"tags": tags,
"timestamp": int(path.stat().st_mtime),
"width": img.width,
"height": img.height,
}
}
batch.append(point)
indexed += 1
except Exception as e:
print(f"Skipping {path.name}: {e}")
skipped += 1
# Flush every BATCH_SIZE images
if len(batch) >= BATCH_SIZE:
shard.upsert(points=batch)
batch = []
print(f" Progress: {i+1}/{total} images indexed...")
# Flush remaining
if batch:
shard.upsert(points=batch)
return {"total": total, "indexed": indexed, "skipped": skipped}
Indexación de imágenes en Qdrant Edge
La etapa de indexación de imágenes en Qdrant 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 plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso. La etapa de indexación de imágenes en Qdrant 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 única responsabilidad en lugar de a un proceso complicado.
Cómo funciona Qdrant Edge aquí
En la etapa de cómo funciona Qdrant Edge, 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. 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 en que se gasten fondos o se modifiquen datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial.
Configuración del shard
Para configurar la etapa de shard, 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. 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 conexión en tiempo de compilación no equivale a la completitud del proceso empresarial.
def get_shard() -> EdgeShard:
"""
Return the singleton EdgeShard, creating it on first call.
- If SHARD_DIR does not exist → create a brand-new shard.
- If SHARD_DIR already contains data → reopen it (no config needed).
EdgeShard runs entirely in-process. No binary, no port, no network.
"""
global _shard
if _shard is not None:
return _shard
SHARD_DIR.mkdir(parents=True, exist_ok=True)
# Detect whether this is a fresh shard or an existing one.
# EdgeShard.create() fails if data already exists on disk.
shard_has_data = any(SHARD_DIR.iterdir())
if shard_has_data:
print(f"[qdrant_client] Reopening existing shard at '{SHARD_DIR}'")
_shard = EdgeShard.load(path=SHARD_DIR)
else:
print(f"[qdrant_client] Creating new shard at '{SHARD_DIR}'")
config = EdgeConfig(
vectors={
VECTOR_NAME: EdgeVectorParams(
size=EMBED_DIM,
distance=Distance.Cosine
)
}
)
_shard = EdgeShard.create(path=str(SHARD_DIR), config=config)
print(f"[store] Shard ready — vector: '{VECTOR_NAME}', dim: {EMBED_DIM}")
return _shard
La división entre crear y cargar
En la etapa de creación frente a carga, 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 generan gastos o modifican datos de producción. La conexión realizada en tiempo de compilación no equivale a una solución completa desde el punto de vista empresarial. En la etapa de creación frente a carga, 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.
El patrón singleton
Al trabajar en la etapa del patrón singleton, anote primero 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. 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.
@app.on_event("shutdown")
def on_shutdown():
close_shard()
El esquema de la carga útil
Al trabajar en la etapa del esquema de carga útil, 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. 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.
from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class PhotoPayload:
filename:str
path:str
tags: list[str] = field(default_factory=list)
timestamp: Optional[str] = None
width: Optional[int] = None
height: Optional[int] = None
def to_dict(self) -> dict:
return {
"filename": self.filename,
"path": self.path,
"tags": self.tags,
"timestamp": self.timestamp,
"width": self.width,
"height": self.height
}
Escribir puntos en el shard
Al trabajar en los puntos de escritura dirigidos a una etapa específica, 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 datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema.
from qdrant_edge import PointStruct
from store.qdrant_client import get_shard
from schema import PhotoPayload
shard = get_shard()
payload = PhotoPayload(
filename = "beach_sunset.jpg",
path = "/Users/me/Pictures/2024/Goa/beach_sunset.jpg",
tags = ["sunset", "beach", "outdoor"],
timestamp = "2024-05-01T18:42:00",
width = 4032,
height = 3024
)
point = PointStruct(
id = "3f7a2b1c-8e4d-4f9a-b2c1-7d8e9f0a1b2c",
vector = {"image": vector.tolist()}, # named vector matching VECTOR_NAME
payload = payload.to_dict()
)
shard.upsert(points=[point])
Al trabajar en los puntos de escritura dirigidos a una etapa específica, 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. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando una etapa falla, el fallo debe referirse a una sola responsabilidad y no a un proceso complejo e entrelazado.
Etiquetado automático de fotos
La etapa de etiquetado automático de fotos 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. Trate 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.
La idea: clasificación sin entrenamiento previo
La etapa de clasificación zero-shot funciona mejor cuando se trata como una superficie medible. Capture un transcripción ideal, 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. La visibilidad temprana del costo evita facturas inesperadas cuando el proceso pasa de la versión de demostración a 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 del proceso.
TAG_VOCABULARY = [
"sunset", "sunrise", "beach", "ocean", "mountain", "forest", "city",
"night", "snow", "rain", "fog", "sunny", "cloudy",
"dog", "cat", "bird", "people", "crowd", "portrait", "selfie",
"food", "coffee", "restaurant", "travel", "architecture",
"car", "road", "nature", "flowers", "trees",
"indoor", "outdoor", "party", "celebration", "sport",
"screenshot", "document", "text", "map",
]
# tools/tag.py
from pipeline.embedder import embed_image, embed_text
from config import TAG_THRESHOLD
import numpy as np
TAG_LABELS = [...] # full list as above
# Pre-compute label embeddings once at module load —
# no point re-embedding the same 50 words on every photo
_label_vectors = {
label: embed_text(label)
for label in TAG_LABELS
}
def generate_tags(image_path: str) -> list[str]:
"""
Run zero-shot classification on an image.
Returns a list of tags whose similarity to the image
exceeds TAG_THRESHOLD (default: 0.20).
"""
image_vector = embed_image(image_path)
tags = []
for label, label_vector in _label_vectors.items():
similarity = np.dot(image_vector, label_vector) # cosine sim on normalised vectors
if similarity >= TAG_THRESHOLD:
tags.append(label)
return tags
Etiquetas en el momento del índice vs. en el momento de la consulta
Las Etiquetas en la fase de indexació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 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 del proceso. Las Etiquetas en la fase de indexació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 falla un paso, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado.
def generate_tags_from_vector(img_vec: np.ndarray, threshold: float = 0.20, max_tags: int = 6) -> list[str]:
"""
Generate tags for an image vector using zero-shot CLIP classification.
Tags with cosine similarity above threshold are included (up to max_tags).
This is a utility function used for generating tags during indexing
or when you already have an image vector.
"""
tag_vecs = _get_tag_vectors()
scores = {
tag: float(np.dot(img_vec, vec)) # both normalized → cosine similarity
for tag, vec in tag_vecs.items()
}
tags = sorted(
[t for t, s in scores.items() if s >= threshold],
key=lambda t: scores[t],
reverse=True,
)[:max_tags]
return tags
Uso de etiquetas como filtros
En la fase de uso de etiquetas como filtros, 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. 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.
def search_photos(query: str, top_k: int = TOP_K, tags: list[str] = None) -> list[dict]:
#search photo library with a Natural language query
#takes in query, no of results to be displayed, and a list of tags
# returns list of dicts with photo metadata and relevance score
print(f"[search] Received query='{query}' with tags={tags} and top_k={top_k}")
shard = get_shard()
query_vector = embed_text(query)
# Over-fetch when tag filtering is requested to have enough candidates
# after post-filtering by tags
over_fetch_multiplier = 5 if tags else 1
fetch_limit = top_k * over_fetch_multiplier
results = shard.query(
QueryRequest(
query=Query.Nearest(query_vector.tolist(), using=VECTOR_NAME),
limit=fetch_limit,
with_vector=False,
with_payload=True,
)
)
print(f"[search] Found {len(results)} initial hits for query='{query}' with tags={tags}")
hits = []
untagged_hits = [] # Fallback results for images without tags
for point in results:
payload = point.payload or {}
point_tags = payload.get("tags", [])
result_dict = {
"path": payload.get("path"),
"filename": payload.get("filename"),
"tags": point_tags,
"timestamp": payload.get("timestamp"),
"score": round(point.score, 4)
}
# Post-filter by tags if specified
# (EdgeShard doesn't support complex filters, so we filter in Python
# after over-fetching more results than needed)
if tags:
if point_tags and any(t in point_tags for t in tags):
# Has tags and matches the filter
hits.append(result_dict)
elif not point_tags:
# No tags yet (images not auto-tagged), save as fallback
untagged_hits.append(result_dict)
else:
# No tag filter specified, include all results
hits.append(result_dict)
# Stop if we have enough tagged results
if len(hits) >= top_k:
break
# If we don't have enough tagged results, include untagged ones that match the query
if tags and len(hits) < top_k:
hits.extend(untagged_hits[:top_k - len(hits)])
return hits[:top_k]
Construyendo el agente de búsqueda
En la fase de creación del agente de búsqueda, 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. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos. Implemente 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.
curl --location 'http://localhost:8000/search' \
--header 'Content-Type: application/json' \
--data '{"query": "eiffel tower from rooftop","tags":[], "top_k": 1}'
{
"query": "eiffel tower from rooftop",
"results": [
{
"path": "/Users/vatsalasingh/Documents/Datasets/tag_phot/photo-1638051017225-0d9fcca18cf4.jpg",
"filename": "photo-1638051017225-0d9fcca18cf4.jpg",
"tags": [
"cloudy",
"city",
"rain",
"screenshot",
"architecture",
"travel"
],
"timestamp": "2021-12-09T17:27:56",
"score": 0.2864
}
]
}
Manejo adecuado de casos límite
Para manejar los casos límite de manera adecuada, 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 pasos que implican gastos o modifican datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial. Para manejar los casos límite de manera adecuada, 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 en lugar de...
una cadena de procesos enredada.Orquestando todo con OpenClaw
Al trabajar en la etapa de orquestación, primero escribe 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. Considera esta etapa como un contrato entre las entradas y los resultados validados. Nombra los artefactos, define las verificaciones de éxito y rechaza las completaciones parciales silenciosas. Haz puntos de control después de pasos costosos. La reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.
Cómo funciona OpenClaw
Al trabajar en la etapa de comprensión de cómo funciona OpenClaw, 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. 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. Haga un punto de control después de los pasos costosos. La reanudación no debe volver a facturar la misma llamada al LLM cuando un operador vuelve a intentar un nodo posterior.
@app.post("/chat")
def chat(req: ChatRequest):
"""
Conversational endpoint. Accepts user message and conversation history,
returns agent's reply after processing with tools.
"""
# Define tool functions that the agent can call
def search_tool(query: str, top_k: int = 10, tag_filter: list = None):
"""Search photos by natural language query"""
return search_photos(query=query, top_k=top_k, tags=tag_filter)
def duplicates_tool(threshold: float = 0.97):
"""Find duplicate or near-duplicate photos"""
return find_duplicates(threshold=threshold)
def tag_tool(image_path: str):
"""Generate and update tags for a specific photo"""
return generate_tags_from_vector(image_path=image_path)
# Create the agent with tools
agent = Agent(
tools=[search_tool, duplicates_tool, tag_tool],
system_prompt="""
You are a personal photo assistant. You help users search, organize,
and understand their local photo library. You have access to tools
for semantic search, duplicate detection, and tagging.
When helping users:
- Use the search tool to find photos by describing their content
- Use duplicates tool to find and clean up duplicate shots
- Use tag tool to inspect or update tags for specific photos
Always be concise and helpful. When returning photo results,
format them clearly with filenames, similarity scores, and tags.
Use emojis sparingly but helpfully.
"""
)
# Run the agent conversation
response = agent.chat(
message=req.message,
history=req.history
)
return {"response": response}
Flujos de interacción reales
Al trabajar en la etapa de flujos de interacción reales, 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. 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 etapa de flujos de interacción reales, 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 sola responsabilidad y no a un proceso complicado.
Por qué es importante la capa de agente
La etapa de la capa de agentes 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 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.
Ejecutar todo localmente: por qué es importante
El enfoque de ejecutar todo localmente y en fases 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. 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.
Nada sale de su dispositivo. Punto final.
The Nothing leaves your device stage 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. 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. Mantenga el estado del grafo simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso. The Nothing leaves your device stage 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.
Qué se necesita realmente para ejecutar esto
En la etapa de “Qué se necesita realmente”, 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. Considere 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 en que se gasten fondos o se modifiquen datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial.
Próximos pasos: ampliando el sistema
En la fase de ampliación de What’s Next, 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. Registre los tiempos de ejecución y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos 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.
Clustering de rostros
En la etapa de clustering facial, 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 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 casos en los que se gastan fondos o se modifican datos de producción. La conexión realizada en tiempo de compilación no equivale a una solución completa desde el punto de vista empresarial. En la etapa de clustering facial, 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.
OCR para capturas de pantalla y documentos
Al trabajar en el OCR para capturas de pantalla y esta etapa, 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 en el código. Trate esta etapa como un contrato entre los datos de entrada 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. El sistema de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intente nuevamente un nodo posterior.
Indexación de fotogramas de video
Al trabajar en la etapa de indexación de fotogramas de video, 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. 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 un punto de control 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.
Búsqueda híbrida: vector + palabra clave + metadatos
Al trabajar en la etapa de palabras clave del vector de búsqueda híbrido, 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 secretos y las banderas de funcionalidad deben estar 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 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 de palabras clave del vector de búsqueda híbrido, 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 sola responsabilidad en lugar de a un proceso complicado.
Búsqueda consciente del tiempo y la ubicación
La etapa de búsqueda consciente del tiempo y la ubicació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. 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. Separe la política de fragmentación de la política de búsqueda. Cambiar una no debe obligar a reescribir la otra cuando cambian las métricas de calidad.
Pensamientos finales
La etapa de “Reflexiones finales” funciona mejor cuando se trata como una superficie medible. Registre un transcripte exitoso, un caso de fallo y la nota de reversión antes de ampliar el alcance. Anote 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 la fase de demostración a entornos compartidos. Mantenga el estado del gráfico en formato plano y con tipos definidos; los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso.
Referencias y lecturas adicionales
La etapa de Referencias y Lectura Adicional 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. La etapa de Referencias y Lectura Adicional 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 verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado.
Lista de verificación operativa
La etapa de lista de verificación operativa 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.
Documente tanto la ruta óptima como la ruta de recuperación juntas. Los intentos repetidos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son ajustes realizados posteriormente.
Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y dificultan la reanudación después de interrupciones.
Añada una prueba 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.
Prefiera unidades pequeñas y probables sobre scripts extensos. Cuando falla un paso, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado.
Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y dificultan la reanudación después de interrupciones.
Antes de promocionar el stack, congele las versiones, capture una transcripción de referencia para la ruta crítica y confirme los pasos de reversión. Los entornos compartidos requieren límites de velocidad, verificaciones de tenencia y un responsable claro para la rotación de secretos. Prefiera una fiabilidad sencilla a demostraciones ingeniosas pero puntuales.
Nota por lotes para b7b9768f8acd: mantenga las claves del proveedor fuera del repositorio, establezca un límite de tokens por sesión y almacene las transcripciones junto a los fixtures de evaluación para que los cambios posteriores en el modelo sigan siendo comparables.