Skip to main content

Build AI Agents with Agentic + Needle

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: