Skip to main content

A LangChain integration for Parallel Web AI services, including Chat and Search.

Project description

LangChain Parallel Web Integration

This package provides LangChain integrations for Parallel, enabling real-time web research and AI capabilities through an OpenAI-compatible interface.

Features

  • Chat Models: ChatParallel (formerly ChatParallelWeb) — real-time web research chat completions, with citations and structured output on the research models.
  • Search Tool: ParallelSearchTool (formerly ParallelWebSearchTool) — direct access to Parallel's GA /v1/search endpoint.
  • Extract Tool: ParallelExtractTool — clean content extraction from web pages via /v1/extract.
  • Streaming Support: Real-time response streaming on chat.
  • Async/Await: Full asynchronous operation support.
  • LangChain Integration: Pydantic input schemas, bind-able tools, with_structured_output(), lc_serializable.

Note: the older names (ChatParallelWeb, ParallelWebSearchTool) continue to work as aliases.

Installation

pip install langchain-parallel

Setup

  1. Get your API key from Parallel
  2. Set your API key as an environment variable:
export PARALLEL_API_KEY="your-api-key-here"

Chat Models

ChatParallelWeb

The ChatParallelWeb class provides access to Parallel's Chat API, which combines language models with real-time web research capabilities.

Picking a model

Model Latency Citations (response_metadata["basis"]) Structured output
speed (default) ~3s none not supported
lite seconds yes with_structured_output()
base seconds–minutes yes with_structured_output()
core minutes yes (most thorough) with_structured_output()

Basic Usage

from langchain_core.messages import HumanMessage, SystemMessage
from langchain_parallel.chat_models import ChatParallelWeb

chat = ChatParallelWeb(model="speed")

messages = [
    SystemMessage(content="You are a helpful assistant with access to real-time web information."),
    HumanMessage(content="What are the latest developments in artificial intelligence?"),
]

response = chat.invoke(messages)
print(response.content)
# Citations on the research models (lite/base/core):
print(response.response_metadata.get("basis"))

Structured output (research models)

from pydantic import BaseModel, Field
from langchain_parallel import ChatParallelWeb

class Founder(BaseModel):
    name: str = Field(description="Full name of the founder")
    company: str = Field(description="Company they founded")

structured = ChatParallelWeb(model="lite").with_structured_output(Founder)
result = structured.invoke([("human", "Who founded SpaceX?")])
print(result)
# Founder(name='Elon Musk', company='SpaceX')

Streaming Responses

# Stream responses for real-time output
for chunk in chat.stream(messages):
    if chunk.content:
        print(chunk.content, end="", flush=True)

Async Operations

import asyncio

async def main():
    # Async invoke
    response = await chat.ainvoke(messages)
    print(response.content)
    
    # Async streaming
    async for chunk in chat.astream(messages):
        if chunk.content:
            print(chunk.content, end="", flush=True)

asyncio.run(main())

Conversation Context

# Maintain conversation history
messages = [
    SystemMessage(content="You are a helpful assistant.")
]

# First turn
messages.append(HumanMessage(content="What is machine learning?"))
response = chat.invoke(messages)
messages.append(response)  # Add assistant response

# Second turn with context
messages.append(HumanMessage(content="How does it work?"))
response = chat.invoke(messages)
print(response.content)

Configuration Options

Parameter Type Default Description
model str "speed" Parallel model name
api_key Optional[SecretStr] None API key (uses PARALLEL_API_KEY env var if not provided)
base_url str "https://api.parallel.ai" API base URL
temperature Optional[float] None Sampling temperature (ignored by Parallel)
max_tokens Optional[int] None Max tokens (ignored by Parallel)
timeout Optional[float] None Request timeout
max_retries int 2 Max retry attempts

Real-Time Web Research

Parallel's Chat API provides real-time access to web information, making it perfect for:

  • Current Events: Get up-to-date information about recent events
  • Market Data: Access current stock prices, market trends
  • Research: Find the latest research papers, developments
  • Weather: Get current weather conditions
  • News: Access breaking news and recent articles
# Example: Current events
messages = [
    SystemMessage(content="You are a research assistant with access to real-time web data."),
    HumanMessage(content="What happened in the stock market today?")
]

response = chat.invoke(messages)
print(response.content)  # Gets real-time market information

Integration with LangChain

Chains

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# Create a chain
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful research assistant with access to real-time web information."),
    ("human", "{question}")
])

chain = prompt | chat | StrOutputParser()

# Use the chain
result = chain.invoke({"question": "What are the latest AI breakthroughs?"})
print(result)

Agents

Parallel's Chat API does not support tool calling, so ChatParallelWeb cannot be the LLM that drives an agent. Use it as a research assistant inside a chain (above), or use Parallel's tools (ParallelWebSearchTool, ParallelExtractTool) with a tool-calling chat model (Anthropic, OpenAI, etc.) — see the Tool Usage in Agents section below.

Search API

The Search API provides direct access to Parallel's web search capabilities, returning structured, compressed excerpts optimized for LLM consumption.

ParallelWebSearchTool

The search tool provides direct access to Parallel's Search API:

from langchain_parallel import ParallelWebSearchTool

search_tool = ParallelWebSearchTool()

result = search_tool.invoke({
    "search_queries": ["renewable energy 2026", "solar power developments"],
    "max_results": 5,
})

print(result["search_id"], len(result["results"]))
for r in result["results"]:
    print(r["title"], "-", r["url"])

Search API Configuration

Parameter Type Default Description
objective Optional[str] None Natural-language description of research goal (≤5000 chars).
search_queries Optional[List[str]] None 1-5 keyword queries (3-6 words each, ≤200 chars). Required by the GA /v1 endpoint; if omitted, the call routes to the deprecated /v1beta endpoint with a DeprecationWarning (slated for removal in 0.4.0). Pair with an optional objective for best results.
max_results int 10 Maximum results to return (1–40).
excerpts Optional[ExcerptSettings] None Per-result excerpt-size cap.
max_chars_total Optional[int] None Cap on total excerpt characters across all results.
mode Optional[Literal["basic", "advanced"]] None (API default advanced) basic is lower-latency; advanced is higher quality with more retrieval and compression. Legacy values fast, one-shot (→ basic) and agentic (→ advanced) are accepted with a DeprecationWarning.
source_policy Optional[SourcePolicy] None Domain include/exclude lists and freshness floor (after_date).
fetch_policy Optional[FetchPolicy] None Cache vs live-fetch policy (e.g. FetchPolicy(max_age_seconds=86400, timeout_seconds=60)).
location Optional[str] None ISO 3166-1 alpha-2 country code (e.g. "us", "gb").
client_model Optional[str] None Identifier of the calling LLM, used for model-specific result optimizations.
session_id Optional[str] None Shared id grouping related Search/Extract calls in one task.
api_key Optional[SecretStr] None API key (uses PARALLEL_API_KEY env var if not provided).
base_url str "https://api.parallel.ai" API base URL.

Search with Specific Queries

You can provide specific search queries instead of an objective:

# Search with specific queries
result = search_tool.invoke({
    "search_queries": [
        "renewable energy 2024",
        "solar power developments",
        "wind energy statistics"
    ],
    "max_results": 8
})

Tool Usage in Agents

Use the search tool with a tool-calling chat model (e.g. Anthropic Claude or OpenAI) and create_agent. Note that Parallel's own Chat API does not currently support tool calling, so use a different model class for the agent's LLM and use Parallel as a tool.

from langchain.agents import create_agent
from langchain_parallel import ParallelWebSearchTool, ParallelExtractTool

agent = create_agent(
    "anthropic:claude-haiku-4-5",
    tools=[ParallelWebSearchTool(), ParallelExtractTool()],
    system_prompt=(
        "You are a research assistant. Use parallel_web_search to find "
        "current information and parallel_extract to read specific pages."
    ),
)

