agentscope-ai / agentscope-ai/QwenPaw

[Bug] WeCom channel streams character-by-character slowly (150ms throttle makes it feel sluggish)

オープン
#7,507 コメント 2 件 リアクション 0 件 担当者 1 名 @hongxicheng に割り当て済み GitHub で見る
主要言語
Python
スター
34.9k
フォーク
3.1k
平均マージ
1日 15時間
マージ済み PR(30日)
225

説明

## [Bug] WeCom channel streams character-by-character slowly while WeChat shows full segments instantly

### Summary

The WeCom channel implements real-time streaming via `reply_stream` (WebSocket), but characters appear on screen much slower than the WeChat channel. The WeChat channel has no streaming support at all and instead sends completed text segments — which paradoxically *feels* much faster to users.

### Environment

- QwenPaw version: 2.1.0
- Channels compared: `wecom` (WeCom AI Bot, WebSocket) vs `wechat` (WeChat iLink Bot, HTTP long-poll)
- Model: any streaming-capable LLM (e.g. DeepSeek / Qwen)

### Reproduction Steps

1. Start an agent and connect both channels simultaneously
2. Send the same prompt: "请写一段 500 字的介绍"
3. Observe the output rate on each client:
- **WeChat**: receives the full reply in one HTTP request after the agent finishes — appears as one quick "burst"
- **WeCom**: receives incremental `reply_stream` deltas, one character at a time, visibly slower

### Root Cause Analysis

Two factors compound:

#### 1. Aggressive throttling in `wecom/channel.py`

```python
# wecom/channel.py:134
class WecomChannel(BaseChannel):
channel = "wecom"
_STREAM_DELTA_MIN_INTERVAL_S = 0.15 # ← 150ms minimum gap between delta pushes
```

Each LLM token is throttled by this 150ms floor (see `base.py:786-792`). Fast-emitting models are forced to drop deltas, so the perceived throughput is capped.

#### 2. No streaming on the WeChat side

```python
# wechat/channel.py — WeChatChannel has NO streaming hooks
class WeChatChannel(BaseChannel):
# no _STREAM_DELTA_MIN_INTERVAL_S
# no on_streaming_delta implementation
```

The WeChat channel inherits `BaseChannel` but never sets `streaming_enabled=True`, so it accumulates the full text and sends via `_send_text_direct` + `split_text`. This *feels* fast because the user only sees the moment of delivery, not the build-up.

### Expected vs Actual Behavior

| Channel | Expected | Actual |
|---------|----------|--------|
| WeChat | Smooth typing animation | Whole-text "burst" (no animation) |
| WeCom | Smooth typing animation similar to typing-indicator UIs | Visible lag, one char per 150ms+, feels broken |

### Suggested Fixes

#### Option A — Reduce throttling (minimal change)

```diff
# wecom/channel.py
- _STREAM_DELTA_MIN_INTERVAL_S = 0.15
+ _STREAM_DELTA_MIN_INTERVAL_S = 0.04 # 40ms, closer to human typing speed
```

#### Option B — Make throttling configurable (recommended)

Add a config option to `channels.wecom.*` in the channel config so admins can tune per deployment:

```python
# In config schema
class WecomChannelConfig:
stream_delta_min_interval_ms: int = 40 # was 150
stream_delta_batch_size: int = 4 # new: batch N chars before pushing
```

Then use it in `on_streaming_delta`:

```python
async def on_streaming_delta(self, request, to_handle, event, send_meta, stream_type, accumulated_text=""):
# Skip push if batch not full
if len(accumulated_text) % self._stream_delta_batch_size != 0:
return
# ... rest of existing logic
```

#### Option C — Smart batching by token boundary

Detect Chinese punctuation / sentence boundaries and flush at natural pauses:

```python
def _should_flush(self, text: str) -> bool:
return text.endswith(("。", "!", "?", "\n")) or len(text) % 6 == 0
```

This gives "sentence-by-sentence" typing instead of "char-by-char" — closer to human rhythm.

#### Option D — Add streaming to WeChat channel

Implement `on_streaming_delta` for `WeChatChannel` so it can also push incremental updates (WeChat iLink Bot supports `typing` indicators that hint at in-progress replies).

### Test Plan

1. Apply Option B
2. With default `stream_delta_min_interval_ms=40`, time a 500-char reply:
- WeCom should display all characters within ~2-3s of LLM finish
- First token should reach the client within 200-300ms of emission
3. Verify no rate-limit errors from WeCom API (the limit is ~10 msg/s per stream)
4. Compare perceived smoothness against WeChat baseline

### Related Code

- `qwenpaw/app/channels/wecom/channel.py:134` — `_STREAM_DELTA_MIN_INTERVAL_S = 0.15`
- `qwenpaw/app/channels/base.py:786-792` — delta throttling logic
- `qwenpaw/app/channels/base.py:593-594` — base defaults (`0.0`/`5.0`)
- `qwenpaw/app/channels/wechat/channel.py` — missing streaming impl

### Environment / Versions

- OS: any
- QwenPaw: 2.1.0
- Python: 3.11
- Model providers tested: DeepSeek, Qwen (both streaming-capable)

### Priority

Medium — visible UX regression on WeCom channel; affects perceived agent responsiveness for end users.

### Labels

`bug`, `enhancement`, `channel:wecom`, `ux`, `streaming`

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。