# How Agent Reach Multi-Backend Routing Works for Twitter and Bilibili

> Discover how Agent Reach multi-backend routing optimizes requests for Twitter and Bilibili. Learn about automatic backend selection and user overrides for seamless performance.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: internals
- Published: 2026-06-16

---

**Agent Reach treats each social platform as a Channel that maintains an ordered list of backend candidates, automatically routing requests to the first healthy backend while supporting user overrides via environment variables or configuration files.**

The open-source Agent Reach project abstracts platforms like Twitter and Bilibili into modular Channel classes that reside in `agent_reach/channels/`. Each channel implements a sophisticated multi-backend routing system that probes multiple implementations—ranging from CLI tools to HTTP APIs—and automatically selects the first healthy candidate, ensuring robust operation even when specific dependencies are unavailable.

## The Routing Contract in the Base Channel Class

The routing logic lives in the abstract `Channel` base class defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py). This class establishes the contract that all platform-specific channels must follow to ensure consistent behavior across the codebase.

### Ordered Candidate Lists and User Overrides

Every channel defines a class attribute `backends` that lists preferred backends in priority order. Users can force a specific backend using the configuration key `<channel>_backend` or the environment variable `<CHANNEL>_BACKEND`.

The `ordered_backends()` method (lines 45-59 of [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py)) reorders the list so that the overridden backend moves to the front while preserving other candidates as fallbacks:

```python

# https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py#L45-L59

```

### Health Probing and Selection Rules

During the `check()` method, a channel iterates over `ordered_backends()`. For each candidate, it runs a lightweight probe that returns a tuple `(status, message)` where `status` can be `"ok"`, `"warn"`, `"error"`, or `"off"`.

The selection rule prioritizes the first candidate reporting `"ok"`. If no candidate reports `"ok"`, the first `"warn"` is selected. If only `"error"` results exist, the channel reports an error state. The chosen backend is stored in `self.active_backend`.

## Twitter Channel Implementation

The `TwitterChannel` in [`agent_reach/channels/twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py) demonstrates a concrete implementation of the routing contract with three distinct backend options.

### Backend Candidates and Priority

The channel declares its candidates as a class attribute (lines 9-13):

```python
backends = ["twitter-cli", "OpenCLI", "bird CLI (legacy)"]

```

### Health Check Logic

The `check()` method (lines 29-38) calls `ordered_backends()` to respect any user override, then probes each candidate in sequence:

- **`twitter-cli`** — The `_check_twitter_cli()` method (lines 66-84) runs `twitter status` and inspects the output for `"ok: true"` (fully usable) or `"not_authenticated"` (installed but not logged in).
- **`OpenCLI`** — The `_check_opencli()` method calls `opencli_status()` to verify the OpenCLI bridge.
- **`bird CLI`** — The `_check_bird()` method runs `bird check` or `birdx check` to verify the legacy tool.

The method walks the findings list, selecting the first `"ok"` or `"warn"` backend and assigning it to `self.active_backend` (lines 43-48). If none are present, it returns `"warn"` with installation instructions.

## Bilibili Channel Implementation

The `BilibiliChannel` in [`agent_reach/channels/bilibili.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/bilibili.py) follows the same pattern with platform-specific adaptations for the Chinese video platform.

### Backend Hierarchy and API Fallback

The channel defines three candidates (lines 35-40):

```python
backends = ["bili-cli", "OpenCLI", "B站搜索 API"]

```

### Error Handling with Context

The `check()` method (lines 51-58) probes each candidate with nuanced error handling:

- **`bili-cli`** — The `_check_bili_cli()` method runs `bili --version` to verify the command exists and is executable.
- **`OpenCLI`** — Reuses the generic `_check_opencli()` helper from the base infrastructure.
- **Bilibili Search API** — The `_check_search_api()` method (lines 24-32) performs a direct HTTP request to Bilibili's public search endpoint.

Unlike the Twitter implementation, the Bilibili channel accumulates `broken_notes` when candidates report `"error"`. If a later candidate succeeds with `"ok"` or `"warn"`, these error notes are appended to the final message, providing users with visibility into fallback failures (lines 62-70). If no backends are reachable, the method returns `"off"` with recommendations to install `bili-cli` or OpenCLI.

## Code Example: Configuring and Checking Channels

The following example demonstrates how to instantiate channels and trigger the backend selection process:

```python
from agent_reach.channels.twitter import TwitterChannel
from agent_reach.channels.bilibili import BilibiliChannel
from agent_reach.config import Config

cfg = Config()                     # reads env vars / yaml overrides

tw = TwitterChannel()
bl = BilibiliChannel()

# Run health checks – each will probe its backends and select the active one.

tw_status, tw_msg = tw.check(cfg)          # e.g. ("ok", "twitter-cli 完整可用…")

bl_status, bl_msg = bl.check(cfg)          # e.g. ("warn", "OpenCLI 可用…")

print("Twitter active backend:", tw.active_backend)   # → "twitter-cli"

print("Bilibili active backend:", bl.active_backend) # → "OpenCLI"

```

Running this on a system with `twitter-cli` installed but `bili-cli` missing yields:

```bash
Twitter active backend: twitter-cli
Bilibili active backend: OpenCLI

```

Users can override backend selection via environment variable:

```bash
export TWITTER_BACKEND=bird

```

Or via YAML configuration:

```yaml
twitter_backend: bird

```

The `ordered_backends()` method promotes `bird` to the front of the list, causing the channel to probe `bird CLI (legacy)` first while keeping other candidates available as fallbacks.

## Summary

- **Agent Reach abstracts social platforms as Channel classes** with ordered backend lists defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py).
- **User overrides are supported** via `<channel>_backend` configuration keys or `<CHANNEL>_BACKEND` environment variables, processed by `ordered_backends()` at lines 45-59.
- **Health probing iterates** through candidates in [`twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/twitter.py) (lines 29-38) and [`bilibili.py`](https://github.com/Panniantong/Agent-Reach/blob/main/bilibili.py) (lines 51-58), executing platform-specific checks via `_check_*` methods.
- **Selection prioritizes `"ok"` status**, falling back to `"warn"` if necessary, and stores the result in `self.active_backend`.
- **Bilibili provides enhanced error context** by appending failure notes from unsuccessful probes to the final success message.

## Frequently Asked Questions

### How do I force Agent Reach to use a specific backend instead of auto-selecting?

Set the `<CHANNEL>_BACKEND` environment variable (e.g., `TWITTER_BACKEND=bird`) or add `<channel>_backend: <name>` to your configuration file. The `ordered_backends()` method in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) automatically reorders the candidate list to prioritize your selection while keeping alternatives available as fallbacks.

### What happens if all backends for a channel report errors?

If no backend reports `"ok"` or `"warn"`, the channel returns an `"error"` status (or `"off"` in the Bilibili implementation). The `check()` method stores diagnostic messages in the returned tuple, often including installation instructions or specific failure reasons from the last attempted probe.

### Can I add custom backends to existing channels like Twitter or Bilibili?

Yes. Each channel defines its `backends` list as a class attribute (e.g., lines 9-13 in [`twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/twitter.py)). You can subclass `TwitterChannel` or `BilibiliChannel` to override this list, or extend the base `Channel` class to implement new platforms following the same routing contract established in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py).

### How does Agent Reach detect if a CLI tool is properly authenticated versus merely installed?

Implementation varies by backend. For example, the Twitter channel's `_check_twitter_cli()` method (lines 66-84) parses the output of `twitter status` to distinguish between `"ok: true"` (fully usable) and `"not_authenticated"` (installed but requiring login). Similarly, the Bilibili channel checks version strings and executable permissions to verify operational readiness before marking a backend as available.