Web Search
Operaide can search the web and scrape individual pages at runtime, giving your Reaktors access to up-to-date information beyond the training data of the LLM. Both features use the Jina AI API under the hood.
Prerequisites
Before using web search, an administrator must create a Jina AI connection in the platform UI. Jina offers a free API key at jina.ai. Once the connection exists, reference it by name in your code.
The Jina connection uses two Jina API products: Search (s.jina.ai) for aktorWebsearch and Reader (r.jina.ai) for aktorWebscrape. Both are accessed through the same API key and connection. Neither requires a model parameter. Jina's Embeddings and Reranker APIs are separate products not covered by this connection. See Connection Management for setup details.
Searching the Web
Use aktorWebsearch to run a web search and get back structured results.
import { aktorWebsearch } from '@operaide/ai';
import { aktorConst, aktorSetting } from '@operaide/aktor';
import { z } from 'zod';
const connectionName = aktorSetting(z.string(), 'jina', 'Jina Connection');
const results = aktorWebsearch({
query: aktorConst('Operaide AI workflow automation'),
connectionName,
limit: aktorConst(5),
});
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | required | The search query |
connectionName | string | required | Name of the Jina connection |
limit | number | 3 | Maximum number of results |
formats | string[] | — | Response formats (e.g. ['markdown']) |
Each result contains title, description, url, and content. When 'markdown' is included in formats, a markdown field is also returned.
Scraping a URL
Use aktorWebscrape to extract content from a single web page.
import { aktorWebscrape } from '@operaide/ai';
import { aktorConst, aktorSetting } from '@operaide/aktor';
import { z } from 'zod';
const connectionName = aktorSetting(z.string(), 'jina', 'Jina Connection');
const page = aktorWebscrape({
url: aktorConst('https://example.com/article'),
connectionName,
});
The result contains title, description, url, content, and markdown.
Using Web Search as an LLM Tool
The most common pattern is to expose web search as a tool that the LLM can call when it needs external information.
import {
aktorAICall,
aktorAISettingProviderModel,
aktorPatchMessages,
aktorToTool,
aktorToolSet,
aktorWebsearch,
} from '@operaide/ai';
import { aktorConst, aktorSetting, createAktorComposition, registerChatReaktorDefinition } from '@operaide/aktor';
import { z } from 'zod';
import type { LlmOptions } from '@operaide/ai';
const aktorResearchChat = createAktorComposition('aktorResearchChat', ({ messages }) => {
const connectionName = aktorSetting(z.string(), 'jina', 'Jina Connection');
const limit = aktorSetting(z.number(), 5, 'Max Search Results');
const searchTool = aktorToTool({
aktor: aktorWebsearch,
description: 'Search the web for current information',
parameters: z.object({
query: z.string().describe('The search query'),
}),
dependencies: {
connectionName,
limit,
},
});
return aktorAICall({
messages: aktorPatchMessages({
messages,
system: aktorConst(
'You are a research assistant. Use the search tool to find current information when needed.'
),
}),
providerModel: aktorAISettingProviderModel(),
tools: aktorToolSet({ search: searchTool }),
llmOptions: aktorConst<LlmOptions>({ max_steps: 5 }),
});
});
registerChatReaktorDefinition({
reaktorDefinitionId: 'research-chat',
label: 'Research Chat',
description: 'Chat with web search capabilities',
aktor: aktorResearchChat,
});
Wrap connectionName and limit in aktorSetting so operators can adjust these values per deployment without code changes.