Skip to content
CrewAI 文档版本 跟随上游 源快照 0f9ebdf2 更新于 2026-10-18

步骤钩子

在 CrewAI 中使用 PRE_STEP 和 POST_STEP 钩子拦截任务与流程方法步骤

步骤钩子会拦截一次执行中的每个工作单元:每个团队任务以及每个流程方法。你可以用它们检查或改写进入某个步骤的内容、转换输出的内容,或逐步追踪进度——而无需触及单个 LLM 或工具调用的层面。

概述

两个拦截点覆盖各个步骤:

拦截点时机ctx.payload
PRE_STEP任务或流程方法运行之前步骤输入(见下文)
POST_STEP任务或流程方法运行之后步骤输出(见下文)

payload 中存放什么取决于 ctx.kind:

ctx.kindPRE_STEP payloadPOST_STEP payload
"task"传给智能体的上下文字符串TaskOutput 对象
"flow_method"方法参数组成的 dict方法的返回值

对于流程方法,位置参数会以 _0、_1……为键出现在参数字典中,关键字参数则以各自的名称作为键;对它们的修改和替换会被映射回实际的调用。

钩子签名

python
from crewai.hooks import on, HookAborted, InterceptionPoint

@on(InterceptionPoint.PRE_STEP)
def step_hook(ctx) -> Any | None:
    # Mutate ctx.payload in place, or
    # return a non-None value to replace it, or
    # raise HookAborted(reason, source) to stop the step
    return None

上下文 Schema

两个拦截点都会收到一个 StepContext:

python
class StepContext(InterceptionContext):
    payload: Any            # Step input (pre) or step output (post)
    kind: str | None        # "task" or "flow_method"
    step_name: str | None   # Task name/description, or flow method name
    output: Any             # POST_STEP only: same object as payload
    agent: Any              # Task steps: the executing agent (else None)
    agent_role: str | None  # Task steps: the agent's role (else None)
    task: Any               # Task steps: the Task instance (else None)
    crew: Any               # None for step points
    flow: Any               # Flow-method steps: the Flow instance (else None)

对于任务步骤,step_name 是任务的 name(若没有则回退到其描述)。对于流程方法步骤,它是方法名。

常见用例

步骤追踪

python
@on(InterceptionPoint.POST_STEP)
def trace_steps(ctx):
    print(f"{ctx.kind} '{ctx.step_name}' finished")

改写任务上下文

python
@on(InterceptionPoint.PRE_STEP)
def inject_disclaimer(ctx):
    if ctx.kind != "task":
        return None
    return f"{ctx.payload}\n\nNote: treat all figures as estimates."

转换任务输出

python
@on(InterceptionPoint.POST_STEP)
def normalize_output(ctx):
    if ctx.kind != "task":
        return None
    ctx.payload.raw = ctx.payload.raw.strip()

NOTE

POST_STEP 在任务输出被存储之前运行,因此改写会传播到使用该输出的所有地方:下游任务上下文、回调、最终的团队输出,以及磁盘上的任务 output_file。

守护流程方法

python
@on(InterceptionPoint.PRE_STEP)
def guard_publish(ctx):
    if ctx.kind == "flow_method" and ctx.step_name == "publish":
        if not ctx.flow.state.get("reviewed"):
            raise HookAborted(reason="publish requires review", source="review-gate")

按智能体过滤

步骤钩子支持与其他拦截点相同的 agents= 过滤器(任务步骤中按执行智能体的角色进行匹配):

python
@on(InterceptionPoint.POST_STEP, agents=["Researcher"])
def log_research_steps(ctx):
    print(f"research step done: {ctx.step_name}")

中止步骤

在 PRE_STEP 中抛出 HookAborted 会在任何智能体或方法工作发生之前中止该步骤,并且中止会带着其原因传播到执行之外——不会被吞掉。步骤钩子抛出的任何其他异常都会被吞掉(fail-open),与其他拦截点相同。

在测试中管理钩子

python
from crewai.hooks import clear_all_hooks

clear_all_hooks()  # Clears every point, including steps

相关文档

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。