## Before you begin

Make sure you have the following tools and accounts ready:

- **[An Algolia account](/content/users/sign_up/index.html)**. If you don’t have one, [create a new account](/content/users/sign_up/index.html) for free.
- **Access to [Agent Studio](https://dashboard.algolia.com/generativeAi/agent-studio/agents)**.
- **[Node.js](https://nodejs.org/en/download)** 22.12 or later with **npm**.
- **An API key** from your LLM provider to connect your Algolia agent to your large language model:
  - Gemini (recommended)
  - Azure OpenAI
  - OpenAI

1. Go to [Google AI Studio](https://aistudio.google.com/api-keys) and sign in with your Google account.
2. Click **Create API key** (or **Get API key**) and name it.
3. For **Choose an imported project**, click **Create project** and name it (if you don’t have a project yet).
4. Click **Create key**.
5. Copy the API key and store it securely.

Google AI Studio offers a free usage tier for Gemini. However, be aware of the [usage limits](https://ai.google.dev/gemini-api/docs/rate-limits) for the Gemini API on the free tier.

For more information, see [Gemini API documentation](https://ai.google.dev/gemini-api/docs/api-key). You need this key when you create your agent’s LLM provider (step 2).

1. Go to [AI Foundry](https://ai.azure.com/) and sign in with your Microsoft account.
2. If you don’t have an Azure OpenAI resource yet, create one:
   1. Select **Create a new project** or use an existing project.
   2. In your project, go to **Deployments** and create a new deployment with your chosen model (for example, GPT-4).
   3. Once you have a deployment, copy the following credentials to create a provider profile in Agent Studio:
      - **Azure endpoint URL**: found in your project settings (for example, `https://your-name-here.openai.azure.com/`).
      - **API key**: found under **Keys and Endpoint** (sometimes known as the subscription key).
      - **Azure deployment name**: the name you assigned to your deployment (for example, `my-gpt4-deployment`).
      - **API version**: the API version to use (for example, `2024-12-01-preview`).

For more information, see [Azure OpenAI documentation](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/latest). You need these credentials later when you create your agent’s LLM provider (step 2).

1. Go to the [OpenAI Platform](https://platform.openai.com/api-keys) and sign in with your OpenAI account.
2. Click **Create new secret key** and name it.
3. Copy the API key and store it securely.

Although API key setup is free, OpenAI requires an active payment method before you can use the key.

For more information, see [OpenAI’s API key documentation](https://platform.openai.com/docs/quickstart/account-setup). You need this key when you create your agent’s LLM provider (step 2).

## Quickstart

In this quickstart, you’ll use Agent Studio with an LLM to build a conversational assistant that queries a products index, avoids hallucinations, and respects the index’s settings and ranking.

### 1. Create a product catalog index

1. Go to the [Algolia dashboard](https://dashboard.algolia.com/explorer/browse) and create a new index. Use `products` as the index name.
2. Download the [`records.json`](https://github.com/algolia/datasets/raw/dd302a00a5681a0344be81f510ba587f14c5ecde/ecommerce/records.json) file. The `records.json` file contains product listing records with attributes such as `name`, `categories`, `price`, and `brand. For example:

```json
{
   "name": "ROCCAT - Taito Control Mouse Pad - Black/Blue",
   "description": "Beat your opponent with a click of your mouse on this ROCCAT Taito Control ROC-13-170-AM mouse pad that is compatible with a wide range of optical and laser gaming mice. The total-control surface ensures smooth, precise mouse movement.",
   "brand": "ROCCAT",
   "categories": [
       "Computers & Tablets",
       "Mice & Keyboards",
       "Mouse & Wrist Pads"
   ],
   "hierarchicalCategories": {
       "lvl0": "Computers & Tablets",
       "lvl1": "Computers & Tablets > Mice & Keyboards",
       "lvl2": "Computers & Tablets > Mice & Keyboards > Mouse & Wrist Pads"
   },
   "type": "Gaming controllers",
   "price": 14.99,
   "price_range": "1 - 50",
   "image": "https://cdn-demo.algolia.com/bestbuy/4384501_sb.jpg",
   "url": "http://www.bestbuy.com/site/roccat-taito-control-mouse-pad-black-blue/4384501.p?id=1219740718517&skuId=4384501&cmp=RMX&ky=1uWSHMdQqBeVJB9cXgEke60s5EjfS6M1W",
   "free_shipping": false,
   "popularity": 1548,
   "rating": 2,
   "objectID": "4384501"
}
```

The conversational assistant app will search and reference these when answering product-related questions.
3. Click **Upload records > Upload file**, and select the `records.json` file you downloaded.

### 2. Add LLM provider credentials

1. From Agent Studio’s [Settings](https://dashboard.algolia.com/generativeAi/agent-studio/settings/providers) page, click **Create provider profile**.
2. Select your preferred provider and enter the appropriate credentials:  
   - **Azure OpenAI**: paste in your chosen key value (as **API Key**) and endpoint URL. Then choose an LLM model and API version.
   - **Gemini**: paste in your Google AI Studio API key.
   - **OpenAI**: paste in your API key and select a region.

### 3. Create an agent in the Algolia dashboard

1. Go to the [Algolia dashboard](https://dashboard.algolia.com/generativeAi/agent-studio/agents).
2. On the left sidebar, select **Generative AI > Agent Studio > Agents**, then click **Create your first agent** or **Create agent**.
3. Click **Start from scratch**.
4. Paste the following into the **Instructions** box:

```
You are a shopping assistant.
Your goal is to help users find products in the product catalog using Algolia search.

Scope:
- Only answer questions about products in the catalog.
- If asked about anything else, reply: "I can only answer questions about the product catalog."
- If an item is not found in the catalog, reply: "Sorry. I couldn't find any matching items." and stop.

Behavior:
- Use a clear and friendly tone.
- When helpful, include product names, short descriptions, prices, categories, and links.
- Return at most five results per query.
- Ask up to two clarifying questions if the query is ambiguous (confidence is less than 95%).
- On timeout or error, reply once: "An error occurred. Try rephrasing your request."

Restrictions:
- Stop searching after five search attempts per session. If no products are found after that, send the "no matching items" message and stop.

Language:
- Reply in English.

Output formatting:
- Use bold labels followed by values, one per line. For example:

**Name**: ROCCAT Mouse Pad
    **Price**: $14.99
    **Brand**: ROCCAT
    **Link**: <https://example.com/product>

- Always insert two spaces at the end of each line to ensure proper line breaks in markdown.
- Don't use bullet points or numbered lists.
- Always format links using angle brackets to show the raw URL.
```

5. Click **Add tools**, choose **Algolia Search**, and select the `products` index. To see supported tool types beyond the Search tool, see [Tools for Agent Studio](/content/doc/guides/algolia-ai/agent-studio/how-to/tools/index.html).
6. For **Description**, enter `Product catalog`, click **Save**, then **Add tool**.
7. Click **Change provider** and choose the LLM provider you added in step 2.

### 4. Test and publish the agent

1. Use the preview panel on the right to test your new agent with a sample query. For example, if you say “What Christian Siriano cases do you have?”, you should expect it to list a handful of products. You can also ask follow-up questions, for example, to filter by price or category.

2. After asking a few questions, click **Publish**.
3. Close the confirmation box.

### 5. Build a conversational assistant app

1. To create a new React app with Vite, enter the following commands in your terminal (on **Windows**, use **PowerShell**, not **Command Prompt**):

```
npm create vite@latest agent-app -- --template react
cd agent-app
npm install
```
If prompted to install `rolldown-vite`, select **No**. When prompted to **Install with npm and start now**, select **No**.
2. Install the Markdown package for rendering output:

```
npm i react-markdown
```
3. To create the agent app, replace the code in `src/App.jsx` with:

```javascript
import { useState } from "react";
import ReactMarkdown from "react-markdown";
import "./App.css";

export default function App() {
   const [input, setInput] = useState("");
   const [messages, setMessages] = useState([]);
   const [isLoading, setIsLoading] = useState(false);

const handleSubmit = async (e) => {
       e.preventDefault();
       const text = input.trim();
       if (!text) return;
       setInput("");
       setIsLoading(true);

// Add user message locally
       setMessages((prev) => [...prev, { role: "user", content: text }]);

try {
           const appID = import.meta.env.VITE_ALGOLIA_APPLICATION_ID;
           const agentId = import.meta.env.VITE_AGENT_ID;
           const apiKey = import.meta.env.VITE_ALGOLIA_SEARCH_API_KEY;

const res = await fetch(
               `https://${appID}.algolia.net/agent-studio/1/agents/${agentId}/completions?stream=false&compatibilityMode=ai-sdk-4`,
               {
                   method: "POST",
                   headers: {
                       "Content-Type": "application/json",
                       "x-algolia-application-id": appID,
                       "x-algolia-api-key": apiKey,
                   },
                   body: JSON.stringify({
                       messages: [{ role: "user", content: text }],
                   }),
               }
           );

const data = await res.json();

// Agent Studio returns a single assistant message object
           if (data.role === "assistant" && data.content) {
               setMessages((prev) => [...prev, data]);
           } else if (data.messages) {
               // Fallback in case API shape changes
               const aiMsg =
                   data.messages.find((m) => m.role === "assistant") ||
                   data.messages.find((m) => m.role === "ai");
               if (aiMsg) setMessages((prev) => [...prev, aiMsg]);
               else console.warn("No assistant message found:", data);
           } else {
               console.warn("Unrecognized response shape:", data);
           }
       } catch (err) {
           console.error("Request failed:", err);
       } finally {
           setIsLoading(false);
       }
   };

return (
       <div className="chat-container">
           <div className="chat-messages">
               {messages.map((m, i) => (
                   <div
                       key={i}
                       className={`chat-message ${m.role === "user" ? "user" : "ai"}`}
                   >
                       <strong>{m.role === "user" ? "User:" : "AI:"}</strong>
                       <div className="chat-content">
                           <ReactMarkdown>{m.content}</ReactMarkdown>
                       </div>
                   </div>
               ))}
           </div>

<form onSubmit={handleSubmit} className="chat-form">
               <textarea
                   value={input}
                   onChange={(e) => setInput(e.target.value)}
                   placeholder="Ask a question..."
                   rows={2}
                   className="chat-input"
                   disabled={isLoading}
               />
               <button type="submit" className="chat-button" disabled={isLoading}>
                   {isLoading ? "Loading..." : "Send"}
               </button>
           </form>
       </div>
   );
}
```

4. To apply styling to the app, replace `src/App.css` with the following:

```css
/* === Root element === */
#root {
   max-width: 1280px;
   margin: 0 auto;
   padding: 2rem;
}

/* === Agent Studio chat UI === */
:root {
    --chat-max-width: 800px;
    --chat-bg: #fafafa;
    --chat-border: #ddd;
    --chat-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
    --chat-font: system-ui, sans-serif;

--user-bg: #e8f0fe;
    --ai-bg: #ffffff;

--button-bg: #0066ff;
    --button-hover-bg: #0052cc;
    --button-text: #ffffff;

--input-border: #ccc;
    --text-color: #111;
}

@media (prefers-color-scheme: dark) {
    :root {
        --chat-bg: #1e1e1e;
        --chat-border: #333;
        --chat-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);

--user-bg: #223355;
        --ai-bg: #2a2a2a;

--button-bg: #3388ff;
        --button-hover-bg: #1e6fff;
        --button-text: #fff;

--input-border: #444;
        --text-color: #f1f1f1;
    }
}

.chat-container {
    max-width: var(--chat-max-width);
    margin: 40px auto;
    padding: 20px;
    border: 1px solid var(--chat-border);
    border-radius: 12px;
    font-family: var(--chat-font);
    background-color: var(--chat-bg);
    box-shadow: var(--chat-shadow);
    color: var(--text-color);
}

.chat-messages {
    min-height: 400px;
    overflow-y: auto;
    margin-bottom: 20px;
    text-align: left;
}

.chat-message {
    margin-bottom: 1em;
    padding: 10px 14px;
    border-radius: 8px;
    white-space: pre-wrap;
    line-height: 1.5;
    border: 1px solid var(--chat-border);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.chat-message.user {
    background-color: var(--user-bg);
}

.chat-message.ai {
    background-color: var(--ai-bg);
}

.chat-content {
    margin-top: 5px;
    line-height: 1.5;
}

/* Fix inline formatting for bold labels and colon values */
.chat-content strong {
    display: inline;
    font-weight: 600;
    margin-right: 0.25em;
}

/* Paragraphs wrap normally */
.chat-content p {
    white-space: normal;
    margin: 0.3em 0;
}

/* Fix spacing and remove bullets */
.chat-content ul,
.chat-content ol {
    list-style: none;
    padding-left: 0;
    margin: 0.4em 0;
}

.chat-content ul > li,
.chat-content ol > li {
    margin: 0.2em 0;
    padding: 0.2em 0;
    border-top: 1px solid var(--chat-border);
}

.chat-content ul > li:first-child,
.chat-content ol > li:first-child {
    border-top: none;
}

/* Prevent line collapse */
.chat-content br {
    line-height: 1.4;
}

/* Make URLs visible and clickable */
.chat-content a {
    color: var(--button-bg);
    text-decoration: underline;
    word-break: break-word;
}

.chat-form {
    display: flex;
    gap: 10px;
}

.chat-input {
    flex: 1;
    padding: 10px;
    border-radius: 8px;
    border: 1px solid var(--input-border);
    background: var(--ai-bg);
    color: var(--text-color);
    font-size: 1rem;
    resize: vertical;
    min-height: 40px;
    max-height: 150px;
    line-height: 1.4;
}

.chat-input::placeholder {
    color: #888;
}

.chat-button {
    padding: 10px 16px;
    border-radius: 8px;
    border: none;
    background-color: var(--button-bg);
    color: var(--button-text);
    font-weight: bold;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.chat-button:hover {
    background-color: var(--button-hover-bg);
}
```

5. Add your environment variables. Create a file called `.env.local` at the root of your app (next to `package.json`) and paste in the following:

```
VITE_ALGOLIA_APPLICATION_ID=
VITE_ALGOLIA_API_KEY=
VITE_AGENT_ID=
```

Add the following credentials after the appropriate `=` character:   - **VITE_ALGOLIA_APPLICATION_ID** is your Algolia Application ID, found under [API Keys](https://dashboard.algolia.com/account/api-keys/) in the dashboard.
   - **VITE_ALGOLIA_API_KEY** is your Search API key from the same page.
   - **AGENT_ID** is your agent ID. Find it on the [Agents overview page](https://dashboard.algolia.com/generativeAi/agent-studio/agents), click **View actions > Copy ID**.

### 6. Run the conversational assistant app

Run the app.

```
npm run dev
```

Open the local URL [http://localhost:5173](http://localhost:5173/) in your browser and test the conversational assistant app.
For example, ask “What’s the best compact refrigerator?”

If your app fails to connect, check that:
- Your agent is published.
- The variables in the `.env.local` file are correct.
- You’re using the Algolia Search API key, not something else.

## Next steps

To customize this quickstart, change the following:

### LLM
- Although this guide uses Gemini, OpenAI, and Azure OpenAI, you can also connect any OpenAI-compatible API (for example, one hosting Llama or Mistral).
- Tweak the agent’s [prompt](/content/doc/guides/algolia-ai/agent-studio/how-to/prompting/index.html), that you added in step 3, to ensure meaningful output.

### Data
- Instead of the Algolia sample data, use your own data and [send it to an Algolia index](/content/doc/guides/sending-and-managing-data/send-and-update-your-data/index.html).
