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

# Linkup

> Utilisez la recherche web Linkup avec les agents vocaux IA de Gradium

Linkup est une API de recherche web pour l'IA, conçue pour la production. Dans un agent vocal Gradium, Linkup joue le rôle de couche web en temps réel : l'appelant formule une demande à voix haute, l'agent la transforme en requête ciblée, Linkup renvoie des résultats web à jour avec leurs sources et des images, et Gradium énonce la réponse pendant que les sources s'affichent en flux à l'écran.

<CardGroup cols={2}>
  <Card title="Linkup" icon="arrow-up-right-from-square" href="https://docs.linkup.so/">
    Découvrez les API de recherche, de récupération et de recherche approfondie de Linkup.
  </Card>

  <Card title="Agent vocal de réservation d'hôtel" icon="github" href="https://github.com/gradium-ai/gradbot/tree/main/demos/hotel">
    Découvrez une démo Gradbot qui réserve des hôtels grâce à la recherche web en temps réel.
  </Card>
</CardGroup>

## Recherche web à commande vocale

Un agent de recherche vocale construit avec Gradium et Linkup suit cette boucle :

1. L'appelant pose une question à voix haute, par exemple « Trouve-moi un hôtel de charme à Lisbonne à moins de 150 euros la nuit. »
2. La transcription (STT) Gradium transcrit la demande en temps réel.
3. L'agent appelle un outil de recherche avec une requête ciblée construite à partir des préférences énoncées par l'appelant.
4. Linkup renvoie des résultats classés avec titres, sources, extraits et images.
5. L'agent filtre, compare et résume les résultats.
6. La synthèse vocale (TTS) Gradium renvoie la réponse en streaming à l'appelant.

Ce modèle permet aux appelants de piloter une recherche web sans rien taper. Ils peuvent affiner la recherche au fil de la conversation, demander des compromis, comparer des sources ou restreindre les résultats selon des critères comme le budget, le lieu, le style ou les dates.

## Câblage de base

La démo d'hôtel expose la recherche sous forme d'outils de l'agent vocal. Gradium gère la session STT et TTS en temps réel ; l'agent décide quand appeler `search_hotels` et `get_hotel_details`.

### Définition de l'outil de recherche

```python theme={null}
gradbot.ToolDef(
    name="search_hotels",
    description=(
        "Search the web for available hotels in a destination. Takes some "
        "time to search. Keep chatting with the caller about the destination "
        "while waiting for results! IMPORTANT: Always include the caller's "
        "preferences (budget, style, etc.) in the preferences field so the "
        "search is targeted."
    ),
    parameters_json=json.dumps({
        "type": "object",
        "properties": {
            "destination": {
                "type": "string",
                "description": "The city or destination to search hotels in",
            },
            "preferences": {
                "type": "string",
                "description": (
                    "Caller's requirements: budget range, style, amenities, "
                    "etc. (e.g. 'under 100 euros per night, boutique style')"
                ),
            },
        },
        "required": ["destination"],
    }),
)
```

### Appeler l'API Search de Linkup

