Skip to content

fix(agent): 让 BaseAgent 的构图契约在实例化期生效 - #1141

Merged
xerrors merged 1 commit into
xerrors:mainfrom
Ashitaka-Laputa-IV:fix/agent-base-abc-contract
Nov 3, 2026
Merged

xerrors merged 1 commit into
xerrors:mainfrom
Ashitaka-Laputa-IV:fix/agent-base-abc-contract

Conversation

@Ashitaka-Laputa-IV

@Ashitaka-Laputa-IV Ashitaka-Laputa-IV commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

变更说明

  • 任务类型:bug-fix
  • 目标:BaseAgent 上的 @abstractmethod get_graph 在实例化期真正生效,漏实现的后端类无法被创建。
  • 非目标:不改变 get_graph 的返回值契约,不改变 AGENT_BACKENDS 的注册方式,不把构图错误转换成领域错误。
  • substantial / trivial 判断:substantial。本变更改变负向案例与实际 gate,并接受“实例化期 TypeError 提前暴露”的取舍,按 implemented 决策记录直接落地,不需要 proposal 阶段。

工程主张与 Owner

  • 受影响主张:
    1. 漏实现 get_graph 的 BaseAgent 子类无法实例化;错误出现在 get_agent_backend / list_agent_backend_info 的创建点(TypeError),而不是构图后访问 None.astream_events。
    2. 已实现 get_graph 的后端(当前只有 ChatbotAgent)与全部测试后端行为不变。
  • Owner / commit point / 观察边界:契约由 backend/yuxi/modules/agents/runtime/base.py 拥有,检查由 ABCMeta 在实例化时触发。本变更不写持久状态,没有 commit point。
  • 决策记录:2026-11-03-base-agent-abstract-contract.md(本 PR 新增;合入后即 docs/develop-guides/decisions/implemented/2026-11-03-base-agent-abstract-contract.md)

验证情况

漏实现 get_graph 的子类无法实例化

  • 失败面:BaseAgent 仍是普通类时装饰器不生效,子类可以实例化,错误推迟到构图
  • 语义 Owner:backend/yuxi/modules/agents/runtime/base.py
  • 直接证据 / 命令:pytest test/unit/agents/test_base_agent_contract.py -q → 1 passed
  • 负向案例:把 class BaseAgent(ABC) 还原为 class BaseAgent: 后,同一测试以 DID NOT RAISE 失败(Reviewer 用真实源码在容器内复现)
  • 结果:Passed

已有后端与测试后端不受影响

  • 失败面:继承 ABC 后误伤合法子类
  • 语义 Owner:backend/yuxi/modules/agents/runtime/agent_backends/__init__.py
  • 直接证据 / 命令:容器内 pytest test/unit -m "not slow" -q → 3530 passed, 126 skipped, 0 failed
  • 负向案例:若 ChatbotAgent 无法实例化,test_builtin_discovery.py、test_base_agent_langfuse_config.py 会失败
  • 结果:Passed

仓库其它抽象基类没有同类遗漏

  • 失败面:别处仍存在不生效的 @abstractmethod
  • 语义 Owner:各基类所在模块
  • 直接证据 / 命令:全仓符号搜索 @abstractmethod,其余 5 处均继承 ABC
  • 负向案例:不适用
  • 结果:Inspected

工程契约与格式检查:

python3 scripts/ci/verify_engineering_contracts.py
  → 工程信任检查通过:344 decisions / 10 workflows / 4 agents files / 509 docs
python3 -m unittest scripts.ci.test_verify_engineering_contracts
  → Ran 56 tests, OK
ruff check / ruff format --check / ruff check --select I → 通过

简化 / 删除验收

不涉及。

独立语义 Review

由不继承实现上下文的全新 Reviewer 覆盖需求、完整 diff、base.py 的全部子类与 consumer、负向测试变异路径、文档与测试证据。结论为 Approve with changes:阻塞项是缺少 decision record(已补),非阻塞建议是收紧测试断言(已改为 match=r"abstract method 'get_graph'")。无未解决项。

未验证范围与风险

  • 本机 Windows 无法运行测试(测试链路依赖 os.O_DIRECTORY、fcntl 等 POSIX 接口),后端测试全部在 Linux 容器 ghcr.io/astral-sh/uv:python3.13-bookworm 中执行,未在 docker compose 的 api 镜像内重跑。
  • 未运行 integration 与 E2E:本变更只影响 Python 类实例化契约,不改变 HTTP、PostgreSQL、worker、SSE、沙盒或浏览器行为。
  • 风险:仓库外或自定义后端若漏实现 get_graph,升级后会在实例化或后端信息查询阶段提前抛出 TypeError;该错误不会映射为 AgentBackendNotFoundError。
  • 边界:ABC 只保证 get_graph 存在,不保证返回已编译的图;返回 None 的子类仍会在构图调用处失败。
  • 文档构建:容器内 pnpm run build 通过(vitepress 1.6.4,build complete in 27.20s)。

事故反馈

不涉及。该缺陷未造成高影响逃逸,未达到 postmortem 门槛。

界面变更

不涉及。

关联事项

无。

补充说明

BaseAgent 自身不再可实例化,这是有意的契约表达。

BaseAgent 未继承 ABC,@AbstractMethod 只写入 __isabstractmethod__,
没有 ABCMeta 在实例化时检查;漏实现 get_graph 的子类仍能创建,
失败被推迟到构图后访问 None.astream_events。

改为继承 ABC,与模型、知识库、解析器等基类保持一致;新增负向测试
断言不完整子类在实例化时抛出 TypeError,并记录对应决策。
@xerrors
xerrors merged commit c7c902c into xerrors:main Nov 3, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants