> ## Documentation Index
> Fetch the complete documentation index at: https://docs.innochat.ch/llms.txt
> Use this file to discover all available pages before exploring further.

# RAG avec une source de données externe

> Découvrez comment intégrer des sources de données externes et dynamiques dans vos agents INNOCHAT grâce au Function Calling.

Télécharger des sources statiques comme données d’entraînement pour vos agents IA est utile – mais que faire lorsque votre base de données est très volumineuse, fortement structurée, hébergée à l’extérieur ou mise à jour en temps réel ?\
Il n’existe pas de moyen pratique de charger **l’intégralité** d’une base de données dans la bibliothèque de connaissances statique d’INNOCHAT **tout en maintenant une connexion live**…

C’est précisément ici qu’intervient le **Function Calling**.\
Grâce au Function Calling, vous pouvez fournir à votre agent IA dans INNOCHAT des **données à la demande** pendant une conversation en cours.

Dans cet exemple, nous montrons comment réaliser un enrichissement RAG avec des résumés (abstracts) d’articles scientifiques provenant d’un agrégateur externe : l’**API Semantic Scholar**.

## Configuration et test de la fonction

Tout d’abord, vous avez besoin d’une **clé API** de votre fournisseur de données externe, s’il propose une API sécurisée.\
Dans notre cas, nous avons obtenu une clé directement auprès de [Semantic Scholar](https://www.semanticscholar.org/).

Puisque nous souhaitons enrichir nos réponses LLM avec des informations issues de la recherche scientifique, nous devons identifier l’endpoint API approprié pour effectuer une recherche.\
Semantic Scholar fournit une bonne [documentation](https://api.semanticscholar.org/api-docs/graph#tag/Paper-Data/operation/get_graph_paper_relevance_search).

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-1.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=cbb6d5725ebabb0030e431f8511d0a49" width="1242" height="954" data-path="images/fc-external-database-api-1.png" />
</Frame>

### Que retourne cet endpoint ?

Pour inspecter la réponse, nous avons écrit un petit script qui exécute une requête avec des paramètres fixes.\
Le code source est présenté ci-dessous.\
Vous aurez besoin de votre propre clé API si vous souhaitez le tester vous-même.

Dans l’exemple, nous recherchons des travaux pertinents sur **« Multifidelity Optimization »** et **« Gaussian Processes »** :

```python theme={null}
import requests
import json
import os

# Set up the headers with the API key
headers = {
    'X-API-KEY': "VOTRE PROPRE CLÉ API"
}

# Specify the fields you want to fetch for each recommended paper
fields = "paperId,title,authors,abstract,url,referenceCount"

# Define the limit for the number of recommendations to return
limit = 20

# Make the request to get paper recommendations
response = requests.get(
    'https://api.semanticscholar.org/graph/v1/paper/search',
    headers=headers,
    params={'fields': fields, 'limit': limit, 'query':'multifidelity optimization, gaussian processes' }
)

# Check if the request was successful
if response.status_code == 200:
    print(json.dumps(response.json(), indent=2))
else:
    print(f"Error: {response.status_code}")
    print(response.text)
```

La sortie ressemble approximativement à ceci :

```json theme={null}
{
  "total": 12096,
  "offset": 0,
  "next": 20,
  "data": [
    {
      "paperId": "b108e6e11f4a96d5058945f3b582a032e8204ade",
      "url": "https://www.semanticscholar.org/paper/b108e6e11f4a96d5058945f3b582a032e8204ade",
      "title": "Multifidelity Gaussian processes for failure boundary andprobability estimation",
      "abstract": "...",
      "referenceCount": 49,
      "authors": [
        { "authorId": "98543101", "name": "Ashwin Renganathan" },
        { "authorId": "144321616", "name": "Vishwas Rao" },
        { "authorId": "143672238", "name": "Ionel M. Navon" }
      ]
    },
    {
      "paperId": "963a5c60ada159d27641a284008f57d6419b26f2",
      "url": "https://www.semanticscholar.org/paper/963a5c60ada159d27641a284008f57d6419b26f2",
      "title": "Generative Transfer Optimization for Aerodynamic Design",
      "abstract": "...",
      "referenceCount": 16,
      "authors": [
        { "authorId": "2149505113", "name": "Zhendong Guo" },
        ...
      ]
    }
    ...
  ]
}
```

La fonction de Semantic Scholar retourne les N résultats les plus pertinents selon nos paramètres de recherche.
Comme vous pouvez le voir, la réponse peut être assez volumineuse ; elle est ici raccourcie pour des raisons de place.
Idéalement, votre endpoint retourne une réponse JSON bien structurée, comme ci-dessus.
Notre analyse de cet endpoint (avec les champs que nous avons demandés) montre :
Chaque résultat représente en moyenne 400–500 tokens.
Selon la limite de tokens réservée pour les sorties de fonctions, vous ne pourrez donc inclure qu’un nombre limité de résultats dans le contexte du LLM.
Gardez cela à l’esprit lorsque vous décidez quelles informations prioriser pour le LLM.
Nous savons maintenant ce que le LLM reçoit comme contexte supplémentaire via le Function Call et nous pouvons le connecter à notre agent innoChat.
<Note>Il est TOUJOURS recommandé d’écrire votre propre script et de tester la réponse de l’API au préalable. Vous devez savoir exactement quelles informations seront transmises à votre agent IA.</Note>

## Créer et préparer l’agent IA

Dans votre chatbot innoChat, commencez par créer un agent IA adapté qui recevra cette capacité de Function Calling.
Dans notre exemple, l’agent s’appelle « The Professor ». Nous définissons une description d’agent et un prompt de base.

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-2.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=e8741b6c80182251c88864072fa055eb" width="1096" height="947" data-path="images/fc-external-database-api-2.png" />
</Frame>

Nous utilisons ici le modèle GPT-4-0125-8k.
Le prompt simple est visible dans la capture ci-dessous :

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-3.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=f610cba76b87cbabf045dd3e1b8064f3" width="1095" height="946" data-path="images/fc-external-database-api-3.png" />
</Frame>

Ensuite, nous enregistrons l’agent et passons dans l’onglet Knowledge pour désactiver le RAG statique provenant de la bibliothèque de connaissances interne.
Cela n’est nécessaire que si vous ne souhaitez pas utiliser de sources d’entraînement statiques.
Dans notre exemple nous n’avons de toute façon pas chargé de données d’entraînement, mais nous le désactivons pour plus de clarté.

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-4.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=478b900c955ea62ae569fa1efbc38de6" width="1096" height="846" data-path="images/fc-external-database-api-4.png" />
</Frame>

Enregistrez l’agent.

## Configurer la fonction

À l’intérieur de l’agent, passez dans l’onglet Functions.
Définissez Response Context Limit au maximum autorisé et cliquez sur Add function.

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-5.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=8e982e648a88558d531a8df7aa63f86a" width="1098" height="497" data-path="images/fc-external-database-api-5.png" />
</Frame>

Ici vous expliquez au LLM :

ce que fait la fonction

comment elle doit être appelée

quels paramètres elle attend

Le LLM décide alors lui-même quand il a besoin de la fonction et avec quels paramètres l’appeler.

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-6.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=ca42d243aad0bf00599f5b4c26ed813c" width="1099" height="949" data-path="images/fc-external-database-api-6.png" />
</Frame>

Le nom et la description de la fonction sont essentiels pour que l’IA comprenne son objectif.
Veillez à rédiger une description claire et détaillée.
Elle ne doit pas dépasser 1024 caractères (espaces inclus).
Dans notre cas :

```typescript theme={null}
Function name: paper_relevance_search

Function description: 
This function searches Semantic Scholar, a scholarly literature database. The input parameters will be defined based on extracted information from conversation context. It will return search results containing academic paper metadata (with abstracts) in a JSON format.
The returned fields are defined as follows:
- title: paper title
- abstract: paper abstract
- paperId: paper uuid
- authors: paper authors
- year: paper publication year
- url: paper link
- referenceCount: number of references included in the paper
- citationCount: number of citations of this paper


```

## Définir l’endpoint API

L’endpoint Semantic Scholar que nous utilisons est :

```bash theme={null}
https://api.semanticscholar.org/graph/v1/paper/search

```

Nous utilisons la méthode HTTP GET.
La documentation de votre endpoint indique s’il faut utiliser GET, POST, etc.

## Paramètres fixes (Fixed Parameters)

Les paramètres fixes restent identiques pour tous les appels API.
Ils représentent des réglages globaux (format, champs activés, fonctionnalités…).

Certaines APIs exigent que ces paramètres soient ajoutés directement à l’URL.
Dans notre exemple Semantic Scholar, aucun paramètre fixe n’est nécessaire.
Un endpoint plus complexe comme :

[https://app.outscraper.com/api-docs#tag/Businesses-and-POI/paths/\~1maps\~1search-v3/get](https://app.outscraper.com/api-docs#tag/Businesses-and-POI/paths/~1maps~1search-v3/get)

pourrait ressembler à :

```pgsql theme={null}
https://api.app.outscraper.com/maps/search-v3?async=false&fields=name,full_address,phone,site

```

## Headers et authentification

Les APIs publiques mais sécurisées demandent presque toujours une authentification.
Semantic Scholar ne fait pas exception.
Nous transmettons notre clé API dans les headers.
Le nom du champ header dépend du fournisseur.
Dans notre exemple il s’appelle x-api-key :

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-7.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=6fbfaf79b20e5f35f9b520665c20cb3e" width="1099" height="946" data-path="images/fc-external-database-api-7.png" />
</Frame>

## Paramètres variables

Passons maintenant aux paramètres variables (dynamiques).

Ces paramètres dépendent de la requête actuelle de l’utilisateur et sont déterminés à l’exécution.
Le LLM extrait lui-même du dialogue les valeurs à utiliser et décide s’il doit (et comment) appeler la fonction.

Pour notre fonction, nous définissons :

```json theme={null}
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Les mots-clés, noms d’auteurs ou IDs exacts d’articles à rechercher"
    },
    "fields": {
      "type": "string",
      "description": "Les informations à retourner, par défaut : 'title,abstract,paperId,authors,year,url,referenceCount,citationCount'"
    },
    "limit": {
      "type": "string",
      "description": "Le nombre d’articles souhaités, par défaut 2. Utilisez la valeur par défaut dans tous les cas."
    }
  },
  "required": [
    "query"
  ]
}
```

Points importants :
Tout commence par "type": "object" – l’ensemble des paramètres est un objet JSON.
Sous properties vous définissez chaque paramètre avec son type et sa description.
type peut être string, integer, boolean, array, etc.
La description explique précisément au LLM ce que représente le paramètre (et éventuellement les valeurs par défaut).
Plus vous êtes clair ici, moins le LLM risque de choisir des valeurs incorrectes.
Exemple de schéma plus complexe avec un tableau :

```json theme={null}
{
  "type": "object",
  "properties": {
    "tags": {
      "type": "array",
      "description": "labels qui doivent être attribués à la demande de l’utilisateur",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Le nom du label"
          },
          "color": {
            "type": "string",
            "description": "La couleur du label"
          }
        },
        "required": ["name", "color"]
      }
    }
  },
  "required": ["tags"]
}

```

La fonction ne sera appelée que lorsque tous les paramètres listés dans required sont disponibles.
S’il en manque un, l’appel ne peut pas être effectué.
Une bonne référence au format JSON Schema :
[https://json-schema.org/understanding-json-schema/reference/type](https://json-schema.org/understanding-json-schema/reference/type)

Tester le chatbot

Une fois tout configuré :

Enregistrez la fonction

Enregistrez l’agent

Passez dans l’onglet Preview

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-8.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=2fa3a2df4b3fcdfad7015b3611399910" width="657" height="811" data-path="images/fc-external-database-api-8.png" />
</Frame>

Vous pouvez activer le Debug Mode en haut à droite.
Cela vous permet de voir si et comment la fonction a été appelée et quelles données ont été retournées :

<Frame>
  <img src="https://mintcdn.com/innoq/-rzRPawWGCb-PHDN/images/fc-external-database-api-9.png?fit=max&auto=format&n=-rzRPawWGCb-PHDN&q=85&s=8e8afcdd71ce67f08dca34d80fcfe9d8" width="1209" height="669" data-path="images/fc-external-database-api-9.png" />
</Frame>

Et voilà : votre agent IA est désormais connecté avec succès à des données à la demande provenant d’un fournisseur externe.
À l’avenir, nous proposerons également un guide expliquant comment implémenter et héberger votre propre fonction de recherche de base de données, puis l’intégrer avec innoChat.
