Construire des agents IA avec Google ADK et TypeScript

Prérequis
Avant de commencer, assurez-vous de disposer de :
- Node.js 20+ installé sur votre machine
- TypeScript 5.x installé globalement
- Un compte Google Cloud avec Gemini API activé
- Une clé API depuis Google AI Studio
- Des connaissances de base en TypeScript et Node.js
- Un éditeur de code comme VS Code
Ce que vous allez construire
Dans ce guide, vous allez créer un système complet d'agents IA comprenant :
- Agent de recherche — recherche sur le web et synthétise les résultats
- Agent d'analyse — traite les données et génère des rapports
- Agent coordinateur — orchestre plusieurs agents pour les tâches complexes
Nous utiliserons Google Agent Development Kit (ADK) — le nouveau framework de Google pour construire des agents IA évolutifs et prêts pour la production.
Qu'est-ce que Google ADK ?
Google Agent Development Kit (ADK) est un framework open-source de Google conçu pour simplifier la création d'agents IA. Ses caractéristiques principales :
- Intégration native avec Gemini — fonctionne parfaitement avec les modèles Gemini 2.x
- Système d'outils flexible — ajoutez facilement des outils personnalisés
- Gestion de mémoire intégrée — sauvegardez et récupérez le contexte entre les conversations
- Support multi-agents — construisez des systèmes d'agents collaboratifs
- Architecture évolutive — du prototype à la production
Étape 1 : Configuration du projet
Commencez par créer un nouveau projet TypeScript et installer les dépendances :
mkdir google-adk-agents
cd google-adk-agents
npm init -yInstallez les packages nécessaires :
npm install @google/adk @google/generative-ai zod dotenv
npm install -D typescript @types/node tsxCréez la configuration TypeScript :
npx tsc --initModifiez tsconfig.json :
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"sourceMap": true
},
"include": ["src/**/*"]
}Créez la structure du projet :
mkdir -p src/{agents,tools,config}
touch src/index.ts src/config/env.tsÉtape 2 : Configuration des variables d'environnement
Créez un fichier .env à la racine du projet :
GOOGLE_API_KEY=your_gemini_api_key_here
GOOGLE_CLOUD_PROJECT=your_project_id
ADK_LOG_LEVEL=infoPuis créez src/config/env.ts :
import dotenv from "dotenv";
import { z } from "zod";
dotenv.config();
const envSchema = z.object({
GOOGLE_API_KEY: z.string().min(1, "Google API key is required"),
GOOGLE_CLOUD_PROJECT: z.string().optional(),
ADK_LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
});
export const env = envSchema.parse(process.env);Nous utilisons Zod pour valider les variables d'environnement au démarrage, évitant ainsi les erreurs à l'exécution.
Étape 3 : Création des outils personnalisés
Les outils sont le moyen par lequel les agents interagissent avec le monde extérieur. Nous allons créer deux outils :
Outil de recherche web
Créez src/tools/search-tool.ts :
import { Tool, ToolContext } from "@google/adk";
import { z } from "zod";
const searchInputSchema = z.object({
query: z.string().describe("The search query to look up"),
maxResults: z.number().default(5).describe("Maximum number of results"),
});
export const webSearchTool = new Tool({
name: "web_search",
description:
"Search the web for current information on any topic. " +
"Use this when you need up-to-date facts, news, or data.",
inputSchema: searchInputSchema,
async execute(input: z.infer<typeof searchInputSchema>, context: ToolContext) {
const { query, maxResults } = input;
// En production, remplacez par une vraie API de recherche
const response = await fetch(
`https://api.search-provider.com/search?q=${encodeURIComponent(query)}&num=${maxResults}`,
{
headers: {
Authorization: `Bearer ${process.env.SEARCH_API_KEY}`,
},
}
);
if (!response.ok) {
return {
error: `Search failed with status ${response.status}`,
results: [],
};
}
const data = await response.json();
return {
query,
results: data.results.map((r: any) => ({
title: r.title,
url: r.url,
snippet: r.snippet,
})),
totalResults: data.totalResults,
};
},
});Outil d'analyse de données
Créez src/tools/analysis-tool.ts :
import { Tool } from "@google/adk";
import { z } from "zod";
const analysisInputSchema = z.object({
data: z.string().describe("The data to analyze (JSON string or text)"),
analysisType: z
.enum(["summary", "trends", "comparison", "sentiment"])
.describe("Type of analysis to perform"),
});
export const dataAnalysisTool = new Tool({
name: "analyze_data",
description:
"Analyze data to extract insights, trends, and patterns. " +
"Supports summary, trend analysis, comparison, and sentiment analysis.",
inputSchema: analysisInputSchema,
async execute(input: z.infer<typeof analysisInputSchema>) {
const { data, analysisType } = input;
let parsedData: any;
try {
parsedData = JSON.parse(data);
} catch {
parsedData = data;
}
switch (analysisType) {
case "summary":
return {
type: "summary",
dataPoints: Array.isArray(parsedData) ? parsedData.length : 1,
summary: `Analyzed ${typeof parsedData === "object" ? Object.keys(parsedData).length : 1} data dimensions`,
timestamp: new Date().toISOString(),
};
case "trends":
return {
type: "trends",
direction: "upward",
confidence: 0.85,
periods: Array.isArray(parsedData) ? parsedData.length : 0,
timestamp: new Date().toISOString(),
};
case "sentiment":
return {
type: "sentiment",
overall: "positive",
score: 0.72,
breakdown: {
positive: 0.72,
neutral: 0.2,
negative: 0.08,
},
};
default:
return {
type: analysisType,
result: "Analysis complete",
data: parsedData,
};
}
},
});Étape 4 : Construction de l'agent de recherche
Créons maintenant le premier agent — un agent de recherche utilisant l'outil web search.
Créez src/agents/search-agent.ts :
import { Agent, AgentConfig } from "@google/adk";
import { webSearchTool } from "../tools/search-tool";
const searchAgentConfig: AgentConfig = {
name: "search_agent",
model: "gemini-2.5-flash",
description:
"A specialized agent for searching the web and summarizing findings. " +
"Excels at finding current information and presenting it clearly.",
instruction: `You are a research assistant specialized in web search.
Your responsibilities:
1. Search for information using the web_search tool
2. Synthesize results from multiple searches
3. Present findings in a clear, structured format
4. Always cite your sources with URLs
Guidelines:
- Perform multiple searches to verify information
- Prioritize recent and authoritative sources
- If you cannot find reliable information, say so clearly
- Respond in the same language as the user's query`,
tools: [webSearchTool],
generationConfig: {
temperature: 0.3,
maxOutputTokens: 2048,
},
};
export const searchAgent = new Agent(searchAgentConfig);Étape 5 : Construction de l'agent d'analyse
Créez src/agents/analysis-agent.ts :
import { Agent, AgentConfig } from "@google/adk";
import { dataAnalysisTool } from "../tools/analysis-tool";
const analysisAgentConfig: AgentConfig = {
name: "analysis_agent",
model: "gemini-2.5-pro",
description:
"An expert data analyst that processes information and generates insights.",
instruction: `You are a data analysis expert.
Your responsibilities:
1. Analyze data provided to you using the analyze_data tool
2. Identify patterns, trends, and anomalies
3. Generate clear reports with actionable insights
4. Create visualization descriptions when helpful
Guidelines:
- Always explain your methodology
- Quantify findings when possible
- Highlight key takeaways prominently
- Flag any data quality issues you notice
- Respond in the same language as the user's query`,
tools: [dataAnalysisTool],
generationConfig: {
temperature: 0.2,
maxOutputTokens: 4096,
},
};
export const analysisAgent = new Agent(analysisAgentConfig);Étape 6 : Construction du coordinateur (Multi-Agent)
Voici la partie la plus importante — l'agent coordinateur qui gère les autres agents.
Créez src/agents/coordinator-agent.ts :
import { Agent, AgentConfig, AgentTool } from "@google/adk";
import { searchAgent } from "./search-agent";
import { analysisAgent } from "./analysis-agent";
const searchAgentTool = new AgentTool({
agent: searchAgent,
name: "research",
description:
"Delegate research tasks to the search agent. " +
"Use this for finding current information from the web.",
});
const analysisAgentTool = new AgentTool({
agent: analysisAgent,
name: "analyze",
description:
"Delegate analysis tasks to the analysis agent. " +
"Use this for processing data and generating insights.",
});
const coordinatorConfig: AgentConfig = {
name: "coordinator",
model: "gemini-2.5-pro",
description:
"The main coordinator that orchestrates research and analysis tasks.",
instruction: `You are an AI coordinator managing a team of specialized agents.
Your team:
1. **Research Agent** - Use the "research" tool for web searches
2. **Analysis Agent** - Use the "analyze" tool for data processing
Workflow:
1. Understand the user's request
2. Break it into sub-tasks
3. Delegate to the appropriate agent(s)
4. Synthesize the results into a coherent response
Guidelines:
- Clearly explain your plan before executing
- Use both agents when the task requires research AND analysis
- Provide a unified, well-structured final response
- Handle errors gracefully and try alternative approaches
- Respond in the same language as the user's query`,
tools: [searchAgentTool, analysisAgentTool],
generationConfig: {
temperature: 0.4,
maxOutputTokens: 8192,
},
};
export const coordinatorAgent = new Agent(coordinatorConfig);Étape 7 : Ajout de la gestion de mémoire
Google ADK fournit un système de mémoire intégré pour maintenir le contexte entre les conversations.
Créez src/config/memory.ts :
import { MemoryService, InMemoryStore, Session } from "@google/adk";
const memoryStore = new InMemoryStore();
export const memoryService = new MemoryService({
store: memoryStore,
searchConfig: {
maxResults: 10,
similarityThreshold: 0.7,
},
});
export async function createSession(userId: string): Promise<Session> {
return memoryService.createSession({
userId,
metadata: {
createdAt: new Date().toISOString(),
source: "tutorial-app",
},
});
}
export async function getOrCreateSession(userId: string): Promise<Session> {
const existingSessions = await memoryService.listSessions({ userId });
if (existingSessions.length > 0) {
return existingSessions[0];
}
return createSession(userId);
}Étape 8 : Construction de l'application principale
Maintenant, assemblons le tout.
Créez src/index.ts :
import { Runner } from "@google/adk";
import { coordinatorAgent } from "./agents/coordinator-agent";
import { getOrCreateSession, memoryService } from "./config/memory";
import { env } from "./config/env";
import * as readline from "readline";
async function main() {
console.log("🤖 Starting AI Agent System...");
console.log(`📋 Log level: ${env.ADK_LOG_LEVEL}`);
const runner = new Runner({
agent: coordinatorAgent,
appName: "ai-research-assistant",
memoryService,
});
const userId = "demo-user";
const session = await getOrCreateSession(userId);
console.log(`📍 Session: ${session.id}`);
console.log("✅ System ready! Type your questions below.\n");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const askQuestion = () => {
rl.question("You: ", async (input) => {
const trimmed = input.trim();
if (trimmed.toLowerCase() === "exit") {
console.log("👋 Goodbye!");
rl.close();
process.exit(0);
}
if (!trimmed) {
askQuestion();
return;
}
try {
console.log("\n🔄 Processing...\n");
const response = await runner.run({
userId,
sessionId: session.id,
newMessage: {
role: "user",
parts: [{ text: trimmed }],
},
});
for (const event of response) {
if (event.content?.parts) {
for (const part of event.content.parts) {
if (part.text) {
console.log(`Agent: ${part.text}\n`);
}
}
}
}
} catch (error) {
console.error("❌ Error:", error);
}
askQuestion();
});
};
askQuestion();
}
main().catch(console.error);Étape 9 : Ajout de la gestion d'erreurs et du monitoring
Créez src/config/logging.ts pour suivre les performances des agents :
import { CallbackHandler, AgentEvent } from "@google/adk";
export class AgentLogger implements CallbackHandler {
private startTimes = new Map<string, number>();
onAgentStart(event: AgentEvent): void {
const agentName = event.agentName;
this.startTimes.set(agentName, Date.now());
console.log(`[${this.timestamp()}] ▶️ Agent "${agentName}" started`);
}
onAgentEnd(event: AgentEvent): void {
const agentName = event.agentName;
const startTime = this.startTimes.get(agentName);
const duration = startTime ? Date.now() - startTime : 0;
console.log(
`[${this.timestamp()}] ✅ Agent "${agentName}" completed in ${duration}ms`
);
this.startTimes.delete(agentName);
}
onToolCall(event: AgentEvent): void {
console.log(
`[${this.timestamp()}] 🔧 Tool "${event.toolName}" called by "${event.agentName}"`
);
}
onError(event: AgentEvent): void {
console.error(
`[${this.timestamp()}] ❌ Error in "${event.agentName}":`,
event.error
);
}
private timestamp(): string {
return new Date().toISOString().split("T")[1].split(".")[0];
}
}Étape 10 : Ajout d'une API HTTP
Rendons le système d'agents accessible via HTTP.
Créez src/server.ts :
import { createServer, IncomingMessage, ServerResponse } from "http";
import { Runner } from "@google/adk";
import { coordinatorAgent } from "./agents/coordinator-agent";
import { getOrCreateSession, memoryService } from "./config/memory";
import { AgentLogger } from "./config/logging";
const runner = new Runner({
agent: coordinatorAgent,
appName: "ai-research-assistant",
memoryService,
callbacks: [new AgentLogger()],
});
async function handleChat(req: IncomingMessage, res: ServerResponse) {
const chunks: Buffer[] = [];
for await (const chunk of req) {
chunks.push(chunk as Buffer);
}
const body = JSON.parse(Buffer.concat(chunks).toString());
const { userId, message } = body;
if (!userId || !message) {
res.writeHead(400, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: "userId and message are required" }));
return;
}
const session = await getOrCreateSession(userId);
const response = await runner.run({
userId,
sessionId: session.id,
newMessage: {
role: "user",
parts: [{ text: message }],
},
});
const parts: string[] = [];
for (const event of response) {
if (event.content?.parts) {
for (const part of event.content.parts) {
if (part.text) {
parts.push(part.text);
}
}
}
}
res.writeHead(200, { "Content-Type": "application/json" });
res.end(
JSON.stringify({
sessionId: session.id,
response: parts.join("\n"),
})
);
}
const server = createServer(async (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
if (req.method === "OPTIONS") {
res.writeHead(204);
res.end();
return;
}
if (req.method === "POST" && req.url === "/chat") {
await handleChat(req, res);
return;
}
res.writeHead(404, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: "Not found" }));
});
const PORT = process.env.PORT || 3001;
server.listen(PORT, () => {
console.log(`🚀 Agent API server running on http://localhost:${PORT}`);
console.log(`📡 POST /chat - Send messages to the agent`);
});Étape 11 : Exécution et test
Ajoutez les scripts d'exécution dans package.json :
{
"scripts": {
"dev": "tsx src/index.ts",
"server": "tsx src/server.ts",
"build": "tsc",
"start": "node dist/index.js"
}
}Mode interactif
npm run devLe message de bienvenue apparaît et vous pouvez commencer à interagir :
🤖 Starting AI Agent System...
📋 Log level: info
📍 Session: session_abc123
✅ System ready! Type your questions below.
You: Quels sont les derniers développements en IA ?
Mode serveur API
npm run serverTestez avec curl :
curl -X POST http://localhost:3001/chat \
-H "Content-Type: application/json" \
-d '{
"userId": "user-1",
"message": "Recherche les dernières actualités Google AI et analyse les tendances"
}'Étape 12 : Ajout d'un outil de stockage
Ajoutons un outil pour persister les résultats de recherche :
// src/tools/storage-tool.ts
import { Tool } from "@google/adk";
import { z } from "zod";
const storage = new Map<string, any>();
const saveInputSchema = z.object({
key: z.string().describe("Unique key for the data"),
data: z.any().describe("Data to store"),
tags: z.array(z.string()).optional().describe("Tags for categorization"),
});
export const storageSaveTool = new Tool({
name: "save_data",
description: "Save research results or analysis data for later retrieval.",
inputSchema: saveInputSchema,
async execute(input: z.infer<typeof saveInputSchema>) {
const entry = {
...input,
savedAt: new Date().toISOString(),
};
storage.set(input.key, entry);
return { success: true, key: input.key, message: "Data saved successfully" };
},
});
const retrieveInputSchema = z.object({
key: z.string().describe("Key of the data to retrieve"),
});
export const storageRetrieveTool = new Tool({
name: "retrieve_data",
description: "Retrieve previously saved research or analysis data.",
inputSchema: retrieveInputSchema,
async execute(input: z.infer<typeof retrieveInputSchema>) {
const data = storage.get(input.key);
if (!data) {
return { found: false, message: `No data found for key: ${input.key}` };
}
return { found: true, data };
},
});Dépannage
Clé API invalide
Error: API key not valid. Please pass a valid API key.
Solution : Vérifiez que GOOGLE_API_KEY est correctement définie dans votre fichier .env et que la clé est active dans Google AI Studio.
Limite de requêtes dépassée
Error: 429 Resource has been exhausted
Solution : Ajoutez des délais entre les requêtes ou augmentez votre quota dans Google Cloud Console.
Modèle non disponible
Error: Model gemini-2.5-pro is not available
Solution : Vérifiez que le modèle demandé est disponible dans votre région. Vous pouvez utiliser gemini-2.5-flash comme alternative.
Performances lentes
Si les réponses sont lentes :
- Utilisez
gemini-2.5-flashau lieu depropour les tâches simples - Réduisez
maxOutputTokensselon les besoins - Activez le streaming avec
runner.runStreaming()pour les réponses longues
Bonnes pratiques
1. Conception des outils
// ✅ Bien : outil spécifique et ciblé
const weatherTool = new Tool({
name: "get_weather",
description: "Get current weather for a specific city",
});
// ❌ Mauvais : outil trop générique
const doAnythingTool = new Tool({
name: "do_anything",
description: "Does everything",
});2. Instructions claires
// ✅ Bien : instructions spécifiques avec exemples
instruction: `You are a financial analyst.
When asked about stocks, always include:
- Current price
- 30-day trend
- Key metrics (P/E, Market Cap)
Format as a structured table.`
// ❌ Mauvais : instructions vagues
instruction: `Help with financial stuff.`3. Gestion des erreurs
// ✅ Gérez les erreurs explicitement
async execute(input) {
try {
const result = await externalAPI.call(input);
return { success: true, data: result };
} catch (error) {
return {
success: false,
error: error.message,
suggestion: "Try with different parameters"
};
}
}Prochaines étapes
Après avoir terminé ce guide, vous pouvez :
- Ajouter plus d'outils — connectez vos agents à de vraies bases de données, APIs externes ou services cloud
- Utiliser Vertex AI — déployez vos agents sur Google Cloud avec Vertex AI Agent Builder
- Construire une interface — créez une interface React/Next.js pour interagir avec vos agents
- Activer le streaming — utilisez
runner.runStreaming()pour des réponses en temps réel - Ajouter des tests — écrivez des tests unitaires pour vos outils et agents
Ressources utiles
- Documentation Google ADK — documentation officielle
- Google AI Studio — obtenez votre clé API
- Référence API Gemini — référence de l'API Gemini
- Dépôt GitHub ADK — code source et exemples
Conclusion
Dans ce guide, nous avons appris à construire un système complet d'agents IA avec Google ADK et TypeScript. Nous avons couvert la création d'outils personnalisés, la construction d'agents spécialisés, leur orchestration via un agent coordinateur, et l'ajout de la gestion de mémoire et du monitoring des performances.
Google ADK simplifie considérablement la construction d'agents IA par rapport aux autres frameworks, notamment grâce à son intégration native avec Gemini. Que vous construisiez un assistant de recherche, un système d'automatisation ou un chatbot avancé — ADK fournit une base solide pour démarrer et évoluer.
Discutez de votre projet avec nous
Nous sommes ici pour vous aider avec vos besoins en développement Web. Planifiez un appel pour discuter de votre projet et comment nous pouvons vous aider.
Trouvons les meilleures solutions pour vos besoins.
Articles connexes

Construire un outil CLI professionnel avec Node.js et TypeScript en 2026
Apprenez à construire, tester et publier un outil en ligne de commande professionnel avec Node.js et TypeScript. Ce guide couvre le parsing des arguments, les prompts interactifs, la sortie colorée et la publication sur npm.

AI SDK 4.0 : Nouvelles Fonctionnalites et Cas d'Utilisation
Decouvrez les nouvelles fonctionnalites et cas d'utilisation d'AI SDK 4.0, incluant le support PDF, l'utilisation de l'ordinateur et plus encore.

Créer un Web Scraper Intelligent avec Playwright et l'API Claude en TypeScript
Apprenez à construire un scraper web intelligent qui utilise Playwright pour l'automatisation du navigateur et l'IA Claude pour extraire, nettoyer et structurer les données de n'importe quel site — sans sélecteurs CSS fragiles.