Skip to content

CH 09 · Subsistemas centrales y el flujo de un mensaje

Cantidad de texto~2.730 palabrasTiempo~14 minPrereqÁrbol de plugins de CH 08NivelConceptual

Objetivo del capítulo

CH 08 explicó que dsh es "un árbol de plugins"; este capítulo hace zoom: qué maneja cada plugin clave (subsistema) del árbol, cómo se coordinan, y luego sigue un mensaje de principio a fin — desde cuando pulsas Enter hasta cuando responde, qué pasa entre medias. Cuando veas estas dos cosas, sabrás cómo funciona dsh internamente.

Subsistemas centrales: el equipo de la cocina trasera del restaurante

Continuando con el pequeño restaurante de CH 08: la cocina no es una persona, sino un equipo con divisiones claras de trabajo, cada uno manejando lo suyo, pasándoselo entre sí. Los subsistemas centrales de dsh son este equipo:

SubsistemaContraparte en el personalQué maneja
agent-loopChef principalEl driver por defecto: decide "qué hacer a continuación" — pedir al modelo, llamar herramientas, recoger resultados; todo el bucle lo conduce él
llmOperador de la línea de pedidos para llevarConecta con modelos externos vía adaptadores, envía mensajes, recibe respuestas
toolsArmario de herramientas + porteroRegistro de herramientas + pipeline de ejecución controlada; cada agent usa el suyo (aislamiento por scope)
system-promptBandeja de preparaciónUne los fragmentos de prompt y los schemas de herramientas registrados por varios plugins en "lo que este plato muestra al modelo"
sessionLibro de cuentasLog de sesión append-only: lo que enviaste, lo que respondió el modelo, qué herramientas corrieron — todo registrado
scopeAislamiento de puestoHace que el registro de cada agent solo sea efectivo en su propia celda, sin cruces

Cómo se coordinan, mira este diagrama:

Cómo colaboran los subsistemas centrales (ilustración)

Una regla nemotécnica: el chef principal (agent-loop) da las órdenes, la bandeja (system-prompt) prepara, el operador de la línea (llm) pide para llevar, el armario de herramientas (tools) entrega las herramientas, y todos los resultados se apuntan en el libro de cuentas (session). El libro de cuentas es la estrella del siguiente capítulo.

Una unidad clave: step y turn

Antes de mirar el flujo, distingue primero dos términos; son la base para entender toda la cadena:

  • step = una petición al modelo + las herramientas que llama. El modelo "piensa + actúa" una vez es un step.
  • turn = cero o más steps. Desde recoger tu primera entrada hasta que ya no quede trabajo pendiente.

¿Por qué una sola respuesta puede tener varios steps? Porque el modelo a menudo hace "piensa un poco → llama una herramienta → ve el resultado y piensa otra vez → llama otra..." hasta que siente que es suficiente y entonces da la respuesta final. Toda esta cadena es un turn, y cada "piensa + actúa" dentro es un step. Las palabras oficiales: un turn se abre antes de recoger la primera entrada, y se cierra cuando ya no queda trabajo pendiente.

Una analogía de la vida real: pides una comida (turn), el camarero puede ir y venir varias veces (step) — primero confirma si el plato está disponible, luego lo sirve, luego pregunta si quieres algo extra — hasta que el pedido está completamente servido.

El flujo de un mensaje: desde tu tecla Enter hasta su respuesta

Ahora recorre un mensaje de principio a fin. Sigue este diagrama de arriba hacia abajo:

El flujo de un mensaje: desde tu tecla Enter hasta su respuesta (ilustración)

① turn/start: el turn se abre. Antes de pulsar Enter, este turn no ha empezado; después de pulsar, el turn primero se abre, entrando en "recoger entrada".

② Recoger entrada (inbox). Todas las entradas van primero a un buzón llamado inbox. El mensaje que enviaste despertará inmediatamente al chef principal para que empiece a trabajar; mientras que el "contexto inyectado" (el tipo que viste en CH 04) se queda primero en el buzón, esperando a que otro mensaje real lo despierte — así que "inyectar datos" por sí solo no interrumpirá el flujo.

③ Ensamblar: prompt + schema de herramientas. system-prompt une los fragmentos registrados por varios plugins en un plato, diciéndole al modelo "quién eres, qué herramientas hay disponibles, cómo son las herramientas".

④ agent/pre-step: decidir qué ve el modelo. Este es el primer "punto de extensión en vivo" — los plugins pueden reescribir el contenido que se va a enviar aquí, o directamente rechazarlo. Si se rechaza o se reescribe a vacío, el turn se cierra igualmente y se registra como siempre; el log muestra "lo intentó una vez pero no corrió".

⑤ step/start: ledger + tomar el historial. El mensaje que enviaste se escribe en el log de sesión como user/message; al mismo tiempo, el historial del modelo para este turn se proyecta desde el log (deriveMessages()). Todo lo que ve el modelo viene del log — esta es una línea a la que volveremos una y otra vez.

⑥ Pedir al modelo → recibir la respuesta. agent/request envía la petición (interceptable), llm/stream transmite en streaming, y la respuesta del modelo se escribe en el log como assistant/message.

⑦ ¿Necesita llamar a una herramienta? Si el modelo decide "necesito actuar", es tool/call → ejecutar → el resultado tool/result se escribe de vuelta en el log. Hay puntos de interceptación antes y después de la ejecución (pre/post-execute). Si no se necesita ninguna herramienta, salta al siguiente step.

⑧ step/end: ¿más trabajo? Si el resultado de la herramienta necesita que el modelo lo procese otra vez (o llega una nueva entrada), abre otro step, vuelve a "recoger entrada"; hasta que ya no quede trabajo pendiente, va a agent/turn-stoppingturn/end, este turn termina, y ves la respuesta final.

Una distinción clave que debes tener en mente: el lado derecho del diagrama marca dos tipos de eventos —

  • Eventos persistentes (turn/*, step/*, user/message, assistant/*, tool/*): escritos en el log de sesión, siguen ahí después del reinicio;
  • Puntos de extensión en vivo (agent/pre-step, agent/request, llm/stream, tools/*): solo efectivos mientras se ejecuta; los plugins los usan para interceptar y cambiar el comportamiento, pero ellos mismos no quedan en el libro de cuentas.

Esto hace eco al "los eventos son puntos de extensión" de CH 08: para observar o interceptar el trabajo en ejecución, vigila los eventos en vivo; para dejar hechos persistentes, usa los eventos persistentes.

De dónde viene la memoria del modelo

Una línea: el log de sesión es el contexto que ve el modelo. Lo que el modelo "recuerda" en este turn no es algo que recuerde él mismo; es el historial que el sistema proyecta desde el log — así que "lo que ve el modelo es lo que está registrado" es una regla dura en dsh: cualquier cosa que llegue a una petición al modelo debe ser reconstruible desde el log, y el runtime lo comprueba con un invariante. Esta regla es el eje de todo el diseño; la cubriremos en CH 10.

Una referencia rápida con lo anterior: la "vista de Trajectory" que viste en CH 04 — esa fila de timeline ASSISTANT / TOOLpor debajo no es más que una visualización de este log de sesión. Lo que dijo el modelo, qué herramientas llamó, cuáles fueron los resultados — todo se renderiza desde el log. Así que cuando preguntas "¿por qué recuerda lo que dije antes?", la respuesta es sencilla: no es el modelo el que recuerda, es el log el que recuerda — cada vez antes de una consulta, el sistema proyecta el historial desde el log y se lo pasa al modelo.

Lo que aprendiste en este capítulo

  • [ ] Enunciar la división de trabajo de los subsistemas centrales (agent-loop / llm / tools / system-prompt / session), y explicar cómo se coordinan
  • [ ] Explicar la diferencia entre step y turn (step = una petición al modelo + herramientas; turn = cero o más steps)
  • [ ] Recorrer el flujo completo de un mensaje siguiendo el diagrama: turn/start → recoger entrada → ensamblar → pre-step → step/start → pedir al modelo → tool call → step/end → turn/end
  • [ ] Distinguir eventos persistentes de puntos de extensión en vivo, y enunciar el propósito de cada uno (dejar evidencia vs interceptar)
  • [ ] Enunciar el significado de la regla "lo que ve el modelo es lo que está registrado"

Open Source · MIT · Community Driven