> SpecStream is the live web data engine for teams and agents. This is the Markdown copy of https://specstream.ai/docs/integrations/tongyi-deepresearch. Every page, with what SpecStream does and costs: https://specstream.ai/llms.txt

# Tongyi DeepResearch

Run Tongyi DeepResearch's search and visit tools on SpecStream by changing the Serper host in `tool_search.py` and the Jina Reader address in `tool_visit.py`. One SpecStream key and one balance pay for every search and every page the agent reads. The model, the prompts and the summary model stay as they are.

[SpecStream for Tongyi DeepResearchAgent frameworks & builders](https://specstream.ai/integrations/tongyi-deepresearch.md)

## What you need

-   Tongyi DeepResearch cloned from GitHub, with `.env` copied from `.env.example` as its README shows. The steps edit two files in its `inference` folder.
-   A SpecStream key. [Get your key](https://specstream.ai/workspace/search?route=serper&utm_source=tongyi-deepresearch&utm_medium=howto) on the Search API screen of your SpecStream workspace. New accounts start with $10 of credit, no card.

1.  1

    ## 1. Point the search tool at SpecStream

    Tongyi DeepResearch has no setting for its search address. The `search` tool in `inference/tool_search.py` opens a connection to `google.serper.dev`, posts each query to `/search`, and sends the key from `SERPER_KEY_ID`.

    From the repository root, change the host and the path to SpecStream's Serper route, and have the tool read its key from a variable of its own. The Scholar tool keeps `SERPER_KEY_ID`, as step 3 explains.

    Shell, in DeepResearch

    ```bash
    # On macOS, write sed -i '' in place of sed -i
    sed -i \
      -e 's#HTTPSConnection("google.serper.dev")#HTTPSConnection("api.specstream.ai")#' \
      -e 's#"POST", "/search"#"POST", "/serper/search"#' \
      -e "s#os.environ.get('SERPER_KEY_ID')#os.environ.get('SPECSTREAM_API_KEY')#" \
      inference/tool_search.py
    ```

2.  2

    ## 2. Point the visit tool at SpecStream's Jina Reader route

    `jina_readpage` in `inference/tool_visit.py` reads a page by calling `https://r.jina.ai/` followed by the page's address, with `JINA_API_KEYS` as a Bearer token. Change the prefix to SpecStream's Jina Reader route. The page's address stays on the end, and the key is sent as before.

    Shell, in DeepResearch

    ```bash
    sed -i 's#https://r.jina.ai/#https://api.specstream.ai/jina/#' inference/tool_visit.py
    
    grep -n "specstream" inference/tool_search.py inference/tool_visit.py
    ```

3.  3

    ## 3. Set the keys in .env

    In `.env`, add `SPECSTREAM_API_KEY` and set `JINA_API_KEYS` to the same SpecStream key. `run_react_infer.sh` exports every line of `.env` before it starts the run, so both tools read them.

    Keep `SERPER_KEY_ID` as it was. The `google_scholar` tool in `inference/tool_scholar.py` still posts to Serper's `/scholar` with that key.

    .env

    ```bash
    SPECSTREAM_API_KEY=YOUR_SPECSTREAM_KEY
    JINA_API_KEYS=YOUR_SPECSTREAM_KEY
    SERPER_KEY_ID=YOUR_SERPER_KEY
    ```

4.  4

    ## 4. Run the agent

    Set `MODEL_PATH`, `DATASET` and `OUTPUT_PATH` in `.env` as the README asks, then start the run. Each `search` query and each page the `visit` tool reads now goes through SpecStream, and each call is in your account's request log with its route as the endpoint.

    Shell, in DeepResearch

    ```bash
    cd inference
    bash run_react_infer.sh
    ```

## What changes and what stays

Each SpecStream route answers in the shape the tools already read. The Serper route returns `organic[]` with `title`, `link`, `snippet` and `position`, with `date` when the page states one, and the `search` tool formats those into its numbered list. The tool still sends `gl` and `hl`: `cn` and `zh-cn` for a query in Chinese, `us` and `en` otherwise. SpecStream searches in that country and language. The tool names no count, so each query gets 10 results.

Called with no `Accept` header, as `visit` calls it, the Jina Reader route answers in Jina's text form: `Title:`, `URL Source:`, then the page's text as Markdown. `visit` passes that text to the summary model at `API_BASE` as before, so `API_KEY`, `API_BASE` and `SUMMARY_MODEL_NAME` stay as they are. The README's OpenRouter setup changes only the model calls in `react_agent.py`, so it works with these edits too.

## What each call costs

-   Each query in a `search` call is one Search API call through a drop-in address: $1 per 1,000 searches of up to 10 results. The tool takes an array of queries, so a call with three queries is three searches. A search that returns no results costs nothing.
-   Each page `visit` reads is one Extract API page at $0.80 per 1,000 pages. A page that gives no text is not charged.
-   A page SpecStream cannot read answers `422` and costs nothing. `visit` tries such a page up to 24 times, 3 tries in each of 8 attempts, so a blocked page slows that step and adds nothing to the bill.
-   `MAX_LLM_CALL_PER_RUN` caps the model at 100 calls a question by default, and that bounds how many tool calls one question can make.
-   Calls come out of your balance with no quote and no approval, and every call, charged or not, is in your request log.

## Why run Tongyi DeepResearch on SpecStream

The README asks for a Serper key for search and a Jina key for page reading, each with its own account and bill. On SpecStream one key and one balance pay for both, and one request log shows every query and every page a run made, which helps when you compare runs on a benchmark.

SpecStream's search API scores 97.9 F-score on all 1,000 SimpleQA Verified questions and 64.0 item F1 on all 200 WideSearch tasks. Scores and method are on the [benchmarks page](https://specstream.ai/benchmarks.md).

## Limits and errors

-   With a wrong key the Serper route answers `401` with no `organic` field, and `search` tells the model `No results found for` the query. When every search comes back empty, check `SPECSTREAM_API_KEY`.
-   `visit` returns `[visit] Failed to read page.` once its tries run out. If it says that for every page, check `JINA_API_KEYS`.
-   When the account has used its calls for the minute, SpecStream answers `429` with `Retry-After`, and nothing is charged. `search` does not wait and reports no results for that query; `visit` tries again after half a second.

## Go back

Run `git checkout -- inference/tool_search.py inference/tool_visit.py`, put your Jina key back in `JINA_API_KEYS`, and start the run again. Settings for other Serper and Jina clients are on [Moving off Serper](https://specstream.ai/migrate/serper.md) and [Moving off Jina Reader](https://specstream.ai/migrate/jina.md). Questions: [support@specstream.ai](mailto:support@specstream.ai).

## More

[SpecStream for Tongyi DeepResearch](https://specstream.ai/integrations/tongyi-deepresearch.md) covers what it does in Tongyi DeepResearch on one page. Every other tool has its guide in [Connect your tools](https://specstream.ai/docs/integrations.md). You see the most a request can cost before it starts, and the matches are paid from your balance. [Billing](https://specstream.ai/docs/billing.md) has the details. For help, email [support@specstream.ai](mailto:support@specstream.ai).
