cardkit
feishu.streaming.cardkit
¶
CardKit v1 流式卡片助手:将增量生成的 LLM 文本持续推送到一张已发送的卡片中。
整个生命周期由四次请求构成,全部经由 client.request 发出,因此自动继承令牌刷新、
重试与限流等底层处理:
POST cardkit/v1/cards:创建一个card_json卡片实体(streaming_mode=True)。POST im/v1/messages:以interactive消息类型发送该卡片。PUT .../elements/{id}/content:流式写入**完整的累积文本**(而非增量), 并携带严格递增的sequence以及每次刷新独立生成的uuid。PATCH .../settings:收尾(streaming_mode=False)。该步骤**必须执行**: 即使生产者抛出异常也会运行,因为卡片在 10 分钟后会自动关闭流式状态, 未收尾的流会白白浪费卡片实体。
限流约定:内容写入与收尾补丁共享同一个单调递增的 sequence
(由 [feishu.streaming.cardkit._SequenceCounter][] 通过 asyncio 锁保证原子性)。
写入带去抖(debounce,默认 0.25 秒,约 4 次/秒,远低于飞书 10 次/秒/卡片的上限):
只有在去抖间隔已过且缓冲区内容发生变化时才会真正发出写入,并在收尾前强制刷新一次。
测试注入接口:feishu.streaming.cardkit.stream_card 接受 _now/_new_uuid
参数(默认为模块级的 time.monotonic / _new_uuid)。测试可传入手动时钟,
使去抖行为完全确定且不产生任何真实等待。
飞书文档
stream_card
async
¶
stream_card(client: FeishuClient, tokens: AsyncIterator[str], *, receive_id: str | None = None, receive_id_type: str | None = None, reply_to_message_id: str | None = None, element_id: str = 'md', debounce_s: float = 0.25, header: str | None = None, template: str | None = None, _now: Callable[[], float] = _now, _new_uuid: Callable[[], str] = _new_uuid) -> str
驱动 CardKit v1 流式生命周期,并返回创建出的 card_id。
先创建并发送一张初始流式卡片,随后将逐 token 累积的**完整文本**流式写入
element_id 指定的 markdown 元素(带去抖限流、序号单调递增、每次写入以 uuid 标识),
最后**始终**执行收尾(streaming_mode=False)。即使 token 生产者抛出异常也会收尾:
卡片的流式状态在 10 分钟后会自动关闭,若不主动收尾,泄漏的开放流会白白浪费卡片实体。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
FeishuClient
|
飞书客户端,须提供 |
必需 |
|
AsyncIterator[str]
|
逐段产出文本的异步迭代器,通常为 LLM 的流式输出。每段会被追加到累积文本上。 |
必需 |
|
str | None
|
消息接收者 ID,其类型由 |
None
|
|
str | None
|
接收者 ID 类型,如 |
None
|
|
str | None
|
以回复形式发送时的目标消息 |
None
|
|
str
|
流式写入目标 markdown 元素的 ID,默认为 |
'md'
|
|
float
|
去抖间隔(秒),默认为 |
0.25
|
|
str | None
|
卡片标题文本。为 |
None
|
|
str | None
|
标题栏配色模板(如 |
None
|
|
Callable[[], float]
|
单调时钟函数,仅供测试注入以使去抖确定化,生产调用请勿传入。 |
_now
|
|
Callable[[], str]
|
uuid 生成函数,仅供测试注入,生产调用请勿传入。 |
_new_uuid
|
返回:
| 类型 | 描述 |
|---|---|
str
|
创建出的卡片实体 |
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/streaming/cardkit.py
| Python | |
|---|---|
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | |