Schéma d’agent d’entrée et de sortie hérité (Model Serving)
Pour les nouveaux cas d'utilisation, Databricks recommande de déployer des agents sur Databricks Apps pour un contrôle total sur le code des agents, la configuration du serveur et le workflow de déploiement. Consultez Créer un agent IA et le déployer sur Databricks Apps. Pour migrer un agent existant, consultez Migrer un agent de Model Serving vers Databricks Apps.
Databricks recommande de migrer vers le schéma ResponsesAgent pour créer des agents. Consultez Créer un agent IA et le déployer sur Databricks Apps.
Les agents IA doivent adhérer à des exigences de schéma d'entrée et de sortie spécifiques pour être compatibles avec d'autres fonctionnalités sur Databricks. Cette page explique comment utiliser les signatures et les interfaces de création d'agents héritées : l'interface ChatAgent, l'interface ChatModel, le schéma d'entrée SplitChatMessageRequest et le schéma de sortie StringResponse.
Créez un agent ChatAgent hérité
L'interface MLflow ChatAgent est similaire, mais pas strictement compatible, au schéma OpenAI ChatCompletion.
Pour apprendre à créer un ChatAgent, consultez les exemples de la section suivante et la documentation MLflow - Qu'est-ce que l'interface ChatAgent.
Pour créer et déployer des agents à l'aide de ChatAgent, installez les éléments suivants :
databricks-agents0,16.0 ou supérieurmlflow2.20.2 ou supérieur- Python 3,10 ou version ultérieure.
- Pour répondre à cette exigence, vous pouvez utiliser le compute Serverless ou Databricks Runtime 13.3 LTS ou une version ultérieure.
%pip install -U -qqqq databricks-agents==0.16.0 mlflow==2.20.2
Et si vous avez déjà un agent ?
Si vous avez déjà un agent construit avec LangChain, LangGraph ou un framework similaire, vous n'avez pas besoin de réécrire votre agent pour l'utiliser sur Databricks. Au lieu de cela, enveloppez simplement votre agent existant avec l'interface ChatAgent MLflow :
-
Écrire une classe wrapper Python qui hérite de
mlflow.pyfunc.ChatAgent.Dans la classe wrapper, conservez votre agent existant en tant qu'attribut
self.agent = your_existing_agent. -
La classe
ChatAgentvous demande d'implémenter unepredictméthode pour gérer les requêtes non-streaming.predictdoit accepter :-
messages: list[ChatAgentMessage], qui est une liste deChatAgentMessagechacun avec un rôle (tel que « user » ou « assistant »), l'invite et un ID. -
(Facultatif)
context: Optional[ChatContext]etcustom_inputs: Optional[dict]pour des données supplémentaires.
Pythonimport uuid
# input example
[
ChatAgentMessage(
id=str(uuid.uuid4()), # Generate a unique ID for each message
role="user",
content="What's the weather in Paris?"
)
]predictdoit renvoyer unChatAgentResponse.Pythonimport uuid
# output example
ChatAgentResponse(
messages=[
ChatAgentMessage(
id=str(uuid.uuid4()), # Generate a unique ID for each message
role="assistant",
content="It's sunny in Paris."
)
]
) -
-
Convertir entre les formats
Dans
predict, convertissez les messages entrants delist[ChatAgentMessage]dans le format d'entrée attendu par votre agent.Une fois que votre agent a généré une réponse, convertissez sa sortie en un ou plusieurs objets
ChatAgentMessageet enveloppez-les dans unChatAgentResponse.
Convertir automatiquement la sortie LangChain
Si vous intégrez un agent LangChain, vous pouvez utiliser mlflow.langchain.output_parsers.ChatAgentOutputParser pour convertir automatiquement les sorties LangChain dans le schéma MLflow ChatAgentMessage et ChatAgentResponse.
Voici un Template simplifié pour convertir votre agent :
from mlflow.pyfunc import ChatAgent
from mlflow.types.agent import ChatAgentMessage, ChatAgentResponse, ChatAgentChunk
import uuid
class MyWrappedAgent(ChatAgent):
def __init__(self, agent):
self.agent = agent
def predict(self, messages, context=None, custom_inputs=None):
# Convert messages to your agent's format
agent_input = ... # build from messages
agent_output = self.agent.invoke(agent_input)
# Convert output to ChatAgentMessage
return ChatAgentResponse(
messages=[ChatAgentMessage(role="assistant", content=agent_output, id=str(uuid.uuid4()),)]
)
def predict_stream(self, messages, context=None, custom_inputs=None):
# If your agent supports streaming
for chunk in self.agent.stream(...):
yield ChatAgentChunk(delta=ChatAgentMessage(role="assistant", content=chunk, id=str(uuid.uuid4())))
Pour des exemples complets, consultez les notebooks dans la section suivante.
ChatAgent exemples
Les notebooks suivants montrent comment créer des ChatAgents en streaming et non en streaming à l'aide des bibliothèques populaires OpenAI, LangGraph et AutoGen.
- LangGraph
- OpenAI
- AutoGen
- DSPy
Si vous intégrez un agent LangChain, vous pouvez utiliser mlflow.langchain.output_parsers.ChatAgentOutputParser pour convertir automatiquement les sorties LangChain dans le schéma MLflow ChatAgentMessage et ChatAgentResponse.
Agent LangGraph d'appel d'outils
Agent d'appel d'outils OpenAI
Agent d'appel d'outils de l'OpenAI Responses API
Agent OpenAI uniquement de chat
Agent AutoGen d'appel d'outils
Agent DSPy de discussion uniquement
Pour apprendre à étendre les capacités de ces agents en ajoutant des outils, veuillez consulter Connecter des agents aux outils.
Réponses de streaming ChatAgent
Les agents de streaming fournissent des réponses dans un flux continu de blocs incrémentiels plus petits. Le streaming réduit la latence perçue et améliore l'expérience utilisateur des agents conversationnels.
Pour créer un ChatAgent streaming, définissez une méthode predict_stream qui renvoie un générateur qui produit des objets ChatAgentChunk – chaque ChatAgentChunk contient une partie de la réponse. En savoir plus sur le comportement de ChatAgent streaming idéal dans la documentation MLflow.
Le code suivant présente un exemple de fonction predict_stream, pour des exemples complets d'agents de streaming, consultez les exemples de ChatAgent:
def predict_stream(
self,
messages: list[ChatAgentMessage],
context: Optional[ChatContext] = None,
custom_inputs: Optional[dict[str, Any]] = None,
) -> Generator[ChatAgentChunk, None, None]:
# Convert messages to a format suitable for your agent
request = {"messages": self._convert_messages_to_dict(messages)}
# Stream the response from your agent
for event in self.agent.stream(request, stream_mode="updates"):
for node_data in event.values():
# Yield each chunk of the response
yield from (
ChatAgentChunk(**{"delta": msg}) for msg in node_data["messages"]
)
Créer un agent ChatModel hérité.
Databricks recommande l'interface ChatAgent pour créer des agents ou des applications d'IA générative. Pour migrer de ChatModel à ChatAgent, consultez la documentation MLflow : Migrer de ChatModel à ChatAgent.
ChatModel est une interface d'agent de création héritée dans MLflow qui étend le schéma ChatCompletion d'OpenAI, vous permettant de maintenir la compatibilité avec les plateformes prenant en charge la norme ChatCompletion tout en ajoutant des fonctionnalités personnalisées. Consultez MLflow : Pour commencer avec ChatModel pour en savoir plus.
La création de votre agent en tant que sous-classe de mlflow.pyfunc.ChatModel offre les avantages suivants :
-
Permet la sortie de l'agent en streaming lors de l'invocation d'un agent servi (en contournant
{stream: true}dans le corps de la requête). -
Active automatiquement les tables d'inférence de la passerelle IA lorsque votre agent est déployé, fournissant un accès à des métadonnées de logs de requêtes améliorées, telles que le nom du demandeur.
Les logs de requête et les logs d'évaluation sont obsolètes et seront supprimés dans une future version. Consultez la dépréciation des logs de requête et des logs d'évaluation pour obtenir des conseils de migration.
-
Vous permet d'écrire du code d'agent compatible avec le schéma ChatCompletion à l'aide de classes Python typées.
-
MLflow déduit automatiquement une signature compatible avec la complétion de chat lors de l'enregistrement de l'agent, même sans
input_example. Cela simplifie le processus d'enregistrement et de déploiement de l'agent. Consultez Inférer la signature du modèle lors de l'enregistrement.
Le code suivant est préférable d'exécuter dans un notebook Databricks. Les notebooks offrent un environnement pratique pour développer, tester et itérer sur votre agent.
La classe MyAgent étend mlflow.pyfunc.ChatModel, implémentant la méthode predict requise. Ceci garantit la compatibilité avec les agents personnalisés.
La classe inclut également les méthodes facultatives _create_chat_completion_chunk et predict_stream pour gérer les sorties de streaming.
# Install a pinned version of mlflow
%pip install -U mlflow==2.20.2
dbutils.library.restartPython()
import re
from typing import Optional, Dict, List, Generator
from mlflow.pyfunc import ChatModel
from mlflow.types.llm import (
# Non-streaming helper classes
ChatCompletionRequest,
ChatCompletionResponse,
ChatCompletionChunk,
ChatMessage,
ChatChoice,
ChatParams,
# Helper classes for streaming agent output
ChatChoiceDelta,
ChatChunkChoice,
)
class MyAgent(ChatModel):
"""
Defines a custom agent that processes ChatCompletionRequests
and returns ChatCompletionResponses.
"""
def predict(self, context, messages: list[ChatMessage], params: ChatParams) -> ChatCompletionResponse:
last_user_question_text = messages[-1].content
response_message = ChatMessage(
role="assistant",
content=(
f"I will always echo back your last question. Your last question was: {last_user_question_text}. "
)
)
return ChatCompletionResponse(
choices=[ChatChoice(message=response_message)]
)
def _create_chat_completion_chunk(self, content) -> ChatCompletionChunk:
"""Helper for constructing a ChatCompletionChunk instance for wrapping streaming agent output"""
return ChatCompletionChunk(
choices=[ChatChunkChoice(
delta=ChatChoiceDelta(
role="assistant",
content=content
)
)]
)
def predict_stream(
self, context, messages: List[ChatMessage], params: ChatParams
) -> Generator[ChatCompletionChunk, None, None]:
last_user_question_text = messages[-1].content
yield self._create_chat_completion_chunk(f"Echoing back your last question, word by word.")
for word in re.findall(r"\S+\s*", last_user_question_text):
yield self._create_chat_completion_chunk(word)
agent = MyAgent()
model_input = ChatCompletionRequest(
messages=[ChatMessage(role="user", content="What is Databricks?")]
)
response = agent.predict(context=None, messages=model_input.messages, params=None)
print(response)
Bien que vous définissiez la classe d'agent MyAgent dans un Notebook, nous vous recommandons de créer un Notebook de Driver distinct. Le Notebook Driver enregistre l'agent dans le Model Registry et déploie l'agent via le Model Serving.
Cette séparation suit le workflow recommandé par Databricks pour l'enregistrement des modèles en utilisant la méthodologie « Models from Code » de MLflow.
Schéma d'entrée SplitChatMessageRequest (obsolète)
SplitChatMessagesRequest vous permet de passer la query actuelle et l'historique séparément comme entrée de l'agent.
question = {
"query": "What is MLflow",
"history": [
{
"role": "user",
"content": "What is Retrieval-augmented Generation?"
},
{
"role": "assistant",
"content": "RAG is"
}
]
}
Schéma de sortie StringResponse (déprécié)
StringResponse vous permet de renvoyer la réponse de l'agent en tant qu'objet avec un champ content de chaîne unique :
{"content": "This is an example string response"}