ChatGPT – Outils & Intégrations
API & assistants OpenAI, RAG/LangChain, automatisations devops, et intégrations IDE.
Plugins & API OpenAI : Chat API, tools/function calling, assistants
Deux voies d’intégration principales : Chat API (prompt → réponse, avec function calling) et Assistants (thread + outils managés : code intérprète, retrieval, fichiers, etc.).
🔑 Sécurité & config
- Stocker
OPENAI_API_KEYen variable d’environnement (jamais dans le code/source). - Fixer les modèles et limites (max tokens) côté serveur ; activer des quotas.
- Mettre un retry/backoff (429, timeouts), et un timeout global (ex. 30s).
🐍 Python — appel simple + function calling
import os, time
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# Tool schema (function) que le modèle peut appeler
tools = [{
"type":"function",
"function":{
"name":"search_articles",
"description":"Recherche d'articles",
"parameters":{"type":"object","properties":{"q":{"type":"string"}},"required":["q"]}
}
}]
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role":"user","content":"Trouve des articles sur RAG et résume."}],
tools=tools,
temperature=0.2
)
# Détecter un appel d'outil
tool_calls = resp.choices[0].message.tool_calls or []
for call in tool_calls:
if call.function.name == "search_articles":
query = json.loads(call.function.arguments)["q"]
# ... appeler votre moteur de recherche interne ...
results = [{"title":"Paper RAG", "url":"..."}]
# renvoyer au modèle comme 'tool' message :
tool_message = {"role":"tool","tool_call_id":call.id,"content":json.dumps(results)}
final = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role":"user","content":"Trouve des articles sur RAG et résume."},
resp.choices[0].message,
tool_message
],
temperature=0.2
)
print(final.choices[0].message.content)🕸️ JS/Node — streaming (SSE)
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const stream = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Donne un plan en 5 puces." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices?.[0]?.delta?.content || "");
}🧰 Assistants — Thread + fichiers + code interpreter
- Créer un assistant (rôle, instructions, outils autorisés).
- Ouvrir un thread (messages), y attacher des fichiers (contextes).
- Lancer un run, puis poll jusqu’à completion ; récupérer les sorties.
# (pseudo-code Python) assistant orienté "data analysis"
assistant = client.beta.assistants.create(
name="Analyste",
instructions="Analyse des CSV, rendre un rapport synthétique.",
tools=[{"type":"code_interpreter"}],
model="gpt-4o-mini"
)
thread = client.beta.threads.create()
# client.files.create(...); client.beta.threads.messages.create(thread_id=..., file_ids=[...])
run = client.beta.threads.runs.create(thread_id=thread.id, assistant_id=assistant.id)
# ... poll run.status jusqu'à "completed" puis lire messages du thread📏 Coûts & métriques (à logguer)
- Tokens prompt / completion ; latence par requête ; erreurs (429, 5xx) ; taux de tool-calls.
- Traçage par feature → tableau de bord (Prometheus/Grafana ou Sentry/Datadog).
LangChain & RAG : indexation, retrieval, évaluation
Un RAG = ingestion (chunking + embeddings) → stockage (vector store) → retrieval (top-k) → génération avec citations → évaluation.
🏗️ Pipeline
- Split : découper docs (500–1000 tokens, overlap 50–150).
- Embed avec un modèle d’embeddings adapté.
- Store : FAISS/Chroma/PGVector/Weaviate/Elastic KNN…
- Retrieve : top-k + reranking éventuel.
- Generate : prompt avec citations des chunks.
- Eval : LLM-as-judge + tests sur un jeu d’oracles.
🐍 LangChain (Python) — mini RAG
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import RetrievalQA
docs = ["Doc A ...", "Doc B ..."]
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)
chunks = splitter.create_documents(docs)
emb = OpenAIEmbeddings() # utilise OPENAI_API_KEY
vs = FAISS.from_documents(chunks, emb)
retriever = vs.as_retriever(search_kwargs={"k": 4})
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.2)
chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever, return_source_documents=True)
res = chain.invoke({"query": "Résume Doc A et cite tes sources"})
print(res["result"])
for s in res["source_documents"]:
print("•", s.metadata.get("source", "chunk"))🛡️ Sécurité RAG
- Prompt-injection : nettoyer HTML/JS, supprimer instructions hostiles, deny-list d’actions.
- Traçabilité : stocker doc_id/chunk_id pour chaque réponse.
- Évaluations : exact match / citation coverage / groundedness.
📦 Variantes utiles
- HyDE (générer une hypothèse de réponse puis la rechercher) pour requêtes difficiles.
- Re-ranking par un modèle cross-encoder pour améliorer la pertinence.
Automatisations : cron, CI/CD, scripts internes robustes
Industrialiser les tâches IA : **jobs planifiés**, **pipelines CI/CD**, **scripts** avec retries, idempotence, et observabilité.
🐍 Script Python — résumé quotidien (robuste)
import os, time, logging
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
logging.basicConfig(level=logging.INFO)
def backoff(i): return min(60, 2 ** i)
def summarize(text):
for i in range(6):
try:
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role":"user","content":f"Résume en 5 puces :\n{text}"}],
temperature=0.3, timeout=30
)
return r.choices[0].message.content
except Exception as e:
logging.warning("retry %s: %s", i, e); time.sleep(backoff(i))
raise RuntimeError("too many retries")
if __name__ == "__main__":
text = open("/data/logs/today.txt","r",encoding="utf-8").read()
print(summarize(text))⏰ Cron
# Tous les jours à 7h
0 7 * * * /venv/bin/python /app/tools/summarize.py >> /var/log/ai.log 2>&1🚀 CI/CD — GitHub Actions (lint + tests + build)
name: CI
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.11" }
- run: pip install -r requirements.txt
- run: ruff check && ruff format --check
- run: pytest -q
build-web:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build📊 Observabilité
- Logguer latence, tokens, erreurs, coût par feature.
- Exporter des métriques (Prometheus) et des traces (OpenTelemetry).
Extensions IDE : VSCode & JetBrains (flux de travail)
Intégrer l’IA **dans l’éditeur** fluidifie la boucle : lire → demander → appliquer → tester.
🧩 VSCode — extensions utiles
- Continue / CodeGPT / GPT Pilot* : chat in-editor, actions sur sélection, génération de tests.
- REST Client / Thunder Client : tester rapidement vos endpoints IA.
- GitLens : revue de diff, blame — pour auditer le code généré.
🧠 Workflows efficaces
- Sélectionner un bloc → “Explique/Refactor/Teste ce code”.
- Commandes de snippets : patrons de view Django, composants React, tests pytest/RTL.
- Raccourcis : ouvrir un panel IA, coller le State Pack, exécuter les contrôles.
🛡️ Bonnes pratiques IDE
- Masquer les secrets via
.env+ extensions d’env inject. - Activer les linters/formatters “on save” pour capter les erreurs tôt.
- Ne jamais appliquer un patch IA sans lire le diff et lancer les tests.
