Aller au contenu principal

Skills : encapsuler des capacités

Skills : encapsuler des capacites

Les Skills sont des unites de capacite reutilisables qui combinent instructions, outils et contexte dans un package autonome. Elles permettent de standardiser des comportements complexes et de les partager entre agents ou applications.

Le concept de Skill

Une Skill encapsule tout ce dont un modele a besoin pour accomplir une tache specifique :

  • Instructions : le prompt systeme specialise
  • Outils : les fonctions et outils built-in necessaires
  • Contexte : les donnees de reference et exemples
from openai import OpenAI

client = OpenAI()

# Definir une skill d'analyse financiere
skill_analyse_financiere = {
    "instructions": (
        "Tu es un analyste financier specialise en PME francaises. "
        "Tu analyses les documents comptables et produis des rapports "
        "structures avec indicateurs cles, tendances et recommandations. "
        "Utilise les normes comptables francaises (PCG). "
        "Formate les montants en euros avec separateurs de milliers."
    ),
    "tools": [
        {"type": "file_search", "vector_store_ids": ["vs_normes_comptables"]},
        {"type": "code_interpreter"}
    ]
}

# Utiliser la skill
response = client.responses.create(
    model="gpt-5.3",
    instructions=skill_analyse_financiere["instructions"],
    input=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Analyse ce bilan et produis un rapport"},
            {"type": "input_file", "file_id": fichier_bilan.id}
        ]
    }],
    tools=skill_analyse_financiere["tools"]
)

Structurer une bibliotheque de Skills

Organisez vos skills dans des modules reutilisables :

class Skill:
    def __init__(self, nom: str, instructions: str, tools: list, exemples: list = None):
        self.nom = nom
        self.instructions = instructions
        self.tools = tools
        self.exemples = exemples or []

    def executer(self, client: OpenAI, requete: str, fichiers: list = None) -> str:
        content = [{"type": "text", "text": requete}]
        if fichiers:
            for fid in fichiers:
                content.append({"type": "input_file", "file_id": fid})

        # Ajouter les exemples au contexte
        instructions = self.instructions
        if self.exemples:
            instructions += "\n\nExemples de reference :\n"
            for ex in self.exemples:
                instructions += f"- Entree : {ex['input']}\n  Sortie : {ex['output']}\n"

        response = client.responses.create(
            model="gpt-5.3",
            instructions=instructions,
            input=[{"role": "user", "content": content}],
            tools=self.tools
        )
        return response.output_text


# Definir les skills
skill_redaction_contrat = Skill(
    nom="redaction-contrat",
    instructions=(
        "Tu es un juriste specialise en droit des contrats. "
        "Tu rediges des clauses claires, precises et conformes au droit francais. "
        "Chaque clause doit etre numerotee et structuree."
    ),
    tools=[
        {"type": "file_search", "vector_store_ids": ["vs_modeles_contrats"]},
        {"type": "web_search_preview"}
    ],
    exemples=[
        {
            "input": "Clause de confidentialite pour un prestataire",
            "output": "Article X - Confidentialite\nX.1 Le Prestataire s'engage..."
        }
    ]
)

skill_support_technique = Skill(
    nom="support-technique",
    instructions=(
        "Tu es un agent de support technique niveau 2. "
        "Tu diagnostiques les problemes en posant des questions ciblees. "
        "Tu cherches d'abord dans la base de connaissances avant de proposer "
        "des solutions. Tu documentes chaque resolution."
    ),
    tools=[
        {"type": "file_search", "vector_store_ids": ["vs_base_connaissances"]},
        {
            "type": "function",
            "name": "creer_ticket_escalade",
            "description": "Escalader un probleme vers le niveau 3",
            "parameters": {
                "type": "object",
                "properties": {
                    "titre": {"type": "string"},
                    "description": {"type": "string"},
                    "priorite": {"type": "string", "enum": ["basse", "moyenne", "haute", "critique"]}
                },
                "required": ["titre", "description", "priorite"],
                "additionalProperties": false
            },
            "strict": true
        }
    ]
)

