故障排查#
先看异常和你收到的最后一个事件。工具错误可能是可恢复的,而模型提供商或生命周期错误会终止请求。失败边界参见集成到应用,想在没有真实模型的情况下复现行为请参见测试你的智能体。绝不要在公开的错误报告里写入凭据或完整的私有提示词。
装饰后的工具在导入时报错#
A tool needs at least one non-empty guideline 表示函数有描述,但缺少使用指引。请添加@tool(guidelines="When to use it."),或者补上一个非空的 Guidelines:文档字符串小节。每个参数还需要类型注解。Args条目必须与真实参数名一致;未知条目和未命名的可变参数都会被拒绝。参见定义并注册工具。
端点会拒绝推理或工具搜索#
模型适配器不会协商模型能力。请确认这个端点支持你选择的协议和推理级别。在 Responses 上,当前适配器会把最高几级映射为 high;在 Chat Completions 上,不受支持的具名级别可能会被拒绝。OFF 可能只是省略该设置,而不是关闭模型提供商默认的推理。
ToolSearchExtension需要兼容的 Responses 工具搜索端点,而不只是普通的工具调用。请使用 response=True和支持该协议的模型,或者省略工具搜索、按常规方式暴露工具。技能加载不要求 Responses。参见连接模型提供商和按需加载工具和技能。
第二个轮次不记得第一个轮次#
历史记录来自扩展。传入 extensions=[...] 会替换默认值,因此请加入InMemoryMessageAccumulator或某个持久化扩展,并一直使用同一个 session_id。两个客户端即使 ID 相同,只要累加器实例不同,就不会共享记忆。
模型看不到你添加的消息#
请在生命周期钩子里添加上下文,不要通过修改共享状态来做:
on_state— 恢复历史记录,并注入系统指令。on_message— 在待发送的用户输入发出去之前改写它。before_model— 在每次模型步骤之前调整上下文。
请使用传给钩子的 context。各个钩子确切在何时运行,参见请求生命周期。
你的自定义事件到不了 UI#
内部通知和 UI 事件是两条不同的通道。context.publish把ExtensionEvent投递给其他扩展;await context.emit(AgentEvent(...))则为 Agent.stream排队。凡是用户应该看到的内容,都用第二种方式。参见发出事件并接收用户输入。
审批一直处于待处理状态#
响应必须与请求的会话 ID、外部事件名称和负载结构匹配。如果没有已注册的扩展接受它,请求就会一直等待。不要用input()阻塞循环——终端输入请改用异步 UI 或 asyncio.to_thread。请求被取消后,它待处理的路由会失效,因此迟到的回复会被忽略。
缺少推理或缓存数据#
推理文本只在模型返回它时才出现;推理级别是请求偏好,而不是承诺。用量会在 MODEL_COMPLETED上报告,而不是在每个文本片段上报告。cache_hit_rate为 None有两种情况:模型提供商什么也没报告,或者输入 token 数为零;ModelUsage.cache_reported可以区分这两者。转发协议的网关经常会丢掉缓存明细,所以在意缓存可见性时请优先使用 Responses 适配器。
请求一直卡住#
没有任何显示,也没有任何失败。提供方,或它前面的网关,收下了请求然后沉默了。现在每个适配器都会放弃并抛出 ProviderTimeoutError;它的 phase 说明是哪一段耗尽了:connect(没有人在监听)、first_byte(响应头一直没来,过载的网关就是这个样子)或 idle(已经开始的响应停了)。请直接用 curl 测试该端点;如果它在那里也卡住,问题就在提供方一侧,这里的任何设置都帮不上忙。参见 默认值以及如何修改。
请求失败或被中止了,我想接着做#
对话已经保存到它停下的位置。请调用 agent.resume(),或者先调用 agent.resume_point(),看看有没有可以恢复的内容、恢复时会做什么。不要发一条“继续”消息:它会增加一条模型没有预期的用户消息,也不会告诉模型有工具被中断了。参见 恢复被中断的会话。
错误里提到了网页或 HTTP 状态码#
answered HTTP 502 with a web page 表示回应的是 API 前面的东西,而不是 API 本身:可能是代理或网关的错误、防火墙,或者登录页。请检查 base_url 以及通往它的网络路径。returned HTTP 400: ... 带有提供方自己的解释,例如未知的模型名;模型 ID 可能区分大小写,网关也可能有自己的命名。answered HTTP 200 with application/json instead of an event stream 通常意味着该端点不支持流式,或者基础 URL 指向了错误的路由。
重试导致文本重复#
内置重试在第一个流式事件之后就会停止,因此重试绝不应该重放已经可见的输出。请检查应用层的重试,并确认你没有把最终消息文本和每一个 TEXT_DELTA片段都追加到同一个缓冲区。
项目指令或技能没有出现#
AgentsMdExtension加载的是你选定的目录及其各级祖先目录,而不是工作区里所有嵌套的文件。请检查 sources()和 instructions(),并确认这个扩展在你的显式列表中。空文件或无法读取的文件会被跳过。directory不会改变工具的路径。参见加载项目指令。
技能方面请检查 extension.skills。发现过程发生在构造时;新增文件或目录元数据需要新建一个扩展。已有技能正文是按需读取的,但编辑文件不会替换已经进入历史记录的指令。请显式传入项目根目录,不要假定默认值包含工作目录。参见按需加载工具和技能。
MCP 服务器没有工具,或在生成之前就失败#
请检查 extension.servers和 extension.config_path。缺少配置文件时不会加载任何服务器,而配置有误则会抛出异常。每次请求都会连接并做发现;连不上的服务器会让初始化失败,而不是悄无声息地消失。默认情况下,catalog上的远程 search工具名为 catalog__search。传输方式和命名空间参见连接 MCP 工具。
运行时拒绝第二个请求#
同一个会话的两个请求不能重叠。请把它们排队,或者结束、关闭第一个流,包括其中的清理工作。从一个裸异步迭代器里直接跳出而不使用 aclosing,可能留下未完成的工作。不同的会话 ID 可以并发运行,但不同的运行时和 worker 不共享准入锁。参见集成到应用。
压缩没有执行#
它需要同时越过大小阈值,并且有一个更早的已完成轮次可供替换。当前轮次会完整保留,所以单个过大的轮次会被放过。如果生成的摘要并不比它替换的消息更小,COMPACTION_COMPLETED会报告 applied=False。可复现的测试见压缩而不丢失历史记录。