feat(question_gen): QuestionGenerator Protocol + 模块公开 API
app/ports.py 追加 QuestionGenerator Protocol(预留 LLM 出题接口)。 app/question_gen/__init__.py re-export load_benchmark 和 stratified_sample。 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,9 @@ from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
||||
if TYPE_CHECKING:
|
||||
import numpy as np
|
||||
|
||||
from app.tree.index import TreeIndex
|
||||
from core.types import GeneratedQuestion
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class EmbeddingProvider(Protocol):
|
||||
@@ -29,3 +32,27 @@ class EmbeddingProvider(Protocol):
|
||||
[N, D] ndarray,每行 L2 范数为 1.0。
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class QuestionGenerator(Protocol):
|
||||
"""LLM 驱动的题目生成端口(预留接口)。
|
||||
|
||||
参数:
|
||||
video_id: 视频标识。
|
||||
task_type: 题型。
|
||||
tree: 视频树索引,提供锚节点上下文。
|
||||
exemplars: 风格示例题目列表。
|
||||
|
||||
返回:
|
||||
生成的单条题目。
|
||||
"""
|
||||
|
||||
async def generate(
|
||||
self,
|
||||
video_id: str,
|
||||
task_type: str,
|
||||
tree: TreeIndex,
|
||||
*,
|
||||
exemplars: list[GeneratedQuestion],
|
||||
) -> GeneratedQuestion: ...
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
"""出题模块 — benchmark 加载与分层采样。"""
|
||||
|
||||
from app.question_gen.loader import load_benchmark, stratified_sample
|
||||
|
||||
__all__ = ["load_benchmark", "stratified_sample"]
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
"""app/ports.py QuestionGenerator Protocol 与 app/question_gen 公开 API 测试。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
|
||||
from app.ports import QuestionGenerator
|
||||
|
||||
|
||||
class TestQuestionGeneratorProtocol:
|
||||
def test_importable(self) -> None:
|
||||
"""QuestionGenerator 可从 app.ports 导入。"""
|
||||
assert QuestionGenerator is not None
|
||||
|
||||
def test_is_runtime_checkable(self) -> None:
|
||||
"""QuestionGenerator 是 runtime_checkable Protocol。"""
|
||||
assert hasattr(QuestionGenerator, "__protocol_attrs__") or hasattr(
|
||||
QuestionGenerator, "__abstractmethods__"
|
||||
)
|
||||
|
||||
def test_generate_method_exists(self) -> None:
|
||||
"""Protocol 定义了 generate 方法。"""
|
||||
assert hasattr(QuestionGenerator, "generate")
|
||||
|
||||
|
||||
class TestQuestionGenPublicAPI:
|
||||
def test_load_benchmark_importable_from_package(self) -> None:
|
||||
"""load_benchmark 可从 app.question_gen 直接导入。"""
|
||||
mod = importlib.import_module("app.question_gen")
|
||||
assert hasattr(mod, "load_benchmark")
|
||||
|
||||
def test_stratified_sample_importable_from_package(self) -> None:
|
||||
"""stratified_sample 可从 app.question_gen 直接导入。"""
|
||||
mod = importlib.import_module("app.question_gen")
|
||||
assert hasattr(mod, "stratified_sample")
|
||||
|
||||
def test_all_exports(self) -> None:
|
||||
"""__all__ 包含预期的公开 API。"""
|
||||
mod = importlib.import_module("app.question_gen")
|
||||
assert set(mod.__all__) == {"load_benchmark", "stratified_sample"}
|
||||
Reference in New Issue
Block a user