result = agent.invoke({"messages": [("human", "Latest AI breakthroughs?")]})
print(result["messages"][-1].content)

See docs/demo_agent.ipynb for a full walkthrough.

Extract API

The Extract API provides clean content extraction from web pages, returning structured markdown-formatted content optimized for LLM consumption.

ParallelExtractTool

The extract tool extracts clean, structured content from web pages:

from langchain_parallel import ParallelExtractTool

# Initialize the extract tool
extract_tool = ParallelExtractTool()

# Extract from a single URL
result = extract_tool.invoke({
    "urls": ["https://en.wikipedia.org/wiki/Artificial_intelligence"]
})

print(result)
# [
#     {
#         "url": "https://en.wikipedia.org/wiki/Artificial_intelligence",
#         "title": "Artificial intelligence - Wikipedia",
#         "content": "# Artificial intelligence\n\nMain content in markdown...",
#         "publish_date": "2024-01-15"  # Optional
#     }
# ]

Extract with Search Objective and Advanced Options

Focus extraction on specific topics using search objectives, with control over excerpts and fetch policy:

# Extract content focused on a specific objective with excerpt settings
result = extract_tool.invoke({
    "urls": ["https://en.wikipedia.org/wiki/Artificial_intelligence"],
    "search_objective": "What are the main applications and ethical concerns of AI?",
    "excerpts": {"max_chars_per_result": 2000},
    "full_content": False,
    "fetch_policy": {
        "max_age_seconds": 86400,
        "timeout_seconds": 60,
        "disable_cache_fallback": False
    }
})

# Returns relevant excerpts focused on the objective
print(result[0]["excerpts"])  # List of relevant text excerpts

Extract with Search Queries

Extract content relevant to specific search queries:

# Extract content focused on specific queries
result = extract_tool.invoke({
    "urls": [
        "https://en.wikipedia.org/wiki/Machine_learning",
        "https://en.wikipedia.org/wiki/Deep_learning"
    ],
    "search_queries": ["neural networks", "training algorithms", "applications"],
    "excerpts": True
})

for item in result:
    print(f"Title: {item['title']}")
    print(f"Relevant excerpts: {len(item['excerpts'])}")
    print()

Content Length Control

# Control full content length per extraction
result = extract_tool.invoke({
    "urls": ["https://en.wikipedia.org/wiki/Quantum_computing"],
    "full_content": {"max_chars_per_result": 3000}
})

print(f"Content length: {len(result[0]['content'])} characters")

Extract API Configuration

Parameter Type Default Description
urls List[str] Required List of URLs to extract content from (up to 20 per request).
search_objective Optional[str] None Natural language objective to focus extraction (≤5000 chars).
search_queries Optional[List[str]] None Specific keyword queries to focus extraction.
excerpts Union[bool, ExcerptSettings] True In v1 GA, excerpts are always returned; the bool is kept for backward compatibility, and ExcerptSettings(max_chars_per_result=…) controls per-result size.
full_content Union[bool, FullContentSettings] False Include full page content in addition to excerpts.
max_chars_total Optional[int] None Cap on total excerpt characters across all results. Does not affect full_content.
fetch_policy Optional[FetchPolicy] None Cache vs live content policy.
client_model Optional[str] None Identifier of the calling LLM, used for model-specific result optimizations.
session_id Optional[str] None Shared id grouping related Search/Extract calls in one task.
max_chars_per_extract Optional[int] None Tool-level default cap on full_content size; only applied when full_content=True.
api_key Optional[SecretStr] None API key (uses PARALLEL_API_KEY env var if not provided).
base_url str "https://api.parallel.ai" API base URL.

Error Handling

The extract tool gracefully handles failed extractions:

# Mix of valid and invalid URLs
result = extract_tool.invoke({
    "urls": [
        "https://en.wikipedia.org/wiki/Python_(programming_language)",
        "https://this-domain-does-not-exist-12345.com/"
    ]
})

for item in result:
    if "error_type" in item:
        print(f"Failed: {item['url']} - {item['content']}")
    else:
        print(f"Success: {item['url']} - {len(item['content'])} chars")

Async Extract

import asyncio

async def extract_async():
    result = await extract_tool.ainvoke({
        "urls": ["https://en.wikipedia.org/wiki/Artificial_intelligence"]
    })
    return result

# Run async extraction
result = asyncio.run(extract_async())

Error Handling

try:
    response = chat.invoke(messages)
    print(response.content)
except ValueError as e:
    if "API key not found" in str(e):
        print("Please set your PARALLEL_API_KEY environment variable")
    else:
        print(f"API Error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Examples

See the examples/ and docs/ directories for complete working examples:

  • examples/chat_example.py - Chat model usage examples
  • docs/search_tool.ipynb - Search tool examples and tutorials
  • docs/extract_tool.ipynb - Extract tool examples and tutorials
  • Basic synchronous usage
  • Streaming responses
  • Async operations
  • Conversation management
  • Tool usage in agents

API Compatibility

This integration provides access to two Parallel APIs:

Chat API Compatibility

The Chat API uses Parallel's OpenAI-compatible interface:

  • Supported: Messages, streaming, response_format (JSON schema)
  • Ignored: temperature, max_tokens, top_p, stop, most OpenAI-specific parameters
  • Not Supported: Function calling, multimodal inputs (images/audio), tool usage

Search API Features

The Search API provides direct web search capabilities:

  • Supported: Objective-based search, query-based search, two processor tiers
  • Output: Structured results with URLs, titles, and relevant excerpts
  • Integration: Works with LangChain tools, retrievers, and agents

Extract API Features

The Extract API provides clean content extraction from web pages:

  • Supported: Batch URL extraction, content length control, markdown formatting
  • Output: Clean, structured content with metadata (title, publish date, etc.)
  • Integration: Works with LangChain tools and agents
  • Error Handling: Gracefully handles failed extractions with detailed error info

Performance & Rate Limits

Chat API

  • Default Rate Limit: 300 requests per minute
  • Performance: 3 second p50 TTFT (time to first token) with streaming
  • Use Cases: Interactive chat, real-time responses

Search API

  • Default Rate Limit: Contact Parallel for rate limit information
  • Performance: Varies based on query complexity and result count
  • Use Cases: Real-time web information, research, content discovery

Production Usage

Contact Parallel for:

  • Higher rate limits
  • Enterprise features
  • Custom configurations

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Documentation

Getting Help

Changelog

See CHANGELOG.md for the full version history.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

langchain_parallel-0.3.0.tar.gz (27.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

langchain_parallel-0.3.0-py3-none-any.whl (26.7 kB view details)

Uploaded Python 3

File details

Details for the file langchain_parallel-0.3.0.tar.gz.

File metadata

  • Download URL: langchain_parallel-0.3.0.tar.gz
  • Upload date:
  • Size: 27.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.14.0 Darwin/24.5.0

File hashes

Hashes for langchain_parallel-0.3.0.tar.gz
Algorithm Hash digest
SHA256 42fd285dce8c69164ee8b54d4242b7acff95cb57f41c542c9517556fcfcfdde1
MD5 ddd5cab10414ef04e28fa42b985d1275
BLAKE2b-256 3562b27081dc7902fc3ef1f78f7b1369ccce561877c18f4b20958e5ae2808b04

See more details on using hashes here.

File details

Details for the file langchain_parallel-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: langchain_parallel-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 26.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.14.0 Darwin/24.5.0

File hashes

Hashes for langchain_parallel-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 28bf8db10285063d14294925fa3684e3885bc3b0b4c22992da3302d3938538f0
MD5 7d6c56df05d73bcb5f19d5cec49c9d0b
BLAKE2b-256 19705bb3e1e0ab10f6accdf68790b236295e0ca8ca81199e308eaa84760dc864

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page