Composer des Skills

Combinez plusieurs skills pour des workflows complexes :

class SkillComposee:
    def __init__(self, nom: str, etapes: list[dict]):
        self.nom = nom
        self.etapes = etapes
        self.client = OpenAI()

    def executer(self, requete_initiale: str, fichiers: list = None) -> dict:
        contexte = requete_initiale
        resultats = {}

        for etape in self.etapes:
            skill = etape["skill"]
            instruction_etape = etape.get("instruction", "")
            prompt = f"{instruction_etape}\n\nContexte precedent : {contexte}"

            resultat = skill.executer(self.client, prompt, fichiers)
            resultats[etape["nom"]] = resultat
            contexte = resultat
            fichiers = None  # Fichiers utilises seulement a la premiere etape

        return resultats


# Workflow : analyse de contrat puis redaction de synthese
workflow_audit_contrat = SkillComposee(
    nom="audit-contrat",
    etapes=[
        {
            "nom": "analyse",
            "skill": skill_analyse_financiere,
            "instruction": "Analyse les aspects financiers de ce contrat"
        },
        {
            "nom": "juridique",
            "skill": skill_redaction_contrat,
            "instruction": "Identifie les risques juridiques et propose des ameliorations"
        }
    ]
)

Skills avec etat

Pour des skills qui accumulent du contexte entre appels :

class SkillAvecEtat:
    def __init__(self, skill: Skill):
        self.skill = skill
        self.client = OpenAI()
        self.historique = []
        self.contexte_accumule = ""

    def appeler(self, requete: str, fichiers: list = None) -> str:
        # Construire le prompt avec l'historique
        instructions = self.skill.instructions
        if self.contexte_accumule:
            instructions += f"\n\nContexte des interactions precedentes :\n{self.contexte_accumule}"

        content = [{"type": "text", "text": requete}]
        if fichiers:
            for fid in fichiers:
                content.append({"type": "input_file", "file_id": fid})

        response = self.client.responses.create(
            model="gpt-5.3",
            instructions=instructions,
            input=[{"role": "user", "content": content}],
            tools=self.skill.tools
        )

        resultat = response.output_text
        self.historique.append({"requete": requete, "reponse": resultat})
        self.contexte_accumule += f"\n- {requete} -> {resultat[:200]}..."

        return resultat

# Utilisation : support technique avec suivi de conversation
session = SkillAvecEtat(skill_support_technique)
r1 = session.appeler("Mon application plante au demarrage")
r2 = session.appeler("J'ai la version 3.2.1 sur Ubuntu 24.04")
r3 = session.appeler("Le log montre une erreur de connexion a la base de donnees")

Registre de Skills

Centralisez la gestion de vos skills :

class RegistreSkills:
    def __init__(self):
        self.skills = {}

    def enregistrer(self, skill: Skill):
        self.skills[skill.nom] = skill

    def obtenir(self, nom: str) -> Skill:
        if nom not in self.skills:
            raise KeyError(f"Skill '{nom}' non trouvee. "
                          f"Disponibles : {list(self.skills.keys())}")
        return self.skills[nom]

    def lister(self) -> list[str]:
        return list(self.skills.keys())

# Registre global
registre = RegistreSkills()
registre.enregistrer(skill_analyse_financiere_obj)
registre.enregistrer(skill_redaction_contrat)
registre.enregistrer(skill_support_technique)

# Utilisation
skill = registre.obtenir("support-technique")
resultat = skill.executer(client, "Mon imprimante ne fonctionne plus")

Points cles a retenir

  • Une Skill encapsule instructions, outils et contexte dans un package reutilisable
  • Composez des skills pour des workflows multi-etapes
  • Utilisez un etat pour les skills conversationnelles
  • Centralisez vos skills dans un registre pour faciliter la decouverte
  • Les exemples dans les instructions ameliorent la precision du modele