Skip to main content
Use the tool definitions below to give any LLM-powered agent real-time web search via Parallel Search and focused page content via Parallel Extract. This works with any framework that supports function/tool calling — OpenAI, Anthropic, Google Gemini, Vercel AI SDK, LangChain, and others.
If you’re using MCP, the tool definition is provided automatically — you don’t need to define it yourself.

Search tool definition (search_web)

Copy this directly into your agent’s tool/function list. We provide OpenAI and Anthropic formats — the schema is identical, only the wrapper differs.
{
  "type": "function",
  "function": {
    "name": "search_web",
    "description": "Searches the web for current and factual information, returning relevant results with titles, URLs, and content snippets.",
    "parameters": {
      "type": "object",
      "properties": {
        "objective": {
          "type": "string",
          "description": "A concise, self-contained search query. Must include the key entity or topic being searched for."
        },
        "search_queries": {
          "type": "array",
          "description": "Exactly 3 keyword search queries, each 3-6 words. Must be diverse — vary entity names, synonyms, and angles. Each query must include the key entity or topic. NEVER write sentences, instructions, or use site: operators.",
          "items": { "type": "string" },
          "minItems": 3,
          "maxItems": 3
        }
      },
      "required": ["objective", "search_queries"]
    }
  }
}

Extract tool definition (web_fetch)

Use this alongside search_web when you want the model to pull token-efficient markdown for specific URLs (for example, after search results narrow down which pages matter).
{
  "type": "function",
  "function": {
    "name": "web_fetch",
    "description": "Fetches content from the given URL, returning the content of the page, or if target_content is provided, returns the content of the page that is most relevant to the target. Use this to fetch content from any specific page on the web.",
    "parameters": {
      "type": "object",
      "properties": {
        "urls": {
          "type": "array",
          "description": "The URLs to fetch content from.",
          "items": { "type": "string" }
        },
        "target_content": {
          "type": "string",
          "description": "The content to target from the page. For example, information about a certain method or a class in a page. If not provided, the entire page is fetched."
        }
      },
      "required": ["urls"]
    }
  }
}
In your tool handler, map target_content to the Extract API objective field when the model provides it. Omit objective (or pass null) when target_content is absent or empty for an unfocused full-page extract.
If you assemble tools in Python, OpenAI expects {"type": "function", "function": {"name": ..., "description": ..., "parameters": ...}}. Anthropic expects the same JSON Schema under input_schema instead of parameters (see the tabs above). For Gemini, pass that schema as parameters on genai.types.FunctionDeclaration as in the Gemini tab.

Agent evaluations and benchmarks

When you evaluate agents that call tools against our Search API, we do not recommend exposing extra Search request fields (such as max_results, max_chars_total, or similar) in the tool schema the model sees. Models often set these without need, which shrinks the search space and hurts quality. Keep tuning parameters server-side in your handler instead. For realistic end-to-end benchmarks, we recommend evaluating Search and Extract together: Search finds relevant URLs and short snippets, and Extract returns concise, token-efficient markdown for the URLs the agent decides it needs to read in depth.

Why the Descriptions Matter

The description fields in each schema are prompts for the LLM — they directly shape how the model constructs search and extract requests. The key guidance baked into search_web above:
  • objective: Must be self-contained with the key entity or topic. This tells the model not to write vague objectives like “search for more information” — instead, it should include the specific subject.
  • search_queries: Exactly 3 diverse keyword queries, 3-6 words each. This prevents the model from writing a single verbose query or repeating the same angle three times. The diversity constraint is critical — varying entity names, synonyms, and angles produces significantly better search coverage.
For more on writing effective objectives and queries, see Search Best Practices. For web_fetch, the optional target_content description steers the model toward concrete extraction goals (for example, a specific API or section); omit it when a full-page extract is enough.

Handling the search_web tool call

When your LLM invokes search_web, forward the arguments to the Search API:
curl -X POST https://api.parallel.ai/v1beta/search \
  -H "Content-Type: application/json" \
  -H "x-api-key: $PARALLEL_API_KEY" \
  -d '{
    "objective": "Python 3.12 asyncio.TaskGroup exception propagation behavior",
    "search_queries": [
      "asyncio TaskGroup exception propagation",
      "python 3.12 TaskGroup error handling",
      "TaskGroup nested exception behavior docs"
    ],
    "mode": "fast"
  }'
Return the result as a JSON string in the tool response message back to the LLM.
These examples set mode to "fast" for predictable low-latency tool responses. See Search Modes for other options. You can also configure excerpts, max_results, and other parameters server-side — see the API Reference for the full list.

Handling the web_fetch tool call

When your LLM invokes web_fetch, forward urls and map target_content to objective on the Extract API. The examples below request excerpts (focused markdown) and omit full page content for more token-efficient tool responses; adjust excerpts and full_content server-side as needed.
curl -X POST https://api.parallel.ai/v1beta/extract \
  -H "Content-Type: application/json" \
  -H "x-api-key: $PARALLEL_API_KEY" \
  -d '{
    "urls": ["https://docs.python.org/3/library/asyncio-task.html"],
    "objective": "asyncio.TaskGroup exception propagation",
    "excerpts": true,
    "full_content": false
  }'
Return the result as a JSON string in the tool response message back to the LLM.

Framework Guides

For a full end-to-end integration walkthrough with a specific framework:
  • OpenAI Tool Calling — complete example with GPT models
  • LangChain — integration with LangChain agents
  • MCP — auto-provided tool definition, no setup needed