Build AI Agents with Agentic + Needle
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))
4. Performing Search
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:
- Visit the GitHub repository
- Join our Discord community