📑 目录(点击展开)
|
|
| 依赖 | 版本 | 说明 |
|---|---|---|
| Python | 3.12+ | 运行环境 |
| PostgreSQL | 16+ | 需安装 pgvector 扩展 (或使用 DuckDB 作为备选) |
| Neo4j | 5+ | 图数据库 (或使用 LadybugDB 作为嵌入式备选) |
| Redis | 7+ | 缓存与队列 (或使用内置 Cashews 作为备选) |
# 克隆项目
git clone <repository-url>
cd weaver
# 安装依赖 (使用 uv)
uv sync
# 安装 spaCy 中文模型及依赖
# 注意:zh_core_web_lg 需要 spacy-pkuseg 分词器依赖
uv pip install "spacy-pkuseg>=0.0.27,<0.1.0"
uv run python -m spacy download zh_core_web_lg
# 可选:安装英文模型
uv run python -m spacy download en_core_web_lg
# 可选:安装更精确的 transformer 模型(需要额外依赖)
# uv pip install spacy-transformers
# uv run python -m spacy download zh_core_web_trf🔧 SpaCy 模型说明
| 模型 | 大小 | 依赖 | 说明 |
|---|---|---|---|
zh_core_web_lg |
~600MB | spacy-pkuseg | 推荐:标准版,精度更高 |
zh_core_web_sm |
~40MB | spacy-pkuseg | 轻量级,无需 GPU |
zh_core_web_trf |
~400MB | spacy-transformers + PyTorch | 精度最高,需要 GPU |
en_core_web_lg |
~560MB | - | 推荐:英文处理,精度更高 |
实体类型映射:
PERSON/PER→ 人物ORG→ 组织机构GPE/LOC→ 地点MONEY/CARDINAL/PERCENT→ 数据指标LAW→ 法规与政策
Weaver 使用分层配置策略,支持环境变量和 TOML 文件:
- 复制配置模板:
cp config/settings.example.toml config/settings.toml
cp config/llm.example.toml config/llm.toml
cp .env.example .env- 配置环境变量(
.env文件):
# PostgreSQL (使用双下划线分隔嵌套配置)
WEAVER_POSTGRES__PASSWORD=your_secure_postgres_password
# Neo4j
WEAVER_NEO4J__PASSWORD=your_secure_neo4j_password
WEAVER_NEO4J__ENABLED=true
# Redis (可选,留空表示无密码)
WEAVER_REDIS__PASSWORD=
# API 认证 (生产环境至少 32 字符)
WEAVER_API__API_KEY=your_secure_api_key_at_least_32_characters_long
# LLM API Keys (供 llm.toml 引用)
WEAVER_LLM__PROVIDERS__AIPING__API_KEY=your_aiping_api_key
WEAVER_LLM__PROVIDERS__DMX__API_KEY=your_dmx_api_key- 配置 LLM 提供商(
config/llm.toml):
[global]
circuit_breaker_threshold = 5
circuit_breaker_timeout = 60.0
default_timeout = 120.0
[providers.openai]
type = "openai"
base_url = "https://api.openai.com/v1"
api_key = "${OPENAI_API_KEY}"
rpm_limit = 500
concurrency = 10
timeout = 120.0
priority = 100
weight = 100
[providers.openai.models.chat]
model_id = "gpt-4o"
temperature = 0.0
max_tokens = 4096
capabilities = ["chat", "vision"]
[providers.openai.models.embedding]
model_id = "text-embedding-3-large"
capabilities = ["embedding"]
# 调用点路由配置
[call-points.classifier]
primary = "chat.openai.gpt-4o"
fallbacks = ["chat.anthropic.claude-sonnet-4-20250514"]
[call-points.entity_extractor]
primary = "chat.openai.gpt-4o"
fallbacks = ["chat.anthropic.claude-sonnet-4-20250514"]
[call-points.embedding]
primary = "embedding.openai.text-embedding-3-large"
fallbacks = ["embedding.ollama.nomic-embed-text"]🔧 完整配置选项
| 配置项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| PostgreSQL | |||
host |
string | localhost |
数据库主机 |
port |
int | 5432 |
数据库端口 |
database |
string | weaver |
数据库名称 |
user |
string | postgres |
用户名 |
WEAVER_POSTGRES__PASSWORD |
string | - | 密码(环境变量,必须设置) |
pool_size |
int | 20 |
连接池大小 |
| Neo4j | |||
uri |
string | bolt://localhost:7687 |
连接地址 |
user |
string | neo4j |
用户名 |
WEAVER_NEO4J__PASSWORD |
string | - | 密码(环境变量,必须设置) |
enabled |
bool | true |
是否启用 |
| Redis | |||
host |
string | localhost |
Redis 主机 |
port |
int | 6379 |
Redis 端口 |
db |
int | 0 |
数据库编号 |
| API | |||
WEAVER_API__API_KEY |
string | - | API 认证密钥(至少32字符) |
| Fetcher | |||
crawl4ai_headless |
bool | true |
Crawl4AI 无头模式 |
crawl4ai_stealth_enabled |
bool | true |
Crawl4AI 隐身模式 |
crawl4ai_timeout |
float | 30.0 |
Crawl4AI 超时时间(秒) |
default_per_host_concurrency |
int | 2 | 每主机默认并发数 |
global_max_concurrency |
int | 32 | 全局最大并发数 |
httpx_timeout |
float | 15.0 | HTTPX 超时时间(秒) |
| Scheduler | |||
pipeline_retry_interval_minutes |
int | 15 | Pipeline 重试间隔(分钟) |
pipeline_retry_batch_size |
int | 20 | Pipeline 重试批次大小 |
| URL Security | |||
WEAVER_URL_SECURITY__ENABLED |
bool | true |
启用 URL 安全检查 |
WEAVER_URL_SECURITY__URLHAUS_API_KEY |
string | "" |
URLhaus API 密钥 |
WEAVER_URL_SECURITY__CACHE_SAFE_TTL |
int | 21600 |
安全缓存 TTL(秒) |
WEAVER_URL_SECURITY__CACHE_MALICIOUS_TTL |
int | 900 |
恶意缓存 TTL(秒) |
Pipeline 处理失败后支持智能重试机制:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
pipeline_retry_interval_minutes |
int | 15 | 重试检查间隔(分钟),控制失败任务的重试频率 |
pipeline_retry_batch_size |
int | 20 | 每次重试处理的任务数量 |
pipeline_retry_dynamic_batch |
bool | false | 是否根据成功率动态调整批次大小 |
pipeline_retry_success_rate_threshold |
float | 0.8 | 动态调整的触发阈值(0.0-1.0),成功率低于此值时减少批次大小 |
动态批次逻辑:
- 启用后,系统监控上批次处理成功率
- 成功率 ≥ 阈值:批次大小不变或增加
- 成功率 < 阈值:批次大小减半,避免大量任务连续失败
控制实体提取阶段的行为:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
disable_data_metrics_nodes |
bool | false | 是否禁用"数据指标"类型实体的提取和存储 |
配置方式:
# 环境变量
WEAVER_ENTITY__DISABLE_DATA_METRICS_NODES=true
# 或在 settings.toml 中
[entity]
disable_data_metrics_nodes = true影响范围:
- spaCy 阶段:跳过
CARDINAL、PERCENT、MONEY标签的实体识别 - LLM 阶段:过滤 LLM 返回的"数据指标"类型实体
- Resolver 阶段:阻止"数据指标"实体的创建和合并
多层 URL 安全检查,保护爬虫免受恶意 URL 攻击:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled |
bool | true |
是否启用 URL 安全检查 |
urlhaus_api_key |
string | "" |
URLhaus API 密钥(为空则跳过 API 检查) |
urlhaus_api_timeout |
float | 5.0 |
URLhaus API 超时(秒) |
phishtank_enabled |
bool | true |
启用 PhishTank 钓鱼数据库检查 |
phishtank_sync_interval_hours |
int | 6 |
PhishTank 数据同步间隔(小时) |
heuristic_enabled |
bool | true |
启用启发式 URL 分析 |
ssl_verify_enabled |
bool | true |
启用 SSL 证书验证 |
cache_safe_ttl_seconds |
int | 21600 |
安全结果缓存 TTL(6 小时) |
cache_malicious_ttl_seconds |
int | 900 |
恶意结果缓存 TTL(15 分钟) |
安全检查层级:
- SSRF 防护:拦截内网 IP、云元数据地址、危险协议
- URLhaus API:实时查询恶意 URL 数据库
- PhishTank:离线钓鱼 URL 黑名单匹配
- 启发式分析:编码混淆检测、可疑关键词、域名异常
- SSL 验证:证书有效性、信任链、EV 证书检测
配置方式:
# 环境变量
WEAVER_URL_SECURITY__ENABLED=true
WEAVER_URL_SECURITY__URLHAUS_API_KEY=your-api-key
# 或在 settings.toml 中
[url_security]
enabled = true
urlhaus_api_key = "your-api-key"
cache_safe_ttl_seconds = 21600# 运行迁移
uv run alembic upgrade head# 开发模式
uv run uvicorn src.main:app --reload --host 0.0.0.0 --port 8000
# 生产模式
uv run python -m src.maingraph TB
subgraph Sources ["📥 数据源"]
A[RSS/Atom Feeds]
B[Web Pages]
end
subgraph Collector ["🔄 采集层"]
C[SourceScheduler]
D[Deduplicator]
E[Interleaver]
F[SmartFetcher<br/>HTTPX / Crawl4AI]
end
subgraph Pipeline ["⚙️ 处理流水线"]
G[Phase 1: 单文章并发<br/>Classifier → Cleaner → Categorizer → Vectorize]
H[Phase 2: 批量合并<br/>BatchMerger]
I[Phase 3: 后处理<br/>ReVectorize → Analyze → Credibility → EntityExtractor]
end
subgraph Storage ["💾 存储层"]
J[(PostgreSQL<br/>+ pgvector)]
K[(Neo4j<br/>知识图谱)]
L[(Redis<br/>缓存/队列)]
end
subgraph API ["🌐 API 层"]
M[FastAPI<br/>REST Endpoints]
end
Sources --> Collector
Collector --> Pipeline
Pipeline --> Storage
Storage --> API
style Sources fill:#DBEAFE,stroke:#1E40AF
style Collector fill:#FEF3C7,stroke:#92400E
style Pipeline fill:#EDE9FE,stroke:#5B21B6
style Storage fill:#DCFCE7,stroke:#166534
style API fill:#FEE2E2,stroke:#991B1B
| 组件 | 描述 | 状态 |
|---|---|---|
| SmartFetcher | HTTPX/Crawl4AI 自动选择 | ✅ 稳定 |
| Deduplicator | 两级 URL 去重 | ✅ 稳定 |
| Pipeline | LangGraph 流水线编排 | ✅ 稳定 |
| LLM Client | 多 Provider 支持 + Fallback | ✅ 稳定 |
| Neo4j Writer | 实体关系写入 | ✅ 稳定 |
| Vector Repo | pgvector 向量存储 | ✅ 稳定 |
| Credibility Checker | 多信号可信度评估 | ✅ 稳定 |
| URL Security | 多层 URL 安全检查 | ✅ 稳定 |
| APScheduler | 定时任务调度 | ✅ 稳定 |
所有 API 请求需要在 Header 中携带 API Key:
X-API-Key: your-api-key
| 端点 | 方法 | 描述 |
|---|---|---|
/health |
GET | 健康检查(无需认证) |
/api/v1/status |
GET | 系统状态(需认证) |
/api/v1/config |
GET | 系统配置(需认证) |
/api/v1/sources |
GET | 获取源列表 |
/api/v1/sources/{source_id} |
GET | 获取指定源 |
/api/v1/sources |
POST | 添加新源 |
/api/v1/sources/{source_id} |
PUT | 更新源配置 |
/api/v1/sources/{source_id} |
DELETE | 删除源 |
/api/v1/pipeline/trigger |
POST | 触发 Pipeline 任务 |
/api/v1/pipeline/tasks/{task_id} |
GET | 获取任务状态 |
/api/v1/pipeline/queue/stats |
GET | 获取队列统计 |
/api/v1/pipeline/url |
POST | 处理单个 URL |
/api/v1/articles |
GET | 查询文章列表(支持分页、过滤、排序) |
/api/v1/articles/{id} |
GET | 获取文章详情 |
/api/v1/search |
GET | 统一搜索(mode 参数路由:local/global/articles) |
/api/v1/search/drift |
POST | DRIFT 迭代式探索搜索 |
/api/v1/search/causal |
POST | 因果关系搜索 |
/api/v1/search/temporal |
POST | 时间推理搜索 |
/api/v1/graph/entities/{name} |
GET | 查询实体及其关系 |
/api/v1/graph/articles/{id}/graph |
GET | 获取文章的知识图谱 |
/api/v1/graph/relations |
GET | 查询实体关系 |
/api/v1/graph/relations/search |
GET | 搜索实体关系 |
/api/v1/graph/metrics |
GET | 图谱指标(health/full/components/orphans/high-degree/modularity/distributions) |
/api/v1/graph/visualization |
GET | 获取图谱可视化数据 |
/api/v1/graph/visualization |
POST | 获取子图数据 |
/api/v1/admin/authorities |
GET | 获取源权威度列表 |
/api/v1/admin/authorities/{host} |
PATCH | 更新源权威度 |
/api/v1/admin/llm-failures |
GET | LLM 失败记录查询 |
/api/v1/admin/llm-failures/stats |
GET | LLM 失败统计 |
/api/v1/admin/llm-usage |
GET | LLM 使用统计(支持多维度分组查询) |
/api/v1/admin/articles/deduplicate |
POST | 文章去重 |
/api/v1/admin/communities |
GET | 社区列表查询 |
/api/v1/admin/communities/{id} |
GET | 社区详情 |
/api/v1/admin/communities/rebuild |
POST | 重建社区 |
/api/v1/admin/communities/health |
GET | 社区健康概览 |
/api/v1/admin/communities/health/diagnose |
POST | 社区健康诊断 |
/api/v1/admin/communities/health/repair |
POST | 社区健康修复 |
/api/v1/admin/communities/reports/generate |
POST | 生成社区报告 |
/api/v1/admin/communities/{id}/report/regenerate |
POST | 重新生成社区报告 |
/metrics |
GET | Prometheus 指标 |
📖 API 示例
curl -X GET "http://localhost:8000/api/v1/articles?page=1&page_size=20&category=politics&min_credibility=0.7&sort_by=publish_time&sort_order=desc" \
-H "X-API-Key: your-api-key"curl -X POST "http://localhost:8000/api/v1/sources" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"id": "xinhua-news",
"name": "新华社",
"url": "http://www.xinhuanet.com/politics/news_politics.xml",
"source_type": "rss",
"enabled": true,
"interval_minutes": 30,
"credibility": 0.98,
"tier": 1
}'新字段说明:
credibility: 预设可信度 (0.0-1.0),用于可信度评估的来源权威度信号tier: 来源层级 (1=权威, 2=可信, 3=普通)
curl -X GET "http://localhost:8000/api/v1/graph/entities/Apple%20Inc?limit=10" \
-H "X-API-Key: your-api-key"flowchart LR
A[Raw Article] --> B[Classifier]
B --> C[Cleaner]
C --> D[Categorizer]
D --> E[Vectorize]
B -->|非新闻| F[终止]
- Classifier: 判断是否为新闻,非新闻直接终止
- Cleaner: 清洗 HTML、提取正文
- Categorizer: 分类(政治/军事/经济/科技等)、语言、地区
- Vectorize: 生成内容向量 (1024维)
BatchMerger (Union-Find 相似度聚类)
- 相似度阈值: 0.80
- 合并相似文章,保留最完整版本
flowchart LR
A[Merged Article] --> B[ReVectorize]
B --> C[Analyze]
B --> D[QualityScorer]
C --> E[Credibility]
D --> E
E --> F[EntityExtractor]
F --> G[EntityResolver]
- ReVectorize: 合并后重新生成向量 (对 terminal 文章跳过)
- Analyze + QualityScorer: 并行执行 - 摘要/情感分析/关键数据提取 + 内容质量评分
- Credibility: 可信度评分 (依赖 Analyze 结果)
- EntityExtractor: spaCy + LLM 实体提取
- EntityResolver: 实体消歧和合并 (新增)
采用三信号类别自适应可信度评估算法:
| 信号 | 说明 |
|---|---|
| 来源权威性 | 三级优先级:预设值 > 历史自动计算 > 默认值 0.50 |
| 内容核查 | LLM 事实一致性检查 |
| 时效性 | 发布时间与事件时间差 |
权重根据文章类型动态调整:
| 类别 | 来源 | 内容 | 时效性 | 特点 |
|---|---|---|---|---|
| 政治/国际/军事 | 0.25 | 0.25 | 0.50 | 突发新闻时效优先 |
| 经济 | 0.45 | 0.35 | 0.20 | 来源权威优先 |
| 科技 | 0.30 | 0.50 | 0.20 | 内容质量优先 |
| 社会/文化/体育 | 0.40 | 0.40 | 0.20 | 均衡分布 |
| 时间差 | 评分 |
|---|---|
| ≤6小时 | 1.00 |
| ≤24小时 | 0.85 |
| ≤72小时 | 0.65 |
| ≤168小时 | 0.45 |
| >168小时 | 0.30 |
- 预设可信度:通过 API 为权威来源(央视、新华社等)预设可信度
- 历史自动计算:基于历史文章平均分自动计算
- 默认值:新来源默认 0.50
| 调用点 | 类型 | 说明 |
|---|---|---|
| classifier | CHAT | 新闻分类 |
| cleaner | CHAT | 内容清洗 |
| categorizer | CHAT | 分类识别 |
| merger | CHAT | 文章合并 |
| analyze | CHAT | 摘要分析 |
| credibility_checker | CHAT | 可信度检查 |
| quality_scorer | CHAT | 质量评分 |
| entity_extractor | CHAT | 实体提取 |
| entity_resolver | CHAT | 实体消歧 |
| search_local | CHAT | 本地搜索问答 |
| search_global | CHAT | 全局搜索问答 |
| causal_inference | CHAT | 因果推理 |
| community_report | CHAT | 社区报告生成 |
| community_title | CHAT | 社区标题生成 |
| entity_facts | CHAT | 事实验证 |
| narrative_synthesis | CHAT | 叙述合成 |
| evidence_sampling | CHAT | 证据采样 |
| roi_summary | CHAT | ROI 总结 |
| embedding | EMBEDDING | 向量生成 |
| rerank | RERANK | 重排序 |
| 任务 | 间隔 | 说明 |
|---|---|---|
| sync_pending_to_neo4j | 10分钟 | 同步待处理记录到 Neo4j |
| retry_neo4j_writes | 10分钟 | 重试失败的 Neo4j 写入 |
| sync_neo4j_with_postgres | 1小时 | 全量 Neo4j ↔ PostgreSQL 同步 |
| consistency_check | 每天 3:00 | 数据一致性检查 |
| cleanup_old_synced | 每天 3:30 | 清理旧同步记录 (保留 7 天) |
| llm_failure_cleanup | 24小时 | 清理 LLM 失败记录 (保留 3 天) |
| llm_usage_raw_cleanup | 6小时 | 清理 LLM 使用原始记录 (保留 2 天) |
| archive_old_neo4j_nodes | 每周六 2:00 | 归档旧 Neo4j 节点 (90 天) |
| cleanup_orphan_entity_vectors | 每周六 3:00 | 清理孤立实体向量 |
| retry_pipeline_processing | 15分钟 | 重试失败的 Pipeline 处理 |
| flush_retry_queue | 30秒 | 刷新爬虫重试队列 |
| llm_usage_aggregate | 5分钟 | LLM 使用量 Redis → PostgreSQL 聚合 |
| update_source_auto_scores | 每天 3:00 | 更新源权威度 |
| community_auto_check | 30分钟 | 社区检测自动检查(基于实体变化阈值触发重建) |
| community_health_check | 6小时 | 社区健康检查和自动修复 |
| update_persist_status_metrics | 5分钟 | 更新持久化状态 Prometheus 指标(支撑告警) |
| memory_consolidation | 30分钟 | Memory 慢路径整合 (条件性) |
| startup_sync_pending_to_neo4j | 启动时 | 启动时立即执行一次同步 |
Weaver 使用分层测试策略:
| 层级 | 位置 | 数量 | 特点 |
|---|---|---|---|
| 单元测试 | tests/unit/ |
~245 | Mock 外部依赖,快速执行 |
| 集成测试 | tests/integration/ |
~18 | 测试多组件交互 |
| E2E 测试 | tests/e2e/ |
~16 | 完整 API 流程,真实服务 |
| 性能测试 | tests/performance/ |
~8 | HNSW 向量索引性能基准 |
# 运行所有测试(不包括 E2E)
uv run pytest
# 运行单元测试
uv run pytest tests/unit/ -v
# 运行集成测试
uv run pytest tests/integration/ -v
# 运行带标记的测试
uv run pytest -m unit -v
uv run pytest -m integration -v
# 带覆盖率报告
uv run pytest --cov=src --cov-report=html
# 跳过慢速测试
uv run pytest -m "not slow"
# E2E 测试(需要 Docker)
cd tests/e2e
docker compose up -d
pytest tests/e2e/ -v
docker compose down项目要求 80% 覆盖率阈值。查看详细报告:
# HTML 覆盖率报告
uv run pytest --cov=src --cov-report=html
open htmlcov/index.html
# 覆盖率摘要
uv run pytest --cov=src --cov-report=term-missingtests/
├── unit/ # 单元测试
│ ├── test_analyze.py # Analyze 节点
│ ├── test_categorizer.py # Categorizer 节点
│ ├── test_classifier.py # Classifier 节点
│ ├── test_vectorize.py # Vectorize 节点
│ ├── test_global_search.py
│ ├── test_local_search.py
│ └── ...
├── integration/ # 集成测试
│ ├── test_pipeline_integration.py
│ ├── test_search_integration.py
│ └── test_source_integration.py
├── e2e/ # E2E 测试
│ ├── conftest.py # Docker fixtures
│ ├── base/client.py # API 客户端
│ ├── test_health.py
│ ├── test_sources.py
│ └── test_workflows.py
└── performance/ # 性能测试
└── test_hnsw_performance.py
E2E 测试使用隔离的 Docker 服务:
# 启动 E2E 测试服务
docker compose -f tests/e2e/docker-compose.yml up -d
# 等待服务就绪
docker compose -f tests/e2e/docker-compose.yml ps
# 运行 E2E 测试
uv run pytest tests/e2e/ -v
# 清理
docker compose -f tests/e2e/docker-compose.yml down -v常用测试 fixtures(定义在 tests/conftest.py):
| Fixture | 描述 |
|---|---|
mock_redis |
Redis mock |
mock_relational_pool |
关系型数据库 mock |
mock_graph_pool |
图数据库 mock |
mock_llm_client |
LLM 客户端 mock |
mock_settings |
配置对象 mock |
sample_article |
示例文章数据 |
使用 tests/factories.py 中的工厂类生成测试数据:
from tests.factories import ArticleRawFactory, SourceConfigFactory
# 创建单个对象
article = ArticleRawFactory.create()
# 批量创建
articles = ArticleRawFactory.create_batch(10)# 创建新迁移
uv run alembic revision --autogenerate -m "description"
# 应用迁移
uv run alembic upgrade head
# 回滚
uv run alembic downgrade -1- 使用
ruff进行代码格式化和 lint - 类型注解必须完整
- 文档字符串使用 Google 风格
|
发现问题? |
有好想法? |
想贡献代码? |
📝 贡献指南
- Fork 本仓库
- Clone 你的 fork:
git clone https://github.com/yourusername/weaver.git - 创建 分支:
git checkout -b feature/amazing-feature - 进行 修改
- 测试 修改:
uv run pytest tests/unit/ -v uv run pytest tests/integration/ -v
- 检查 覆盖率:
uv run pytest --cov=src --cov-report=term-missing
- 提交 修改:
git commit -m 'feat: 添加某功能' - 推送 到分支:
git push origin feature/amazing-feature - 创建 Pull Request
- ✅ 遵循 Python 标准编码规范 (PEP 8)
- ✅ 使用
ruff格式化代码:uv run ruff check --fix src/ - ✅ 编写全面的测试(新增功能必须有测试覆盖)
- ✅ 更新文档
- ✅ 类型注解完整
- 所有新功能必须包含单元测试
- 公共 API 必须包含集成测试
- 覆盖率阈值:80%
- 测试命名:
test_<模块>_<功能>.py - 使用 Mock 隔离外部依赖
- 新代码有测试覆盖
- 所有测试通过
- 覆盖率不低于阈值
- 无新增 linting 错误
- 类型注解完整
- 文档已更新
本项目采用 MIT 许可证:
© 2026 WEAVER. 保留所有权利。