Skip to main content

Build AI Agents with Needle and Agentic

3 min read
Agentic Logo

GitHub Repository

Use Needle as a powerful RAG tool in your AI agents through Agentic - a standard library of AI functions that works with all major TypeScript AI SDKs (LangChain, LlamaIndex, Vercel AI SDK, OpenAI SDK, etc).

Setup

Installation

npm install @agentic/needle openai dotenv

Environment Configuration

Create a .env file with your API keys:

NEEDLE_API_KEY=your_needle_api_key_here
OPENAI_API_KEY=your_openai_api_key_here

Package Dependencies

Add these to your package.json:

{
"dependencies": {
"@agentic/core": "workspace:*",
"@agentic/needle": "workspace:*",
"dotenv": "^16.4.5",
"openai": "^4.28.0"
}
}

Building an AI Agent

Let's build an agent that can create collections, add documents, and perform semantic search. We'll break it down into steps:

1. Initial Setup

First, import the required packages and initialize the clients:

import 'dotenv/config'
import { NeedleClient } from '@agentic/needle'
import OpenAI from 'openai'

async function main() {
const needle = new NeedleClient()
const openai = new OpenAI()
let collectionId: string | undefined

const messages: OpenAI.ChatCompletionMessageParam[] = [
{
role: 'system',
content:
'You are a helpful assistant. Only use the information provided in the search results to answer questions. Do not make assumptions or add information from other sources.'
},
{
role: 'user',
content:
'Create a collection for Needle documentation and add the Needle website (needle-ai.com) to it, then search for what Needle is.'
}
]

2. Creating a Collection

The agent will first create a new collection:

// Create collection
const res = await openai.chat.completions.create({
messages,
model: "gpt-4o-mini",
temperature: 0,
tools: needle.collections.functions.toolSpecs,
tool_choice: "required",
});
const message = res.choices[0]?.message!;
console.log("Create collection response");
messages.push(message);

// Handle collection creation
for (const toolCall of message.tool_calls || []) {
if (toolCall.function.name === "create_collection") {
const fn = needle.collections.functions.get(toolCall.function.name)!;
const result = await fn(toolCall.function.arguments);
console.log("Collection created");
collectionId = result.id;
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: JSON.stringify(result),
});
}
}

3. Adding Content

Next, add a website to the collection:

// Add file to collection
const addFileRes = await openai.chat.completions.create({
messages,
model: "gpt-4o-mini",
temperature: 0,
tools: needle.collections.functions.toolSpecs,
tool_choice: "required",
});
const addFileMessage = addFileRes.choices[0]?.message!;
console.log("Add file");
messages.push(addFileMessage);

// Handle file addition
const addFileCall = addFileMessage.tool_calls?.find(
(call) => call.function.name === "add_file"
);
if (addFileCall) {
const fn = needle.collections.functions.get(addFileCall.function.name)!;
const params = JSON.parse(addFileCall.function.arguments);
params.collection_id = collectionId;
params.files = [{ url: "https://needle-ai.com", name: "Needle Website" }];
const result = await fn(JSON.stringify(params));
console.log("Files added");
messages.push({
role: "tool",
tool_call_id: addFileCall.id,
content: JSON.stringify(result),
});
}

// Wait for indexing
console.log("Waiting 20 seconds for file indexing...");
await new Promise((resolve) => setTimeout(resolve, 20_000));

Now search the collection:

// Search collection
const searchRes = await openai.chat.completions.create({
messages,
model: "gpt-4o-mini",
temperature: 0,
tools: needle.collections.functions.toolSpecs,
tool_choice: "required",
});
const searchMessage = searchRes.choices[0]?.message!;
console.log("Search response");
messages.push(searchMessage);

// Handle search
const searchCall = searchMessage.tool_calls?.find(
(call) => call.function.name === "search_collection"
);
if (searchCall) {
const fn = needle.collections.functions.get(searchCall.function.name)!;
const params = JSON.parse(searchCall.function.arguments);
params.collection_id = collectionId;
const result = await fn(JSON.stringify(params));
console.log("Search results");
messages.push({
role: "tool",
tool_call_id: searchCall.id,
content: JSON.stringify(result),
});
}

5. Generating Summary

Finally, generate a summary of the search results:

  // Generate summary
messages.push({
role: 'user',
content:
'Based ONLY on the search results above, what is Needle? If there are no results yet, please say so.'
})

const summaryRes = await openai.chat.completions.create({
messages,
model: 'gpt-4o-mini',
temperature: 0,
tools: needle.collections.functions.toolSpecs
})
const summaryMessage = summaryRes.choices?.[0]?.message

console.log('\n=== AI Summary ===')
if (summaryMessage?.content) {
console.log('\n' + summaryMessage.content + '\n')
} else {
console.log('\nNo content in response\n')
}
}

await main()

Support

For questions and support: