agent
feishu.agent
¶
LlmBackend
¶
Bases: Protocol
大模型后端协议,是自定义模型后端的扩展契约。
实现该协议即可接入 feishu.agent.loop.Agent;内置实现见 feishu.agent.adapters.anthropic.AnthropicBackend
与 feishu.agent.adapters.openai.OpenAIBackend。stream 须返回逐个产出 [feishu.agent.llm.StreamChunk][]
的异步迭代器。该协议标注了 runtime_checkable,可用 isinstance 校验实现是否符合契约。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
stream
¶
stream(*, messages: Sequence[Message], tools: Sequence[ToolSpec] = (), system: str | None = None, **kwargs: Any) -> AsyncIterator[StreamChunk]
以流式方式生成一轮模型响应。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
Sequence[Message]
|
截至当前轮次的对话历史。 |
必需 |
|
Sequence[ToolSpec]
|
本轮可供模型调用的工具声明。 |
()
|
|
str | None
|
系统提示词。 |
None
|
|
Any
|
透传给底层大模型 API 的额外参数。 |
{}
|
返回:
| 类型 | 描述 |
|---|---|
AsyncIterator[StreamChunk]
|
逐个产出 [feishu.agent.llm.StreamChunk][] 的异步迭代器。 |
源代码位于: feishu/agent/llm.py
Message
dataclass
¶
一条对话消息,由角色与若干内容块组成。
role 取 user、assistant 或 tool 之一;content 是 [feishu.agent.llm.ContentPart][] 列表,
适配器会将其翻译为各家大模型 API 的消息格式。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
MessageStop
dataclass
¶
流式响应的终止信号,携带停止原因与可选的用量统计。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
StopReason
¶
归一化后的模型停止原因。
各适配器会将厂商返回的原始停止原因映射到这些枚举值。由于继承自 str,枚举成员可直接与对应的
字符串字面量比较,便于序列化与传输。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
TextDelta
dataclass
¶
TextPart
dataclass
¶
ToolCall
dataclass
¶
由流式片段归并而成的完整工具调用。
与 feishu.agent.llm.ToolUsePart 不同,此处的 arguments 为完整的 JSON 字符串,由
feishu.agent.loop.Agent 在分发前 json.loads() 解析。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
ToolCallDelta
dataclass
¶
流式响应中的一个工具调用增量片段。
同一次工具调用的多个片段共享相同的 index;id 与 name 通常仅在首个片段出现,而 arguments
会逐段累积成完整的参数 JSON 字符串。feishu.agent.loop.accumulate_stream 负责按 index 归并这些片段。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
ToolResultPart
dataclass
¶
工具执行结果,作为工具消息(role="tool")的内容块回传给模型。
tool_call_id 须与触发执行的 feishu.agent.llm.ToolUsePart 的 id 对应。当工具执行失败时,
将 is_error 置为 True,模型即可据此调整后续行为。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
ToolSpec
dataclass
¶
工具的与厂商无关的声明,供模型据此决定是否调用。
input_schema 为描述参数的 JSON Schema。适配器会将其翻译为各家大模型所需的工具格式
(Anthropic 的 input_schema、OpenAI 的 function.parameters)。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
ToolUsePart
dataclass
¶
模型发起的一次工具调用,作为助手消息的一个内容块。
arguments 为已解析的参数字典;与 feishu.agent.llm.ToolCall 不同,此处的参数已经是 dict,
而非待解析的 JSON 字符串。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/llm.py
Agent
¶
智能体主循环:驱动大模型与工具协作,自动回复飞书消息。
每收到一条消息,便载入会话历史、调用 feishu.agent.llm.LlmBackend 流式生成响应,并由
feishu.agent.loop.accumulate_stream 归并结果。若模型请求调用工具,则经
feishu.agent.tools.ToolRegistry 分发执行,并将结果回传后继续下一轮,直至产出最终文本或触及
max_iterations 上限。需要审批的工具会先发送审批卡片并挂起本轮,待用户在卡片上批准或拒绝后由
feishu.agent.loop.Agent.handle_card_action 恢复。
经 feishu.agent.dispatch.register_agent 注册到事件分发器后,即可自动处理消息与卡片回调事件。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
LlmBackend
|
大模型后端,须实现 feishu.agent.llm.LlmBackend。 |
必需 |
|
ToolRegistry
|
必需 | |
|
SessionStore | None
|
会话历史存储。默认使用 feishu.agent.session.InMemorySessionStore。 |
None
|
|
FeishuClient | None
|
飞书客户端,用于回复消息与发送卡片;为 |
None
|
|
PendingApprovalStore | None
|
挂起审批存储。默认使用 feishu.agent.session.InMemoryPendingApprovalStore。 |
None
|
|
int
|
单轮对话中模型与工具往返的最大次数。默认为 |
8
|
|
str | None
|
系统提示词。 |
None
|
|
bool
|
是否以流式卡片回复。为 |
False
|
|
Any
|
透传给 feishu.agent.llm.LlmBackend.stream 的额外参数。 |
{}
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
|
示例:
源代码位于: feishu/agent/loop.py
| Python | |
|---|---|
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 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | |
run
async
¶
处理一条飞书消息事件:载入历史、追加用户消息并驱动主循环。
通常无需直接调用,而是经 feishu.agent.dispatch.register_agent 注册为消息事件的处理函数。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
Event
|
飞书消息事件,须具备 |
必需 |
飞书文档
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/loop.py
handle_card_action
async
¶
处理审批卡片的回传交互,恢复或终止此前挂起的对话。
从卡片回传值中读取 __approval__ 与 decision。决策无效时不消费挂起审批,用户可重试;批准则执行
对应工具并恢复主循环,拒绝则向模型回传一条错误工具结果再恢复。无论恢复过程是否抛错,都会同步返回
包含 toast 与更新后 card 的飞书响应。
通常无需直接调用,而是经 feishu.agent.dispatch.register_agent 注册为卡片回调事件的处理函数。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
Event
|
飞书卡片回调事件,须具备 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
dict[str, Any]
|
供飞书更新卡片的同步响应字典,含 |
飞书文档
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/loop.py
StreamResult
dataclass
¶
一轮流式响应归并后的完整结果。
由 feishu.agent.loop.accumulate_stream 将逐个 [feishu.agent.llm.StreamChunk][] 归并而成:
text 为拼接后的全部文本,tool_calls 为重组完成的工具调用列表,stop_reason 为归一化的停止原因,
usage 为可选的用量统计。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/loop.py
InMemoryPendingApprovalStore
¶
基于内存的 feishu.agent.session.PendingApprovalStore 实现。
将挂起审批保存在进程内字典中,写操作以锁保护因而并发安全。每个审批仅可被取出一次,取出即移除,可天然 防止重复执行。仅适用于单进程场景;生产环境请自行实现 feishu.agent.session.PendingApprovalStore。
示例:
源代码位于: feishu/agent/session.py
put
async
¶
put(approval: PendingApproval) -> None
pop
async
¶
pop(approval_id: str) -> PendingApproval | None
按 approval_id 取出并移除一次挂起的审批。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
str
|
审批标识。 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
PendingApproval | None
|
对应的 feishu.agent.session.PendingApproval;不存在或已被取出时返回 |
源代码位于: feishu/agent/session.py
| Python | |
|---|---|
InMemorySessionStore
¶
基于内存的 feishu.agent.session.SessionStore 实现。
将各会话历史保存在进程内字典中,写操作以锁保护因而并发安全。仅适用于单进程、可接受重启即丢失历史的 场景;生产环境请自行实现 feishu.agent.session.SessionStore 接入持久化后端。
示例:
源代码位于: feishu/agent/session.py
get
async
¶
get(session_id: str) -> list[Message]
append
async
¶
append(session_id: str, *messages: Message) -> None
向指定会话追加一条或多条消息。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
str
|
会话标识。 |
必需 |
|
Message
|
待追加的消息。 |
()
|
源代码位于: feishu/agent/session.py
PendingApproval
dataclass
¶
一次挂起的工具审批,记录恢复对话所需的全部上下文。
当工具的 requires_approval 为 True 时,feishu.agent.loop.Agent 会创建该记录并发送审批卡片;
用户在卡片上批准或拒绝后,依据其中保存的会话与工具调用信息恢复本轮对话。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/session.py
PendingApprovalStore
¶
Bases: Protocol
挂起审批存储协议,是自定义审批持久化后端的扩展契约。
feishu.agent.loop.Agent 通过该协议保存与取回挂起的 feishu.agent.session.PendingApproval;
内置实现为 feishu.agent.session.InMemoryPendingApprovalStore。该协议标注了 runtime_checkable,
可用 isinstance 校验实现是否符合契约。
示例:
源代码位于: feishu/agent/session.py
put
async
¶
put(approval: PendingApproval) -> None
SessionStore
¶
Bases: Protocol
会话历史存储协议,是自定义持久化后端的扩展契约。
feishu.agent.loop.Agent 通过该协议读写各会话的对话历史;内置实现为
feishu.agent.session.InMemorySessionStore,可自行实现该协议接入数据库等持久化后端。该协议标注了
runtime_checkable,可用 isinstance 校验实现是否符合契约。
示例:
源代码位于: feishu/agent/session.py
Tool
dataclass
¶
一个已注册的工具:名称、描述、参数 Schema、处理函数及是否需要审批。
handler 既可为同步函数也可为协程函数;同步函数在分发时会被放到工作线程中执行,避免阻塞事件循环。
当 requires_approval 为 True 时,feishu.agent.loop.Agent 会先发送审批卡片并挂起本轮对话,
待用户批准后再执行。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/tools.py
ToolRegistry
¶
工具注册表,负责工具的注册、声明导出与分发执行。
既支持装饰器形式注册,也支持直接传入处理函数;通过 feishu.agent.tools.ToolRegistry.specs 将 已注册工具导出为 feishu.agent.llm.ToolSpec 列表交给模型,再由 feishu.agent.tools.ToolRegistry.dispatch 校验参数并执行对应处理函数。
示例:
源代码位于: feishu/agent/tools.py
| Python | |
|---|---|
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 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 | |
register
¶
register(name: str | None = None, handler: Callable[..., Any] | None = None, *, input_schema: dict[str, Any], description: str, requires_approval: bool = False) -> Callable[..., Any] | None
注册一个工具,支持装饰器与直接调用两种形式。
直接传入 handler 时立即注册并原样返回该处理函数;省略 handler 时返回一个装饰器,可直接装饰处理
函数。未显式指定 name 时取处理函数的 __name__ 作为工具名。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
str | None
|
工具名称。省略时取处理函数的 |
None
|
|
Callable[..., Any] | None
|
工具处理函数,可为同步函数或协程函数。省略时本方法返回装饰器。 |
None
|
|
dict[str, Any]
|
描述工具参数的 JSON Schema。 |
必需 |
|
str
|
工具描述,供模型理解其用途。 |
必需 |
|
bool
|
是否在执行前要求用户审批。默认为 |
False
|
返回:
| 类型 | 描述 |
|---|---|
Callable[..., Any] | None
|
直接调用形式下原样返回 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
既未提供 |
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/tools.py
specs
¶
将所有已注册工具导出为 feishu.agent.llm.ToolSpec 列表。
返回:
| 类型 | 描述 |
|---|---|
list[ToolSpec]
|
工具声明列表,可直接作为 |
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/tools.py
dispatch
async
¶
校验参数并执行指定工具,返回其结果。
先依据工具的 input_schema 校验 arguments,再调用对应处理函数。协程处理函数会被 await;
同步处理函数则放到工作线程中执行,避免阻塞事件循环。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
str
|
工具名称。 |
必需 |
|
dict[str, Any]
|
已解析为字典的工具参数。 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Any
|
工具处理函数的返回值。 |
引发:
| 类型 | 描述 |
|---|---|
KeyError
|
工具未注册时抛出。 |
ToolValidationError
|
参数未通过 |
示例:
源代码位于: feishu/agent/tools.py
ToolValidationError
¶
Bases: ValueError
工具参数校验失败时抛出。
当 feishu.agent.tools.ToolRegistry.dispatch 收到的参数不是对象、缺少必填字段,或在
additionalProperties 为 False 时出现多余字段,即抛出该异常。
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/tools.py
register_agent
¶
register_agent(dispatcher: EventDispatcher, agent: Agent, *, message_event: str = 'im.message.receive_v1', card_event: str = 'card.action.trigger') -> None
将智能体的消息处理与卡片回调挂载到事件分发器上。
把 feishu.agent.loop.Agent.run 注册为消息事件的处理函数,把
feishu.agent.loop.Agent.handle_card_action 注册为卡片回调事件的处理函数。dispatcher 须提供与
feishu.events.dispatcher.EventDispatcher 一致的 on(event_type) 装饰器接口。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
EventDispatcher
|
事件分发器,须提供 |
必需 |
|
Agent
|
已构造的 feishu.agent.loop.Agent。 |
必需 |
|
str
|
消息事件类型。默认为 |
'im.message.receive_v1'
|
|
str
|
卡片回调事件类型。默认为 |
'card.action.trigger'
|
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/dispatch.py
accumulate_stream
async
¶
accumulate_stream(chunks: AsyncIterator[StreamChunk]) -> StreamResult
将一轮流式响应的增量片段归并为一个 feishu.agent.loop.StreamResult。
文本片段按序拼接;工具调用片段按 index 归并,逐段累积出完整的参数 JSON 字符串,并产出有序的
feishu.agent.llm.ToolCall 列表;停止原因与用量统计取自 feishu.agent.llm.MessageStop。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
AsyncIterator[StreamChunk]
|
逐个产出 [feishu.agent.llm.StreamChunk][] 的异步迭代器,通常来自 feishu.agent.llm.LlmBackend.stream。 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
StreamResult
|
示例:
源代码位于: feishu/agent/loop.py
session_id_for
¶
从消息事件推导会话标识,用于隔离不同会话的对话历史。
优先使用 chat_id;当消息属于话题(thread)回复时,附加 root_id 以将同一话题归为独立会话;
若事件中没有 chat_id,则回退为 message_id。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
Event
|
飞书消息事件,须具备 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
str
|
会话标识字符串。 |
飞书文档
示例:
源代码位于: feishu/agent/loop.py
user_message_from_event
¶
将飞书消息事件转换为一条用户角色的 feishu.agent.llm.Message。
文本提取委托给 feishu.im.inbound.message_text,因此除纯文本外还支持富文本(post)消息,
并会依据消息的 mentions 数组将 @_user_N 提及占位符解析为 @<姓名>;未被解析的开头占位符
(例如事件未携带 mentions 时)会被去除。当无法解析出任何文本时(如图片等非文本消息),退回使用
原始 content 作为文本。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
Event
|
飞书消息事件,须具备 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
Message
|
角色为 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
事件体中不存在 |
飞书文档
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/agent/loop.py
stream_text
async
¶
stream_text(provider_stream: Any) -> AsyncIterator[str]
将任意 LLM 提供商的流式响应转换为纯文本增量的异步迭代器。
本函数是 feishu.client.FeishuClient.stream_card 的配套适配器:将大模型流式
响应(同步或异步)归一化为逐个字符串 token,可直接传入 stream_card 的
tokens 参数,从而把 LLM 输出实时推送至飞书消息卡片。
适配策略:
-
Anthropic 上下文管理器(
AsyncMessageStreamManager,带__aenter__但无__aiter__):进入上下文后迭代原始 SSE 事件,经 [feishu.agent.adapters.anthropic._translate_events][] 归一化。 -
OpenAI 异步流(
AsyncStream[ChatCompletionChunk]或 chunk 带choices属性):直接异步迭代,经 [feishu.agent.adapters.openai._translate_chunks][] 归一化。 -
OpenAI 同步流(
Stream[ChatCompletionChunk],同步可迭代,首个元素有choices属性):通过loop.run_in_executor包装后同上处理。 -
归一化 StreamChunk 序列(已经 feishu.agent.llm.LlmBackend 适配器处理 的异步迭代器,首个元素为 feishu.agent.llm.TextDelta):直接消费,仅产出
TextDelta.text,跳过工具调用增量与停止信号。 -
Anthropic 原始事件异步/同步流(默认 fallback):经 Anthropic 适配器归一化。
同步/异步均兼容。工具调用增量(feishu.agent.llm.ToolCallDelta)与停止信号 (feishu.agent.llm.MessageStop)均被静默跳过,只有文本内容被产出。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
Any
|
LLM 提供商返回的流式对象,支持以下类型:
|
必需 |
返回:
| 类型 | 描述 |
|---|---|
AsyncIterator[str]
|
逐个产出文本增量字符串( |
引发:
| 类型 | 描述 |
|---|---|
TypeError
|
当 |
飞书文档
示例:
源代码位于: feishu/agent/streaming.py
| Python | |
|---|---|
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |