Guardrails para LLM en streaming: un token enviado no se retira
Guardrails para LLM en streaming: un token enviado no se retira. Velocidad frente a seguridad en NeMo, Guardrails AI y Bedrock, y cómo validar cada afirmación.
Un token que un LLM ya ha enviado en streaming no se puede recuperar. Cuando el texto llega al lector, un guardrail que lo rechace solo puede detener lo que viene después. Por eso un guardrail sobre un flujo toma una única decisión real: comprobar antes de liberar el texto y hacer esperar al lector, o liberarlo primero y aceptar que una respuesta bloqueada ya se ha leído. Hay tres formas viables: comprobar después de liberar, retener y comprobar fragmentos fijos, o retener y comprobar frases completas. El asistente de este sitio, que he construido yo, aplica una compuerta por frases. El coste es esperar una frase. El límite es que comprueba si una afirmación está respaldada, no si es verdadera.
Este artículo trata la última comprobación antes de liberar una respuesta fundamentada. Las capas anteriores, desde rechazar preguntas fuera de ámbito hasta un umbral mínimo de puntuación de recuperación, se describen en Guardrails contra las alucinaciones en RAG: un diseño en cinco capas.
Por qué no se puede retirar un token enviado en streaming
Un validador a posteriori ve la respuesta completa solo después de que el lector la haya leído. Si la tercera frase inventa una fecha, borrarla después cambia el registro, no lo que se leyó. Un preprint reciente de arXiv firmado por Christopher M. Frost formula el límite con exactitud: «un control que detecta un patrón prohibido después de liberar el fragmento que lo completa no puede recuperarlo».
Los proveedores documentan el mismo límite. El filtro asíncrono de Azure OpenAI, que hay que activar expresamente, devuelve el texto de inmediato y solo garantiza su señal de infracción dentro de unos 1000 caracteres del contenido infractor. Su guía de solución de problemas aconseja «implementar en su aplicación la ocultación de contenido para eliminar el contenido ya mostrado». La entrada LLM09:2025 de OWASP recomienda herramientas y procesos «para validar automáticamente las salidas clave». La pregunta abierta es cuándo se ejecuta la validación con respecto a la liberación del texto.
Tres formas de proteger un flujo: a posteriori, por fragmentos y por frases
Enfoque | El lector ve el texto | Una respuesta bloqueada | Ejemplos |
|---|---|---|---|
A posteriori (primero se libera) | Antes de comprobarlo (NeMo: cada fragmento en cuanto se acumula en el búfer; modos asíncronos de Azure y Bedrock: según se genera) | Se lee en parte antes de la parada | NeMo con |
Compuerta por fragmentos | Cuando cada fragmento pasa | El fragmento bloqueado nunca se muestra | Valores por defecto de Azure y Bedrock; NeMo con |
Compuerta por frases | Cuando cada frase pasa | La frase bloqueada nunca se muestra | El asistente de este sitio |
Qué gana y qué pierde stream_first en NeMo Guardrails
En NeMo Guardrails, el streaming de los output rails está desactivado por defecto. Una vez activado, ejecuta los output rails (las comprobaciones que NeMo aplica al texto generado) sobre fragmentos de 200 tokens por defecto y traslada 50 tokens de contexto al fragmento siguiente. El indicador stream_first vale True por defecto: «El cliente recibe cada fragmento de tokens antes de que los output rails procesen ese fragmento. Esto reduce el tiempo hasta el primer token, pero si un rail bloquea el contenido, el usuario ya ha recibido los tokens». El flujo termina entonces con un error JSON.
Con False, «el usuario nunca ve el contenido bloqueado, pero el tiempo hasta el primer token aumenta en el tiempo de ejecución del rail por fragmento». Ese es el compromiso: tiempo hasta el primer token (TTFT) frente a texto bloqueado que llega al lector. Con el streaming de output rails activado, NeMo libera primero por defecto; los dos filtros en la nube que se describen más abajo comprueban primero. Si un rail está ahí para detener algo que nunca debe verse, cambie el valor por defecto.
Qué ganan y qué pierden los validadores por frases de Guardrails AI
Guardrails AI elige la frase: «Por defecto, los validadores esperan a haber acumulado del LLM el equivalente a una frase de contenido antes de ejecutar la validación». Validar frases sueltas en lugar de la respuesta completa «ayuda a ahorrar costes en los validadores que requieren una inferencia cara».
No todos los tipos de on_fail admiten streaming, y las correcciones de varios validadores esperan «a que todos los validadores acumulen suficientes fragmentos» antes de fusionarse. La documentación no dice con claridad si los tokens en bruto llegan al usuario antes de la validación, así que compruébelo en su propia integración.
Con búfer por defecto: Azure OpenAI y Amazon Bedrock
Azure OpenAI acumula por defecto en un búfer el texto generado, filtra ese búfer y devuelve «fragmentos de contenido» en lugar de tokens sueltos. Amazon Bedrock Guardrails analiza los fragmentos antes de enviarlos en su modo síncrono por defecto, que «introduce cierta latencia» pero «ofrece mayor precisión». En el modo asíncrono de Bedrock, los fragmentos «pueden contener contenido inapropiado hasta que termina el análisis de los guardrails», y la información sensible no se puede enmascarar.
Cómo una compuerta por frases valida un flujo en streaming
El asistente de este sitio responde solo a partir del contenido del propio sitio, y una pregunta que no trata sobre mí y que ningún pasaje respalda nunca llega al modelo. Habla de mí en tercera persona. En un sitio que lleva mi nombre, el peor fallo es una credencial inventada, y una credencial es una afirmación. La frase es la unidad más pequeña capaz de contener una afirmación, así que la compuerta acumula el texto en el búfer hasta un límite de frase, lo comprueba y solo entonces lo libera. La demo del laboratorio RAG frente a sin RAG llama al mismo endpoint de streaming.
Dónde termina una frase cuando aún llegan tokens
Terminadores:
.!?…, más el signo de interrogación؟y el punto۔de la escritura árabe y, para el chino y el hindi,。!?, el danda।y el doble danda॥. Una secuencia como?!cuenta como un solo límite. El punto y coma؛de la escritura árabe une proposiciones, así que se deja fuera a propósito.Debe seguir un espacio en blanco. Esa única regla mantiene enteros
3.14yexample.com. La excepción son el punto y los signos de exclamación y de interrogación del chino, tras los que no va ningún espacio. Dentro de una cita terminan la frase donde se cierra la cita, y no la terminan si después viene una coma.No todo punto termina una frase. Seguido de minúscula no la termina (
et al. y), y tampoco el punto de una abreviatura de una lista breve, comoe.g.,p. ej.o el alemánbzw., ni el que sigue al día en una fecha alemana (am 17. September).El carácter siguiente decide. Un límite solo es definitivo cuando llega un carácter que no es ni un espacio ni un marcador de cita, porque los marcadores que siguen al punto pertenecen a la frase anterior: todos,
[S1][S2]o[S1] [S2], no solo el primero.Un marcador de lista tras un límite no es una frase. De lo contrario, un
1.al principio de la respuesta o de una frase nueva se juzgaría como una afirmación sin cita y detendría una respuesta fundamentada en su primera viñeta.Un tope. Pasados mil caracteres sin ningún límite, el búfer se corta en el último espacio y se comprueba de todos modos.
Una línea en blanco se conserva. Una frase que venía después de una línea en blanco se libera también después de una, así que una respuesta de dos párrafos conserva sus dos párrafos.
Esperar al carácter siguiente suele costar un carácter de retraso, algo más cuando al punto le siguen marcadores. La última frase se comprueba cuando termina el flujo. Las comparaciones unifican los dígitos y separadores persas (۳٫۱۴ coincide con 3.14) y las formas de las letras árabes, eliminan los signos de vocales breves del árabe y tratan el carácter de no unión de ancho cero (ZWNJ) como un espacio: las mismas variantes que la búsqueda híbrida para RAG en persa resuelve en el lado de la recuperación.
Las cuatro comprobaciones deterministas: citas, valores y persona gramatical
Rango de citas. Un marcador como
[S7]cuando se han proporcionado seis fuentes nombra una fuente inventada.Cita obligatoria. Una frase de ocho palabras o más, o con cualquier número, URL o dirección de correo electrónico, necesita un marcador. Las frases cortas de transición pasan.
Respaldo literal. Todo número, URL y dirección de correo debe aparecer en una fuente que la frase cite. La coincidencia respeta los límites entre dígitos, así que un año que figura en una fuente no puede avalar un porcentaje que comparte sus últimas cifras, y los decimales que solo se diferencian en ceros finales son un mismo valor:
20.00es20. Una coma que no agrupa millares es una coma decimal:2,5es2.5, no25.Persona gramatical. Una palabra en primera persona detiene el flujo. La lista en inglés es corta y fija: los pronombres de primera persona y sus contracciones. La lista en persa está seleccionada a mano: pronombres más unas pocas formas verbales de alto riesgo, como los equivalentes persas de «soy» y «tengo». El persa marca la persona con terminaciones verbales que los sustantivos corrientes también pueden tener, así que una regla lo bastante amplia para capturar todas las terminaciones capturaría también sustantivos. Las listas de los demás idiomas del sitio recogen pronombres personales y posesivos, y las del español, el portugués, el ruso, el árabe y el hindi añaden algunos verbos, porque esos idiomas suelen decir «yo» solo con el verbo; en chino se busca 我 en cualquier punto de la frase, salvo en un compuesto de 自我, «auto-», como 自我修正 («autocorrección»). Qué listas se aplican depende del idioma en que se pidió la respuesta. Las de inglés, persa, árabe, ruso, hindi y chino se aplican a todas las respuestas. El inglés es el idioma de las instrucciones del modelo y, por tanto, aquel hacia el que más probablemente se desvíe una respuesta; los otros cinco usan escrituras en las que ningún nombre ni sigla latinos puede formar una de sus palabras. La excepción es una respuesta en árabe, que no se comprueba en busca del «yo» y el «nosotros» persas, porque en árabe esas mismas palabras significan «de» y «qué». Las listas de alemán, francés, español y portugués solo se aplican a las respuestas pedidas en su idioma: sus palabras cortas también son nombres y palabras corrientes de otros idiomas, como el «Ma» de «Ma et al.». Las siglas en mayúsculas, un apellido delante de «et al.» y el número romano de «anexo I» se apartan antes de leer cualquier lista.
Qué ocurre cuando una frase no supera la compuerta
Se liberan todas las frases que pasaron antes del fallo, incluidas las anteriores del mismo lote.
La compuerta se detiene y sigue detenida: una sola frase sin respaldo desacredita el resto.
Un evento
guardlleva los motivos de la infracción y un texto fijo y localizado que indica que el resto se ha retenido, y el evento finaldoneregistra la parada. La frase bloqueada nunca se envía; el servidor solo registra su longitud.Se cierra el flujo del proveedor, que es como este diseño cancela la petición upstream. Lo generado antes del corte sigue en la factura, así que también se imputa al límite de gasto mensual. Los dos protocolos de proveedor informan del consumo de salida en un evento final al que un flujo cortado a medias nunca llega, así que el servicio se queda con el texto que recibió y rellena lo que el proveedor no notificó a un token por byte UTF-8, un recuento que, si se equivoca, lo hace por exceso. Los tokens que un modelo de razonamiento gasta en pensar nunca llegan como texto, así que esa estimación los deja fuera. El artículo de las cinco capas trata el límite de gasto.
El panel de chat marca el turno como retenido y conserva en el historial de la conversación el texto ya liberado, porque ese texto está respaldado hasta la parada.
El truncamiento es un fallo distinto, y una versión anterior de este asistente confundía los dos. Cuando el modelo se quedaba sin espacio de salida, la compuerta juzgaba el fragmento cortado como una frase terminada y lo retenía por no llevar cita. Al lector se le decía que una respuesta que solo se había interrumpido no podía respaldarse con las fuentes. Cuando no llegaba ningún texto, el turno desaparecía sin ningún mensaje. Ahora el fragmento inacabado se descarta sin juzgarlo y se muestra un aviso de corte. Una frase interrumpida no es una frase sin respaldo. Si ocurren ambas cosas, prevalece la parada de la compuerta.
Los marcadores de cita son internos
El prompt pide un marcador [Sn] en cada frase que enuncia un hecho, y la compuerta aplica la regla de cita obligatoria a cada frase sustantiva. Cuando una frase pasa, se eliminan sus marcadores y se corrige el espaciado, también delante de la puntuación persa, de modo que los lectores ven prosa, no marcadores. Quitar los marcadores del prompt, en cambio, haría que todas las frases sustantivas incumplieran la regla de cita obligatoria.
Cuando el modelo no tiene nada que decir
Cuando las fuentes no cubren la pregunta, el prompt pide al modelo un token fijo, no una frase. Un rechazo redactado por el modelo sería una afirmación como cualquier otra, y además sin cita, que la compuerta detendría con un aviso que culpa a las fuentes de una pregunta que nunca les correspondió responder.
La compuerta nunca libera el token. Mientras el texto recibido todavía pueda acabar siendo el token, lo retiene; el primer carácter que lo descarta envía el texto por el camino habitual, así que una respuesta normal no espera nada de más. Si una respuesta empieza por el token, el servicio la sustituye por el rechazo fijo del sitio, el mismo texto que muestra cualquier otro rechazo. Si el token llega después de frases ya liberadas, esas frases se mantienen y la respuesta termina ahí.
Comprobar «respaldado» no es comprobar «verdadero»
En un estudio dirigido por Stanford, Magesh y sus colegas llevaron a cabo lo que describen como la primera evaluación prerregistrada de herramientas de investigación jurídica con IA. Las herramientas de investigación con IA de LexisNexis y de Thomson Reuters alucinaron cada una entre el 17 y el 33 % de las veces. Una respuesta contaba como alucinada si era «incorrecta o mal fundamentada», y mal fundamentada significa que «las proposiciones fácticas clave están citadas, pero malinterpretan la fuente o remiten a una fuente no aplicable». Las respuestas mal fundamentadas llevan citas. Lo que esto implica para los productos de IA jurídica se trata en otro artículo.
Una compuerta que solo compara cadenas no puede detectar una fundamentación errónea, y esta compuerta tiene puntos ciegos conocidos:
Una frase que cita dos fuentes puede tomar un valor de cualquiera de ellas. La comprobación se hace por frase, no por proposición.
Un punto decimal cuenta como límite.
14.52en una fuente puede avalar52%o14, y un separador de millares hace lo mismo:1,200avala200.Las palabras no se comprueban. Una frase sin números que cambia un cargo o una organización pasa con cualquier marcador dentro de rango.
Las frases cortas sin cita pasan. Una frase de menos de ocho palabras sin números, URL ni direcciones no necesita marcador. El chino no pone espacios entre palabras, así que en él se cuentan los caracteres, tres por cada dos palabras: una frase formada solo por caracteres chinos no necesita marcador por debajo de doce.
Las listas fijas de palabras tienen huecos. En inglés,
we'dylet'spasan, igual que un pronombre escrito todo en mayúsculas, comoWEoUS, que se lee como una sigla. La cobertura de la primera persona en persa se apoya en el prompt: un verbo en primera persona que no está en la lista seleccionada pasa. Las listas de los demás idiomas también están seleccionadas a mano, y la primera persona en alemán, francés, español o portugués dentro de una respuesta pedida en otro idioma queda en manos del prompt.La puntuación de cierre puede fusionar frases. Tras unas comillas que se cierran sobre un terminador, como en
?»o.", solo una mayúscula o un salto de línea termina la frase; tras un paréntesis, como en.), solo un salto de línea o un marcador de cita. Así, dos frases pueden juzgarse como una: tras.)ante una mayúscula, tras؟»en árabe, persa e hindi, que no tienen mayúsculas, y tras las comillas alemanas„…?“y»…?«, que el divisor de frases no lee como comillas de cierre. Los signos chinos conservan su propia regla, descrita más arriba.
El error también se da en sentido contrario. Una abreviatura que no está en la lista termina una «frase» antes de tiempo cuando la sigue una mayúscula, como Sr. ante un nombre propio, y lo mismo hace una pregunta entre comillas seguida de un nombre o, en alemán, de cualquier sustantivo; si ese fragmento tiene ocho palabras o más y ningún marcador, se retiene una respuesta fundamentada. Una lista introducida por una línea que acaba en dos puntos no tiene ningún límite antes de su primer marcador. El divisor de frases corta justo después de 1., y ese fragmento incumple la regla de cita obligatoria. En ambos casos la compuerta falla en modo cerrado: retiene una respuesta fundamentada antes que liberar una sin comprobar.
El corpus también cambia. Los artículos publicados se indexan para el asistente, así que sus cifras, incluidos el 17 y el 33 % de este artículo, pasan a ser valores que la compuerta avalará. «Respaldado» significa «en algún lugar de lo que cita la frase», no «sobre esto».
La compuerta es la última comprobación antes de liberar el texto, no la única. Joren y sus colegas observaron que los modelos más grandes «a menudo dan respuestas incorrectas en lugar de abstenerse» cuando el contexto no es suficiente, y Google Research señala que, aunque RAG en general mejora el rendimiento global, «reduce, paradójicamente, la capacidad del modelo de abstenerse de responder cuando corresponde». Por eso el rechazo y el umbral de puntuación van primero, como expone el diseño en cinco capas. El preprint de Frost enuncia el límite de su propio resultado con unas palabras que también encajan con esta compuerta: «conformidad con la política para una red de seguridad determinista, no una prueba de seguridad semántica ni de completitud de la política».
SSE para streaming de LLM: fetch, proxies y cancelación
Una compuerta por frases solo sirve si cada frase liberada llega al lector en el acto. Lo deciden cuatro detalles del transporte.
Por qué fetch y ReadableStream, y no EventSource
La especificación de WHATWG da al constructor de EventSource una URL y una sola opción, withCredentials: ni método ni cuerpo. Una pregunta con su idioma y su historial es un cuerpo, así que el endpoint es un POST que devuelve Server-Sent Events. El navegador lo lee con fetch, un lector de ReadableStream y un AbortController, cuyo abort(), en palabras de MDN, «puede abortar peticiones fetch, el consumo de cualquier cuerpo de respuesta y los streams».
Un parser escrito a mano necesita estas reglas:
Acumular en un búfer entre lecturas. Un fragmento no es un mensaje.
Despachar el evento al llegar una línea en blanco. Mientras no llega, el evento está incompleto.
Ignorar las líneas de comentario, las que empiezan por
:.Unir los datos de varias líneas: todas las líneas
data:de un mismo evento se unen con un salto de línea (LF).Aceptar CRLF, LF y CR como finales de línea.
Quitar un espacio después de los dos puntos, y solo uno.
Decodifique con TextDecoder y {stream: true}, la opción que MDN indica «si se procesan los datos en fragmentos». De lo contrario, un carácter persa partido entre dos fragmentos se decodifica como caracteres de sustitución.
Buffering en proxies: nginx y Caddy
nginx acumula por defecto en un búfer las respuestas cuando actúa como proxy, y la cabecera de respuesta X-Accel-Buffering puede desactivar ese búfer. El flujo del asistente envía X-Accel-Buffering: no y Cache-Control: no-cache, no-store, no-transform; no-transform está ahí porque un proxy que vuelve a comprimir el cuerpo puede agrupar fragmentos. Caddy vacía de inmediato hacia el cliente las respuestas text/event-stream, y la configuración de Caddy del sitio fija además flush_interval -1 en la ruta del chat. El service worker no registra ninguna ruta para el flujo, porque una estrategia de caché retendría la respuesta hasta que terminara.
Keep-alives y errores dentro de un flujo abierto
La especificación de SSE sugiere una línea de comentario «cada 15 segundos más o menos» para protegerse de los proxies antiguos que cortan las conexiones tras un tiempo de espera corto, y el servidor envía un ping con ese intervalo. El código de estado ya es 200 cuando sale el primer byte, así que los fallos viajan como un evento error dentro del flujo.
Una cancelación que también corta el gasto
Detener la respuesta en el navegador aborta el fetch. El servidor comprueba si se ha producido una desconexión a medida que llega cada token. Cuando detecta una, sale del bucle y cierra el flujo del proveedor, lo que en este diseño cancela la petición upstream. Hay dos cosas que merecen una prueba y no una suposición. La primera, que cada proxy y cada CDN entre el navegador y su API transmitan la desconexión del cliente. Pruebe esa ruta; no se fíe de la configuración. La segunda, cuándo notifica su proveedor el consumo: si el consumo de salida solo llega con el último fragmento, un flujo que usted cierre antes de tiempo nunca lo recibe, y un límite de gasto que cuente el consumo notificado se quedará por debajo de lo que realmente se generó.
Cómo probar un guardrail en streaming
Las pruebas cubren la compuerta en tres niveles:
Pruebas unitarias de la compuerta con fuentes fijas. Los valores inventados, los marcadores fuera de rango, las afirmaciones sin cita y las palabras en primera persona (en cada uno de los idiomas del sitio) detienen el flujo; los valores respaldados y las frases cortas de transición pasan; las frases correctas anteriores sobreviven a una frase incorrecta posterior.
Pruebas del divisor de frases. Los decimales y los dominios no son límites, los marcadores finales se quedan con su frase y
؟termina una frase. El texto en chino se divide en frases sin espacios. La que merece la pena copiar: un texto introducido en trozos de tres caracteres debe dividirse exactamente igual que el texto completo.Pruebas del flujo con un proveedor simulado que reproduce una respuesta predefinida en trozos pequeños: un valor inventado nunca llega a la red, una parada de la compuerta o una desconexión cierra el flujo upstream, y el truncamiento se notifica como truncamiento.
Este es un esbozo de las dos pruebas centrales, escrito para este artículo y no tomado del sitio:
# Sketch only: SentenceSplitter and SentenceGate stand for your own classes.
import pytest
ANSWER = "The reading room opens early [S1]. Is the café open? Yes, on weekdays [S2]."
def pieces(text, size):
return [text[i:i + size] for i in range(0, len(text), size)]
def split_streamed(text, size):
splitter = SentenceSplitter()
sentences = [s for piece in pieces(text, size) for s in splitter.feed(piece)]
tail = splitter.flush()
return sentences + ([tail] if tail else [])
@pytest.mark.parametrize("size", [1, 2, 3, 7])
def test_piece_size_does_not_change_sentences(size):
assert split_streamed(ANSWER, size) == split_streamed(ANSWER, len(ANSWER))
def test_unsupported_value_never_reaches_the_reader():
gate = SentenceGate(sources=["The library opens at nine."])
released = ""
for piece in pieces("It opens at nine [S1]. Late fees ended in 2019 [S1]. More", 7):
outcome = gate.feed(piece)
released += outcome.text
if outcome.stopped:
break
assert "2019" not in released and gate.stoppedNinguna de estas pruebas hace red teaming sobre un modelo en vivo. Lo que he medido son los errores de la propia compuerta: respuestas grabadas en producción y reproducidas sin conexión, para encontrar dónde detuvo una respuesta fundamentada. Eso cuenta detenciones en falso con un modelo y un conjunto de preguntas, no la frecuencia con la que un modelo real inventa, así que no lo publico como una tasa.
Lista de comprobación: desplegar un guardrail sobre una respuesta en streaming
Decida qué no debe verse nunca. Eso determina si se comprueba antes o se libera primero, sea cual sea el valor por defecto de su framework.
Elija la unidad y haga explícita la espera: un fragmento fijo o una frase.
Use comprobaciones deterministas cuando basten las cadenas, y unifique antes los dígitos y las formas de las letras. Un rail basado en un modelo suma su tiempo de ejecución a cada unidad.
Dé por confirmado un límite solo cuando llegue el carácter siguiente, y ponga un tope al búfer.
Ante una infracción, libere lo que pasó, detenga el flujo, muestre un texto fijo, no repita nunca el texto bloqueado y cierre el flujo upstream.
Separe el truncamiento de la infracción, y contabilice lo que se generó, no lo que se mostró.
Transporte: POST con
fetch, un lector de stream yAbortController; un decodificador en modo streaming; pings como líneas de comentario; errores como eventos.Proxies:
X-Accel-Buffering: no,no-transform, vaciado inmediato de event-stream, una ruta de desconexión probada y ningún service worker sobre el flujo.Pruebas: reproduzca respuestas en trozos pequeños y compruebe que un valor bloqueado nunca llega a la red.
Si está diseñando un asistente fundamentado y quiere otra mirada sobre su ruta de liberación, la página de Diagnóstico de proyecto es donde empieza esa conversación.
Preguntas frecuentes
¿Se puede validar la salida de un LLM en streaming sin renunciar al streaming?
Sí. Acumule el texto en un búfer hasta una unidad que pueda comprobar y libere cada unidad cuando pase. El lector ve llegar el texto frase a frase o fragmento a fragmento, en lugar de token a token.
¿Retener el texto hasta completar una frase empeora el tiempo hasta el primer token?
Retrasa la salida visible en una frase: el texto aparece cuando la primera frase está completa y comprobada. Las comprobaciones de cadenas son baratas en comparación con la generación, pero no he medido la diferencia en este sitio, así que no doy ninguna cifra.
¿Debo desactivar stream_first en NeMo Guardrails?
Desactívelo si un fragmento bloqueado no debe verse nunca. NeMo documenta el coste: el tiempo hasta el primer token aumenta en el tiempo de ejecución del rail por fragmento. Mantenga el valor por defecto solo si su producto puede aceptar que un lector vea tokens que un rail bloquea después.
¿Por qué no usar EventSource para el streaming de LLM?
EventSource acepta una URL y un indicador de credenciales, así que no puede enviar un cuerpo de petición. Una petición de chat con historial es un POST, así que use fetch con un lector de stream, que además le permite cancelar mediante AbortController.
¿Una comprobación de citas evita las alucinaciones?
No. Detiene los números de fuente inventados, las frases sustantivas sin cita y los valores que no están en las fuentes que cita una frase. No puede saber si una fuente citada respalda la afirmación, que es el fallo de fundamentación errónea. Trátela como una red de seguridad por detrás del rechazo y del umbral de recuperación.