La démo utilise le paquet [`linkup-sdk`](https://pypi.org/project/linkup-sdk/). Comme le client est synchrone, le handler exécute chaque recherche dans un pool de threads afin de ne pas bloquer la session vocale. `include_images=True` renvoie des résultats d'images en plus des sources textuelles.

```python theme={null}
import asyncio
from linkup import LinkupClient

linkup_client = LinkupClient(api_key=os.environ["LINKUP_API_KEY"])

async def do_search(query: str, include_images: bool = True) -> dict:
    loop = asyncio.get_running_loop()
    result = await loop.run_in_executor(
        None,
        lambda: linkup_client.search(
            query=query,
            depth="standard",
            output_type="searchResults",
            include_images=include_images,
        ),
    )

    sources, images = [], []
    for item in result.results or []:
        if item.type == "image":
            images.append({"title": item.name, "url": item.url})
        else:
            sources.append({
                "title": item.name,
                "href": item.url,
                "body": item.content[:300] if item.content else "",
            })

    answer = "\n".join(f"- {s['title']}: {s['body']}" for s in sources[:5])
    return {"answer": answer, "sources": sources, "images": images}
```

Chaque résultat textuel comporte un `name`, une `url` et un `content` ; les résultats d'images comportent un `name` et une `url`. Deux paramètres déterminent la recherche :

* **`depth`** arbitre entre latence et exhaustivité. `fast` est une recherche par mots-clés en moins d'une seconde, destinée aux chemins critiques en latence comme la voix ; `standard` est une recherche agentique en une seule itération, d'environ une à trois secondes, adaptée à la plupart des recherches d'agent ; et `deep` exécute jusqu'à dix itérations en cinq à trente secondes pour des investigations complexes multi-sources. La démo utilise `standard`.
* **`output_type`** détermine la forme de la valeur renvoyée. `searchResults` renvoie des URL classées et des extraits sur lesquels l'agent peut raisonner, `sourcedAnswer` renvoie une réponse générée avec citations, et `structured` renvoie du JSON conforme à un schéma que vous fournissez. La démo utilise `searchResults` pour que l'agent puisse filtrer et résumer lui-même les sources.

### Renvoyer les résultats à l'agent

Le handler de l'outil envoie en flux les sources et les images au navigateur, remplace le prompt par un prompt construit à partir des résultats de recherche, et renvoie à l'agent un résumé compact accompagné d'instructions sur la manière d'énoncer la réponse. Un payload réduit permet de garder rapide la partie LLM du tour de parole.

```python theme={null}
async def handle_search_hotels(destination, preferences, tool_handle, input_handle, websocket):
    query = f"hotels in {destination} {preferences or ''} with star ratings, prices per night, and brief descriptions"
    result = await do_search(query)

    # Stream source cards and images to the frontend
    await websocket.send_json({
        "type": "search_results",
        "query": f"Hotels in {destination}",
        "results": result["sources"],
        "images": result.get("images", []),
    })

    await tool_handle.send(json.dumps({
        "success": True,
        "destination": destination,
        "answer": result["answer"],
        "sources": result["sources"],
        "message": (
            "Hotel search results are ready. Present the top options based on "
            "the search results, highlighting star ratings, price ranges, and "
            "key features. Ask which one interests the caller."
        ),
    }))
```

### Configuration de la session de l'agent

La configuration de session relie les outils à une session vocale Gradium en temps réel.

```python theme={null}
def make_config(instructions: str) -> gradbot.SessionConfig:
    return gradbot.SessionConfig(
        voice_id="cLONiZ4hQ8VpQ4Sz",
        instructions=instructions,
        language=gradbot.Lang.En,
        tools=build_tools(),
        silence_timeout_s=0.0,
    )

await gradbot.websocket.handle_session(
    websocket,
    on_start=on_start,
    on_config=on_config,
    on_tool_call=handle_tool_call,
)
```

## Garder la boucle vocale rapide

C'est la latence qui rend une recherche vocale magique ou défaillante. La démo applique quelques règles bonnes à reprendre :

* **Recherchez en dehors de la boucle d'événements.** Le client Linkup est synchrone : exécutez-le dans un pool de threads avec `run_in_executor` pour éviter de bloquer l'audio pendant qu'une requête est en cours.
* **Adaptez la profondeur au tour de parole.** La démo utilise la profondeur `standard` et comble l'attente par la conversation. Pour les recherches qui doivent aboutir pendant une pause dans la conversation, `depth="fast"` renvoie des résultats par mots-clés en moins d'une seconde ; réservez `deep` aux questions de type recherche approfondie, où quelques secondes de plus sont acceptables.
* **Comblez l'attente par la conversation.** Demandez à l'agent de continuer à parler de la destination pendant la recherche, afin que l'appelant n'entende jamais de blanc.
* **Limitez et tronquez les résultats.** Une poignée de sources avec des extraits réduits à environ 300 caractères suffit au LLM pour répondre sans alourdir le prompt.
* **Affichez les sources en flux à l'écran.** Envoyez les fiches de sources et les images au navigateur au fur et à mesure que les résultats arrivent, pour que l'appelant voie ce dont parle l'agent.
* **Gérez les échecs avec la voix de l'agent.** Si une recherche échoue, renvoyez un résultat vide et demandez à l'agent de dire qu'il ne peut pas accéder au web pour le moment, plutôt que de laisser le modèle deviner.

## Authentification

Obtenez une clé API depuis le [tableau de bord Linkup](https://app.linkup.so/). Passez-la au `LinkupClient` ou définissez-la comme variable d'environnement, à côté de votre clé Gradium :

| Variable | Rôle |
| - | - |
| `LINKUP_API_KEY` | Clé de recherche Linkup |
| `GRADIUM_API_KEY` | Voix Gradium (STT et TTS) |

## Pourquoi utiliser Linkup avec Gradium ?

* **Des réponses à jour dans les sessions vocales en temps réel** : donnez aux agents Gradium accès à des résultats web actuels sans obliger les appelants à quitter la conversation.
* **Une recherche qui suit les contraintes énoncées à l'oral** : transformez des préférences exprimées en langage naturel, comme le budget, le lieu, le style ou les dates, en requêtes Linkup ciblées.
* **Sources et images réunies** : les résultats arrivent sous forme de données structurées propres, avec sources textuelles et images, prêtes à être résumées, énoncées et affichées en flux à l'écran.
* **Des réponses orales fondées** : l'agent répond à partir de résultats web en temps réel plutôt que de la mémoire figée du modèle, et peut citer la source naturellement.

## Démo

L'[agent vocal de réservation d'hôtel](https://github.com/gradium-ai/gradbot/tree/main/demos/hotel) illustre le modèle complet : une application FastAPI qui exécute une session Gradbot, guide l'appelant dans le choix d'une destination, d'un hôtel et d'une chambre, et appuie chaque étape sur une recherche Linkup en temps réel. Servez-vous-en comme référence pour créer votre propre expérience de recherche vocale instantanée.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.