DatabricksAdapter yields text content during tool-calling rounds, causing response duplication

Abierto
#421 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 3 días

Nadie ha tomado este issue todavía.

  • #436 de @MarioCadenas — cerrado sin fusionar

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
typescript
Área
ai, api, backend

Línea de trabajo

Empieza por DatabricksAdapter's streamCompletion() y el método run() alrededor de la línea 196, y después reproduce el problema con maxSteps: 10 y varias herramientas como describeTable y executeSql. Rastrea los eventos message_delta y tool-call a lo largo de una ronda de llamadas a herramientas. Se considera terminado cuando el texto intermedio no produce respuestas duplicadas visibles para el usuario, mientras que la respuesta final sigue apareciendo una sola vez.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

DatabricksAdapter yields text content during tool-calling rounds, causing response duplication

Problem

When using DatabricksAdapter with Claude models via Databricks Model Serving (OpenAI-compatible endpoint), the model produces substantial text content alongside tool calls in the same response turn. The adapter's streamCompletion() method yields all delta.content text as message_delta events regardless of whether the same response also contains tool calls.

In a multi-step ReAct loop, this causes the model's intermediate text (which often includes the full answer) to be emitted and displayed to the user on every tool-calling turn — resulting in the same answer appearing 3-4× in the final output.

Root Cause Analysis

Claude's native API uses a trained-in tool-use system prompt that shapes the model to produce brief commentary before tool_use blocks. The Databricks OpenAI-compatible translation layer does not include this trained-in prompt, so Claude produces more verbose text during tool-calling rounds.

The adapter loop (run() method, line ~196) correctly breaks when no tool calls are present, but during tool-calling rounds, streamCompletion() yields ALL delta.content as message_delta events — there's no mechanism to suppress or buffer text that arrives in a turn that also contains tool calls.

Expected Behavior

Text content from tool-calling rounds should either:

  1. Be suppressed (not yielded as message_delta) when the same response also contains tool_calls
  2. Be buffered until streamCompletion returns, and only yielded if no tool calls were detected
  3. Be marked with metadata so consumers can distinguish intermediate text from final-answer text
Current Workaround

We added:

  • A system prompt instruction telling the model to only write brief status notes during tool-calling turns
  • Client-side text buffering in the SSE transport layer that discards accumulated text when a function_call event arrives in the same round
Environment
  • AppKit version: 0.38.1
  • Model: databricks-claude-opus-4-6 via Model Serving
  • Adapter: DatabricksAdapter.fromServingEndpoint()
Reproduction
  1. Create an agent with maxSteps: 10 and multiple tools (e.g., describeTable, executeSql)
  2. Ask a question that triggers 3+ tool calls
  3. Observe that the assistant's text response contains the full answer repeated once per tool-calling round
Lenguaje dominante
TypeScript
Estrellas
119
Forks
36
Merge medio
4 d 16 h
PR fusionados (30 d)
37

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de databricks/appkit

Todos los issues de databricks/appkit

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.