🔍 一、LlamaIndex 内部是如何触发事件的?
我们直接来看一段源码片段(已精简注释,来自 LlamaIndex Retriever
):
from llama_index.core.callbacks import CallbackManager
from llama_index.core.callbacks.schema import CBEventType
def retrieve(self, query: str) -> List[NodeWithScore]:
# 🔔 触发事件:开始检索
with self.callback_manager.event(
CBEventType.RETRIEVE, payload={"query_str": query}
) as event:
# 👇 真实的检索逻辑
nodes = self._retrieve(query)
# 🔚 触发事件:结束检索(自动由上下文管理器完成)
event.on_end(payload={"nodes": nodes})
return nodes
这段逻辑中最关键的两行是:
with self.callback_manager.event(CBEventType.RETRIEVE, payload=...) as event:
和
event.on_end(payload={"nodes": nodes})
这就是 LlamaIndex 的内部:在关键操作前后自动调用事件回调。
🧠 解释成通俗语言:
这就像机器人(LlamaIndex)有个内置习惯:每当它要做一件重要的事,比如“检索”,就会:
- 先在对讲机喊一声:“📣 我要开始检索啦!”
- 然后执行任务(比如从知识库找文档)
- 最后再喊一声:“📣 我检索结束啦,我找到了 3 篇文档!”
这两个喊话,其实就是 on_event_start
和 on_event_end
的调用。
你只要监听这个“对讲机”,就能实时知道它的每一个操作进度。
🧪 二、我们来模拟一个完整调用流程!
假设现在这样使用 LlamaIndex 的聊天引擎:
response = chat_engine.chat("鲁迅的真实姓名是谁?")
LlamaIndex 内部执行流程大致如下:
步骤 | 内部触发 | 事件类型 |
---|---|---|
1. 接收到用户问题 | → 准备检索 | retrieve |
2. 执行检索逻辑 | → 搜索知识库 | / |
3. 检索结束 | → 报告找到的文档数 | retrieve |
4. 构建提示词模板 | → 进入模板阶段 | templating |
5. 调用大模型生成回答 | → 发出 LLM 请求 | llm |
6. 回答完成 | → 结束 LLM 阶段 | llm |
7. 输出最终回答 | → 任务完成 | / |
🧰 三、可以在哪里“插耳朵监听”?
只要在代码中像下面这样注册一个回调,就能监听所有喊话:
event_handler = EventCallbackHandler()
chat_engine.callback_manager.handlers.append(event_handler)
你写的这个 EventCallbackHandler
,只要实现了:
on_event_start(event_type, payload)
on_event_end(event_type, payload)
你就能像监听广播一样,实时看到 LlamaIndex 的操作。
📦 四、如果想监听更多事件,在哪里能看到完整列表?
可以去看 CBEventType
的定义,路径在:
llama_index/core/callbacks/schema.py
或者在代码里直接打印:
from llama_index.core.callbacks.schema import CBEventType
print(list(CBEventType))
你会看到:
[
'retrieve',
'function_call',
'agent_step',
'chunking',
'node_parsing',
'embedding',
'llm',
'templating',
'query',
...
]
✅ 总结一下
问题 | 答案 |
---|---|
LlamaIndex 是怎么知道事件类型的? | 它自己在源码中写明了:CBEventType.RETRIEVE 等 |
是谁调用的? | LlamaIndex 框架的内部逻辑自动调用 |
开发者可以监听这些事件吗? | 可以,通过注册自定义的回调处理器(如 EventCallbackHandler ) |
能看到过程细节吗? | 能,在回调的 payload 中可以看到 query、检索结果、生成内容等 |