Accueil / Articles / Notes pratiques : Un agent de support local avec SmolLM3 : Mode réflexion, outils et

Notes pratiques : Un agent de support local avec SmolLM3 : Mode réflexion, outils et

Guide opérationnel des notes pratiques : Un agent de support local avec SmolLM3 – Mode réflexion, outils, ainsi que contrats, vérifications et emplacements pour du code intégrable destinés aux équipes utilisant ce modèle.

1641 mots

Utilisez ceci comme une version révisée destinée aux opérateurs des idées présentées dans « Un agent de support local avec SmolLM3 : mode réflexion, outils et moments où ne pas raisonner » : étapes claires, emplacements de code ordonnés, ainsi que des notes de récupération permettant de poursuivre le travail en cas de transfert. L’étape « Aperçu » fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement exemplaire, un cas d’échec et la note de réversion avant d’élargir le périmètre. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Nommez les artefacts, définez des critères de succès, et refusez toute complétion partielle silencieuse.

La configuration

Pendant l’étape de configuration, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des jetons ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés. Préférez des sorties structurées avec validation de schéma plutôt que du texte libre lorsque l’étape suivante consiste en du code ou une appel à outil.

Choisir entre Think et no_think relève d’une décision de produit

Pour une phase de type « penser ou ne pas penser », il convient de définir les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu, sans avoir à deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Préférez des sorties structurées avec validation de schéma plutôt que du texte libre lorsque l’étape suivante consiste en du code ou une appel à outil.

messages = [
    {"role": "system", "content": "/no_think"},
    {"role": "user", "content": prompt},
]
tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True,
    enable_thinking=False,  # the /no_think flag in the system prompt wins if both are set
)
<|im_start|>assistant
<think>

</think>
final = re.sub(r"<think>.*?</think>", "", raw, flags=re.DOTALL).strip()
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>
TOOLS = [
    {
        "name": "lookup_order_status",
        "description": (
            "Look up the current status, estimated delivery date, and carrier "
            "for a specific customer order. Call this when the customer mentions "
            "an order number or asks where their order is."
        ),
        "parameters": {
            "type": "object",
            "properties": {
                "order_id": {
                    "type": "string",
                    "description": "The order ID, usually in the format ORD-XXXXXX.",
                }
            },
            "required": ["order_id"],
        },
    }
]
ORDERS = {
    "ORD-4821": {"status": "shipped", "eta": "June 18, 2026", "carrier": "DHL"},
    "ORD-3307": {"status": "processing", "eta": "June 20, 2026", "carrier": None},
    "ORD-1190": {"status": "delivered", "eta": None, "carrier": "FedEx"},
}
def respond_with_tools(user_message: str) -> str:
    messages = [{"role": "user", "content": user_message}]
    turn1 = generate_reply(messages)
    name, args = parse_tool_call(turn1)
    if name == "lookup_order_status":
        result = lookup_order_status(**args)
        messages += [
            {"role": "assistant", "content": turn1},
            {"role": "tool", "content": json.dumps(result), "name": name},
        ]
        return generate_reply(messages)
    return turn1
<tool_call>
{"name": "lookup_order_status", "arguments": {"order_id": "ORD-4821"}}
</tool_call>

C’est avec le ticket par e-mail que la boucle naïve échoue

Pour cette étape liée aux tickets par e-mail, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez conjointement le parcours idéal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Préférez des sorties structurées avec validation de schéma plutôt que du texte libre lorsque l’étape suivante consiste en du code ou une appel à outil. Pour cette étape liée aux tickets par e-mail, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définites des vérifications de succès et refusez les terminations partielles silencieuses.

<tool_call>
{"name": "lookup_order_status", "arguments": {"order_id": "your_order_id"}}
</tool_call>

Gardiens qui ne subissent pas de fine-tuning

Lorsque vous travaillez sur les gardiens qui ne sont pas en phase de développement, notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le chemin passe de l’environnement de démonstration à des environnements partagés. Mémorisez les instructions du système stables ainsi que les schémas des outils. Envoyer à nouveau un préambule identique est une cause fréquente de gaspillage.

