Skip to main content
Version: 3.0

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

ParameterTypeDefaultDescription
querystringrequiredThe search query
connectionNamestringrequiredName of the Jina connection
limitnumber3Maximum number of results
formatsstring[]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,
});
tip

Wrap connectionName and limit in aktorSetting so operators can adjust these values per deployment without code changes.