ORDER_RE = re.compile(r"^ORD-\d{4,}quot;)
PURE_TOOL_RE = re.compile(r"^\s*<tool_call>(.*?)</tool_call>\s*quot;, re.DOTALL)

def parse_executable_tool_call(output: str):
    cleaned = re.sub(r"<think>.*?</think>", "", output, flags=re.DOTALL).strip()
    match = PURE_TOOL_RE.match(cleaned)
    if not match:
        return None
    payload = json.loads(match.group(1).strip())
    order_id = str(payload.get("arguments", {}).get("order_id", "")).strip()
    if not ORDER_RE.match(order_id):
        return None
    return payload

Ce que cela ne prouve pas

Lorsque vous travaillez sur la section « Ce que cela ne prend pas en charge », notez d’abord les exigences : entrées requises, signal de succès, et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les administrateurs peuvent auditer sans devoir lire l’ensemble du système. Mémorisez les instructions stables du système ainsi que les schémas des outils. Envoyer à nouveau un préambule identique est une cause fréquente de gaspillage.

Lancez-le

Lors de l’étape « Exécuter », notez d’abord les conditions du contrat : entrées requises, signal de succès et comportement en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Documentez à la fois le parcours normal et les scénarios de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non traités font partie intégrante du produit, et non d’améliorations ultérieures. Mémorisez les instructions système stables ainsi que les schémas des outils. Envoyer à nouveau un préambule identique est une cause fréquente de gaspillage. Lors de l’étape « Exécuter », notez d’abord les conditions du contrat : entrées requises, signal de succès et comportement en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définites des critères de succès et refusez les terminations partielles silencieuses.

python llm-learning/smollm3-local-support-agent/code/think_vs_nothink.py
python llm-learning/smollm3-local-support-agent/code/support_agent.py
python llm-learning/smollm3-local-support-agent/code/support_agent_guarded.py

Liste de contrôle opérationnelle

Lors de l’étape du tableau de contrôle opérationnel, notez d’abord les éléments requis par le contrat : les données nécessaires, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Ce tableau permet de garantir l’honnêteté des modifications ultérieures du code.

Préférez des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’erreur doit indiquer une seule responsabilité et non un processus embrouillé.

Mémorisez les instructions du système stables ainsi que les schémas des outils. Envoyer à nouveau un préambule identique est une cause fréquente de problèmes.

Exposez les outils ayant des schémas restreints et des étiquettes explicites indiquant leurs effets secondaires. Les hôtes doivent savoir quels appels modifient l’état avant d’approuver automatiquement.

Imposez une approbation humaine pour les opérations qui entraînent des dépenses ou modifient des données en production. La connexion en temps de compilation ne garantit pas la complétude du processus métier.

Rédigez un petit manuel d’utilisation : comment rotationner les clés, comment vider la file d’attente, comment annuler la dernière ingestion.

Au préalable de promouvoir l’ensemble technique, figez les versions, conservez une transcription parfaite pour le chemin critique, et confirmez les étapes de rollback. Les environnements partagés nécessitent des limites de débit, des vérifications d’attribution, ainsi qu’un responsable clair pour la rotation des secrets. Préférez une fiabilité banale à des démonstrations ingénieuses ponctuelles.

Note de lot pour 0e44ad944ff5 : gardez les clés du fournisseur hors du répertoire, fixez un plafond pour les tokens par session, et stockez les transcriptions à côté des fichiers de configuration d’évaluation afin que les remplacements ultérieurs de modèles restent comparables.

Lorsque vous travaillez sur la note de renforcement au stade 0, écrivez d’abord le contrat : entrées requises, signal de succès, et ce qui se passe en cas d’échec partiel. Cette liste de contrôle garantit l’honnêteté des modifications ultérieures du code. Documentez à la fois le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une finition ultérieure.

Détail de renforcement 0/868 : mesurez le temps d’exécution, la classe d’erreur et la consommation de tokens pour cette note, puis décidez si vous souhaitez conserver le changement en vous basant sur un ensemble de questions prédéfini plutôt que sur des anecdotes.

La première étape du renforcement fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Recueillez un enregistrement exemplaire, un cas d’échec et la note de réversion avant d’élargir le périmètre. Traitez cette étape comme un contrat entre les entrées et les sorties validées. Nommez les artefacts, définites des critères de succès et refusez toute complétion partielle silencieuse.

Détail de renforcement 1/868 : mesurez le temps d’exécution, la classe d’erreur et la consommation de tokens pour cette note, puis décidez si vous souhaitez conserver le changement en vous basant sur un ensemble de questions prédéfini plutôt que sur des anecdotes.

Pour la deuxième étape de l’amélioration de sécurité, définissez les entrées, le responsable de l’étape et les critères d’achèvement avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système.

Détail 2/868 de l’amélioration de sécurité : mesurez le temps d’exécution, la catégorie d’erreur et l’utilisation des tokens pour cette étape, puis décidez s’il convient de conserver la modification en vous basant sur un ensemble prédéfini de critères plutôt que sur des observations subjectives.

Lors de la réalisation de l’étape 3 des notes de renforcement de sécurité, notez d’abord les éléments essentiels : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Préférez des unités petites et testables à des scripts complexes. Lorsqu’une étape échoue, l’erreur doit indiquer une responsabilité précise plutôt qu’un processus embrouillé.

Détail de renforcement 3/868 : mesurez le temps d’exécution, la catégorie de l’erreur et la consommation de tokens pour cette note, puis décidez si vous souhaitez conserver la modification en vous basant sur un ensemble de critères prédéfinis plutôt que sur des observations subjectives.