TaskClassification

类 TaskClassification 在 skills/task_classifier.py: 任务分类结果 | 方法: __post_init__, to_dict

class TaskClassification:
    """任务分类结果"""
    category: TaskCategory = TaskCategory.UNKNOWN
    priority: TaskPriority = TaskPriority.MEDIUM
    confidence: float = 0.0
    sub_categories: List[str] = None
    reasoning: str = ""

    def __post_init__(self):
        if self.sub_categories is None:
            self.sub_categories = []

    def to_dict(self) -> Dict:
        return {
            "category": self.category.value,
            "priority": self.priority.value,
            "confidence": self.confidence,
            "sub_categories": self.sub_categories,
            "reasoning": self.reasoning,
        }


TaskClassifierSkill

任务分类技能
    基于关键词和模式匹配进行轻量级任务分类

类 TaskClassifierSkill 在 skills/task_classifier.py: 任务分类技能
    基于关键词和模式匹配进行轻量级任务分类 | 方法: __init__, process, _classify_category, _detect_sub_categories, _generate_reasoning

class TaskClassifierSkill:
    """
    任务分类技能
    基于关键词和模式匹配进行轻量级任务分类
    """

    # 类别关键词映射
    CATEGORY_KEYWORDS = {
        TaskCategory.CHAT: [
            "你好", "hello", "hi", "再见", "谢谢", "早上好", "晚上好",
            "聊天", "闲聊", "怎么样",
        ],
        TaskCategory.QUERY: [
            "什么", "如何", "为什么", "怎么", "哪", "介绍", "解释",
            "说明", "查询", "搜索", "了解", "是什么",
        ],
        TaskCategory.CODE: [
            "代码", "编程", "函数", "类", "方法", "bug", "调试",
            "python", "java", "javascript", "api", "git", "部署",
            "开发", "实现", "重构", "测试",
        ],
        TaskCategory.WRITE: [
            "写", "撰写", "创作", "文章", "报告", "邮件", "文案",
            "故事", "摘要", "翻译", "文档", "方案",
        ],
        TaskCategory.ANALYZE: [
            "分析", "评估", "比较", "研究", "调查", "统计",
            "深入", "详细", "全面", "优劣",
        ],
        TaskCategory.PLAN: [
            "规划", "计划", "设计", "方案", "架构", "路线",
            "策略", "目标", "步骤", "流程",
        ],
        TaskCategory.TRANSLATE: [
            "翻译", "translate", "中译英", "英译中", "转换为",
        ],
        TaskCategory.COMPUTE: [
            "计算", "算", "数学", "公式", "多少", "统计",
            "求值", "求解",
        ],
        TaskCategory.SAFETY: [
            "安全", "加密", "隐私", "防护", "漏洞", "攻击",
            "风险", "合规", "审计",
        ],
    }

    # 优先级规则
    PRIORITY_RULES = {
        TaskCategory.SAFETY: TaskPriority.CRITICAL,
        TaskCategory.CODE: TaskPriority.HIGH,
        TaskCategory.ANALYZE: TaskPriority.HIGH,
        TaskCategory.WRITE: TaskPriority.HIGH,
        TaskCategory.PLAN: TaskPriority.HIGH,
        TaskCategory.COMPUTE: TaskPriority.MEDIUM,
        TaskCategory.QUERY: TaskPriority.MEDIUM,
        TaskCategory.TRANSLATE: TaskPriority.MEDIUM,
        TaskCategory.CHAT: TaskPriority.LOW,
    }

    # 子类别检测模式
    SUB_CATEGORY_PATTERNS = {
        "frontend": [r"前端", r"html", r"css", r"react", r"vue"],
        "backend": [r"后端", r"服务器", r"数据库", r"api"],
        "ai_ml": [r"机器学习", r"深度学习", r"模型", r"训练", r"ai", r"神经网络"],
        "devo


文件 skills/dialogue_manager.py: 对话管理技能
管理对话上下文、多轮对话状态、话题跟踪 | 定义: class DialogueState, class TopicCategory, class
class, def __post_init__, class
class, def to_dict, class DialogueManagerSkill, def __init__, def process, def add_assistant_response

time uuid enum typing dataclasses skills.base_skill

#!/usr/bin/env python3
"""
对话管理技能
管理对话上下文、多轮对话状态、话题跟踪
"""

import time
import uuid
from enum import Enum
from typing import Dict, List, Optional
from dataclasses import dataclass, field

from skills.base_skill import BaseSkill, SkillType, SkillInput, SkillOutput

class DialogueState(Enum):
    """对话状态"""
    STARTED = "started"       # 刚开始
    ACTIVE = "active"         # 活跃对话中
    WAITING = "waiting"       # 等待用户输入
    ENDED = "ended"           # 已结束

class TopicCategory(Enum):
    """话题类别"""


DialogueState

类 DialogueState 在 skills/dialogue_manager.py: 对话状态 | 方法:

class DialogueState:
    """对话状态"""
    STARTED = "started"       # 刚开始
    ACTIVE = "active"         # 活跃对话中
    WAITING = "waiting"       # 等待用户输入
    ENDED = "ended"           # 已结束


TopicCategory

类 TopicCategory 在 skills/dialogue_manager.py: 话题类别 | 方法:

class TopicCategory:
    """话题类别"""
    GREETING = "greeting"
    QUESTION = "question"
    TASK = "task"
    FOLLOW_UP = "follow_up"    # 追问
    CLARIFICATION = "clarification"  # 澄清
    CLOSING = "closing"
    OTHER = "other"

@dataclass


DialogueTurn

类 DialogueTurn 在 skills/dialogue_manager.py: 对话轮次 | 方法: __post_init__

class DialogueTurn:
    """对话轮次"""
    turn_id: str = ""
    user_message: str = ""
    assistant_message: str = ""
    topic: TopicCategory = TopicCategory.OTHER
    timestamp: float = 0.0
    metadata: Dict = field(default_factory=dict)

    def __post_init__(self):
        if not self.turn_id:
            self.turn_id = uuid.uuid4().hex[:12]
        if not self.timestamp:
            self.timestamp = time.time()

@dataclass


DialogueContext

类 DialogueContext 在 skills/dialogue_manager.py: 对话上下文 | 方法: to_dict

class DialogueContext:
    """对话上下文"""
    session_id: str = ""
    state: DialogueState = DialogueState.STARTED
    turns: List[DialogueTurn] = field(default_factory=list)
    current_topic: TopicCategory = TopicCategory.OTHER
    topic_history: List[str] = field(default_factory=list)
    user_intent: str = ""
    mentioned_entities: List[str] = field(default_factory=list)
    turn_count: int = 0

    def to_dict(self) -> Dict:
        return {
            "session_id": self.session_id,
            "state": self.state.value,
            "turn_count": self.turn_count,
            "current_topic": self.current_topic.value,
            "topic_history": self.topic_history[-5:],  # 最近5个话题
            "user_intent": self.user_intent,
            "mentioned_entities": self.mentioned_entities[-10:],
        }


DialogueManagerSkill

对话管理技能
    管理多轮对话的上下文和状态

类 DialogueManagerSkill 在 skills/dialogue_manager.py: 对话管理技能
    管理多轮对话的上下文和状态 | 方法: __init__, process, add_assistant_response, get_context, end_session, _get_or_create_session, _identify_topic, _detect_follow_up, _resolve_references, _infer_intent

class DialogueManagerSkill:
    """
    对话管理技能
    管理多轮对话的上下文和状态
    """

    # 话题转换关键词
    TOPIC_KEYWORDS = {
        TopicCategory.GREETING: ["你好", "hello", "hi", "早上好", "晚上好"],
        TopicCategory.QUESTION: ["什么", "如何", "为什么", "怎么", "？", "?"],
        TopicCategory.TASK: ["请", "帮我", "写", "创建", "生成", "执行"],
        TopicCategory.FOLLOW_UP: ["还有", "另外", "继续", "然后呢", "接着", "更多"],
        TopicCategory.CLARIFICATION: ["你说的是", "意思是", "是指", "具体"],
        TopicCategory.CLOSING: ["再见", "谢谢", "拜拜", "bye", "结束"],
    }

    # 指代消解词
    REFERENCE_WORDS = ["这个", "那个", "它", "这", "那", "上面", "刚才", "之前"]

    def __init__(self, max_context_turns: int = 20):
        super().__init__(
            skill_type=SkillType.DIALOGUE,
            name="dialogue_manager",
            description="对话管理：上下文/多轮/话题跟踪",
        )
        self.max_context_turns = max_context_turns
        # session_id → DialogueContext
        self._sessions: Dict[str, DialogueContext] = {}

    def process(self, skill_input: SkillInput) -> SkillOutput:
        """处理对话管理"""
        text = skill_input.text
        session_id = skill_input.session_id or "default"

        # 获取或创建对话上下文
        ctx = self._get_or_create_session(session_id)

        # 1. 识别话题
        topic = self._identify_topic(text)

        # 2. 检测追问/指代
        is_follow_up = self._detect_follow_up(text, ctx)
        resolved_text = self._resolve_references(text, ctx) if is_follow_up else text

        # 3. 更新对话上下文
        turn = DialogueTurn(
            user_message=text,
            topic=topic,
        )
        ctx.turns.append(turn)
        ctx.turn_count += 1
        ctx.current_topic = topic
        ctx.state = DialogueState.ACTIVE

        # 更新话题历史
        if topic.value not in ctx.topic_history or topic != TopicCategory.FOLLOW_UP:
            ctx.topic_history.append(topic.value)

        # 保持最近N轮
        if len(ctx.turns) > self.max_context_turns:
            ctx.turns = ctx.turns[-self.max_context_turns:]

        # 4. 推断用户意图
        ctx.user_intent = self._i


方法 DialogueManagerSkill.add_assistant_response():
        """添加助手回复到对话上下文"""
        ctx = self._sessions.get(session_id)
        if ctx and ctx.turn

def add_assistant_response(self):
        """添加助手回复到对话上下文"""
        ctx = self._sessions.get(session_id)
        if ctx and ctx.turns:
            ctx.turns[-1].assistant_message = response


方法 DialogueManagerSkill.end_session():
        """结束对话会话"""
        ctx = self._sessions.get(session_id)
        if ctx:
            ctx.s

def end_session(self):
        """结束对话会话"""
        ctx = self._sessions.get(session_id)
        if ctx:
            ctx.state = DialogueState.ENDED


文件 core/memory_core.py: 虫群智能体系统 — 统一记忆核心
合并 enhanced_memory_core / v2 / simple_memory_core 三者功能
SQLite存储 + 重要性评分 + 自动分类 + 过期清理 | 定义: class MemoryCore, def __new__, def _init_db, def _init_categories, def _start_cleanup_thread, def store, def retrieve, def get_relevant_context, def get_stats, def cleanup_expired

hashlib json logging os re sqlite3 threading time collections datetime typing core.types

#!/usr/bin/env python3
"""
虫群智能体系统 — 统一记忆核心
合并 enhanced_memory_core / v2 / simple_memory_core 三者功能
SQLite存储 + 重要性评分 + 自动分类 + 过期清理
"""

import hashlib
import json
import logging
import os
import re
import sqlite3
import threading
import time
from collections import Counter
from datetime import datetime, timedelta
from typing import Dict, List, Optional

from core.types import MemoryCategory, MemoryRecord

logger = logging.getLogger(__name__)

# 默认数据库路径
DEFAULT_DB_PATH = "/home/admin/swarm/data/me


MemoryCore

类 MemoryCore 在 core/memory_core.py: 统一记忆核心 — 单例 | 方法: __new__, _init_db, _init_categories, _start_cleanup_thread, store, retrieve, get_relevant_context, get_stats, cleanup_expired, _detect_category, _calc_importance, _generate_tags, _default_retention, _increment_access, _cleanup_worker

class MemoryCore:
    """统一记忆核心 — 单例"""

    _instance = None

    def __new__(cls, db_path: str = DEFAULT_DB_PATH):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._db_path = db_path
            cls._instance._lock = threading.Lock()
            cls._instance._init_db()
            cls._instance._init_categories()
            # 启动后台清理
            cls._instance._start_cleanup_thread()
        return cls._instance

    # ============================================================
    # 初始化
    # ============================================================

    def _init_db(self):
        """初始化数据库表和索引"""
        # :memory: 模式不需要创建目录
        db_dir = os.path.dirname(self._db_path)
        if db_dir:
            os.makedirs(db_dir, exist_ok=True)
        conn = sqlite3.connect(self._db_path)
        c = conn.cursor()
        c.execute("""
            CREATE TABLE IF NOT EXISTS memories (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                memory_id TEXT UNIQUE,
                user_id TEXT,
                conversation_id TEXT,
                title TEXT,
                user_message TEXT,
                ai_response TEXT,
                category TEXT DEFAULT 'general',
                importance REAL DEFAULT 0.5,
                priority INTEGER DEFAULT 1,
                access_count INTEGER DEFAULT 0,
                tags TEXT,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                last_accessed DATETIME,
                expires_at DATETIME
            )
        """)
        for idx in ["idx_user", "idx_category", "idx_importance", "idx_expires"]:
            try:
                c.execute(f"CREATE INDEX IF NOT EXISTS {idx} ON memories({idx.replace('idx_', '')})")
            except Exception:
                pass
        conn.commit()
        conn.close()

    def _init_categories(self):
        """初始化分类关键词映射"""
        self._category_keywords = {
            MemoryCategory.GREE


文件 core/health_checker.py: 虫群智能体系统 — 模型健康检查与自动故障转移
监控模型可用性，失败时自动降级到备选模型 | 定义: class HealthStatus, def __init__, def record_success, def record_failure, def can_try, def get_status_summary, class ModelHealthChecker, def __new__, def initialize, def _update_failover_order

logging threading time collections typing datetime core.types core.model_registry

#!/usr/bin/env python3
"""
虫群智能体系统 — 模型健康检查与自动故障转移
监控模型可用性，失败时自动降级到备选模型
"""

import logging
import threading
import time
from collections import defaultdict
from typing import Dict, List, Optional, Tuple
from datetime import datetime, timedelta

from core.types import ModelStatus
from core.model_registry import ModelRegistry, get_registry

logger = logging.getLogger(__name__)

class HealthStatus:
    """单个模型的健康状态"""

    def __init__(self, model_id: str):
        self.model_id = model_id


HealthStatus

类 HealthStatus 在 core/health_checker.py: 单个模型的健康状态 | 方法: __init__, record_success, record_failure, can_try, get_status_summary

class HealthStatus:
    """单个模型的健康状态"""

    def __init__(self, model_id: str):
        self.model_id = model_id
        self.is_healthy = True
        self.last_check_time = None
        self.last_success_time = None
        self.last_failure_time = None
        self.consecutive_failures = 0
        self.consecutive_successes = 0
        self.total_checks = 0
        self.total_failures = 0
        self.avg_latency_ms = 0.0
        self._latencies = []  # 最近10次延迟

        # 熔断器状态
        self.circuit_open = False  # 熔断器是否打开（打开=不再尝试）
        self.circuit_open_time = None  # 熔断器打开时间
        self.half_open_attempts = 0  # 半开状态尝试次数

    def record_success(self, latency_ms: float):
        """记录成功"""
        self.consecutive_failures = 0
        self.consecutive_successes += 1
        self.total_checks += 1
        self.last_success_time = datetime.now()
        self.last_check_time = datetime.now()
        self.is_healthy = True

        # 延迟记录
        self._latencies.append(latency_ms)
        if len(self._latencies) > 10:
            self._latencies.pop(0)
        self.avg_latency_ms = sum(self._latencies) / len(self._latencies)

        # 熔断器：连续3次成功后关闭
        if self.circuit_open and self.consecutive_successes >= 3:
            self.circuit_open = False
            self.circuit_open_time = None
            self.half_open_attempts = 0
            logger.info(f"模型 {self.model_id} 熔断器关闭，恢复服务")

    def record_failure(self):
        """记录失败"""
        self.consecutive_successes = 0
        self.consecutive_failures += 1
        self.total_checks += 1
        self.total_failures += 1
        self.last_failure_time = datetime.now()
        self.last_check_time = datetime.now()

        # 熔断器：连续5次失败后打开
        if self.consecutive_failures >= 5 and not self.circuit_open:
            self.circuit_open = True
            self.circuit_open_time = datetime.now()
            self.is_healthy = False
            logger.warning(f"模型 {self.model_id} 熔断器打开，停止尝试")

    def can_try(self) -> bool:


方法 HealthStatus.record_success():
        """记录成功"""
        self.consecutive_failures = 0
        self.consecutive_successes += 1

def record_success(self):
        """记录成功"""
        self.consecutive_failures = 0
        self.consecutive_successes += 1
        self.total_checks += 1
        self.last_success_time = datetime.now()
        self.last_check_time = datetime.now()
        self.is_healthy = True

        # 延迟记录
        self._latencies.append(latency_ms)
        if len(self._latencies) > 10:
            self._latencies.pop(0)
        self.avg_latency_ms = sum(self._latencies) / len(self._latencies)

        # 熔断器：连续3次成功后关闭
        if self.circuit_open and self.consecutive_successes >= 3:
            self.circuit_open = False
            self.circuit_open_time = None
            self.half_open_attempts = 0
            logger.info(f"模型 {self.model_id} 熔断器关闭，恢复服务")


方法 HealthStatus.record_failure():
        """记录失败"""
        self.consecutive_successes = 0
        self.consecutive_failures += 1

def record_failure(self):
        """记录失败"""
        self.consecutive_successes = 0
        self.consecutive_failures += 1
        self.total_checks += 1
        self.total_failures += 1
        self.last_failure_time = datetime.now()
        self.last_check_time = datetime.now()

        # 熔断器：连续5次失败后打开
        if self.consecutive_failures >= 5 and not self.circuit_open:
            self.circuit_open = True
            self.circuit_open_time = datetime.now()
            self.is_healthy = False
            logger.warning(f"模型 {self.model_id} 熔断器打开，停止尝试")


ModelHealthChecker

模型健康检查器 — 单例

类 ModelHealthChecker 在 core/health_checker.py: 模型健康检查器 — 单例 | 方法: __new__, initialize, _update_failover_order, record_success, record_failure, get_healthy_models, get_fallback, check_health, check_all, get_report, _get_api_key, _get_model_name

class ModelHealthChecker:
    """模型健康检查器 — 单例"""

    _instance = None
    _lock = threading.Lock()

    def __new__(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super().__new__(cls)
                cls._instance._health = {}
                cls._instance._registry = None
                cls._instance._failover_order = []  # 故障转移顺序
                cls._instance._initialized = False
            return cls._instance

    def initialize(self, registry: ModelRegistry = None):
        """初始化健康检查器"""
        self._registry = registry or get_registry()
        # 初始化所有已注册模型的健康状态
        for model in self._registry.list_models():
            if model.model_id not in self._health:
                self._health[model.model_id] = HealthStatus(model.model_id)
        # 默认故障转移顺序：API优先 → 本地兜底
        self._update_failover_order()
        self._initialized = True
        logger.info(f"健康检查器初始化: {len(self._health)}个模型")

    def _update_failover_order(self):
        """更新故障转移顺序：本地模型在最后兜底"""
        api_models = []
        local_models = []
        for mid, hs in self._health.items():
            model = self._registry.get(mid)
            if model and model.is_local:
                local_models.append(mid)
            else:
                api_models.append(mid)
        # API优先，本地兜底
        self._failover_order = api_models + local_models
        logger.info(f"故障转移顺序: {' → '.join(self._failover_order)}")

    # ----------------------------------------------------------
    # 健康状态记录
    # ----------------------------------------------------------

    def record_success(self, model_id: str, latency_ms: float):
        """记录模型调用成功"""
        if model_id not in self._health:
            self._health[model_id] = HealthStatus(model_id)
        self._health[model_id].record_success(latency_ms)

        # 如果从不可用恢复，更新注册表状态
        if self._health[model_id].is_healthy:
            model = self._registry.get(model_id)
            if model and model.status != Mode


initialize

方法 ModelHealthChecker.initialize():
        """初始化健康检查器"""
        self._registry = registry or get_registry()
        # 初始化所有已注册模型的健康状

def initialize(self):
        """初始化健康检查器"""
        self._registry = registry or get_registry()
        # 初始化所有已注册模型的健康状态
        for model in self._registry.list_models():
            if model.model_id not in self._health:
                self._health[model.model_id] = HealthStatus(model.model_id)
        # 默认故障转移顺序：API优先 → 本地兜底
        self._update_failover_order()
        self._initialized = True
        logger.info(f"健康检查器初始化: {len(self._health)}个模型")


方法 ModelHealthChecker.record_success():
        """记录模型调用成功"""
        if model_id not in self._health:
            self._health[model_id]

def record_success(self):
        """记录模型调用成功"""
        if model_id not in self._health:
            self._health[model_id] = HealthStatus(model_id)
        self._health[model_id].record_success(latency_ms)

        # 如果从不可用恢复，更新注册表状态
        if self._health[model_id].is_healthy:
            model = self._registry.get(model_id)
            if model and model.status != ModelStatus.ACTIVE:
                self._registry.set_status(model_id, ModelStatus.ACTIVE)


方法 ModelHealthChecker.record_failure():
        """记录模型调用失败"""
        if model_id not in self._health:
            self._health[model_id]

def record_failure(self):
        """记录模型调用失败"""
        if model_id not in self._health:
            self._health[model_id] = HealthStatus(model_id)
        self._health[model_id].record_failure()

        # 如果不健康，更新注册表状态
        hs = self._health[model_id]
        if not hs.is_healthy or hs.circuit_open:
            self._registry.set_status(model_id, ModelStatus.ERROR)

    # ----------------------------------------------------------
    # 故障转移
    # ----------------------------------------------------------


文件 core/task_tree.py: 虫群v7 — 任务模型树(Task Tree)
知识树结构的按需加载任务模型群

设计思路（类比高中物理课程体系）:
- 高中物理 = 力学 + 电学 + 热学 + 光学 ...
- 力学 = 运动学 + 动力学 + 动量 + 能量 ...
- 每个知识点 = 一个任务模型(Drone)
- 上课时只加载当前章节的模型，用完卸载
- 这样内存中永远只有需要的模型在运行 | 定义: class TaskNode, def __init__, def to_dict, class TaskTree, def __init__, def _init_default_tree, def execute, def record_usage, def _ensure_loaded, def _evict_one

#!/usr/bin/env python3
"""
虫群v7 — 任务模型树(Task Tree)
知识树结构的按需加载任务模型群

设计思路（类比高中物理课程体系）:
- 高中物理 = 力学 + 电学 + 热学 + 光学 ...
- 力学 = 运动学 + 动力学 + 动量 + 能量 ...
- 每个知识点 = 一个任务模型(Drone)
- 上课时只加载当前章节的模型，用完卸载
- 这样内存中永远只有需要的模型在运行
"""

import json
import logging
import os
import time
from datetime import datetime
from typing import Dict, List, Optional

logger = logging.getLogger(__name__)

# ============================================================
# 任务节点 — 知识树的叶子/分支
# =======================================


TaskNode

类 TaskNode 在 core/task_tree.py: 任务节点 — 知识树的一个节点

    可以是分支（如"力学"）或叶子（如"牛顿第二定律"）
    叶子节点关联一个具体的任务模型 | 方法: __init__, to_dict

class TaskNode:
    """
    任务节点 — 知识树的一个节点

    可以是分支（如"力学"）或叶子（如"牛顿第二定律"）
    叶子节点关联一个具体的任务模型
    """

    def __init__(self, node_id: str, name: str,
                 domain: str = "", parent_id: str = "",
                 is_leaf: bool = False, model_id: str = ""):
        self.node_id = node_id
        self.name = name
        self.domain = domain
        self.parent_id = parent_id
        self.is_leaf = is_leaf
        self.model_id = model_id        # 叶子节点关联的模型ID
        self.children: List[str] = []    # 子节点ID列表

        # 运行时状态
        self.loaded = False              # 是否已加载到内存
        self.use_count = 0               # 使用次数
        self.last_used: Optional[float] = None

    def to_dict(self) -> Dict:
        return {
            "node_id": self.node_id,
            "name": self.name,
            "domain": self.domain,
            "parent_id": self.parent_id,
            "is_leaf": self.is_leaf,
            "model_id": self.model_id,
            "children": self.children,
            "use_count": self.use_count,
            "loaded": self.loaded,
        }

# ============================================================
# 任务模型树核心
# ============================================================


TaskTree

类 TaskTree 在 core/task_tree.py: 任务模型树 — 按需加载的知识树

    类比课程体系:
    - 根节点 = 用户的全部知识领域
    - 分支节点 = 领域分类（编程/物理/写作/日常...）
    - 叶子节点 = 具体任务模型（python基础/力学/邮件写作...）

    核心操作:
    1. execute(): 按TaskAnalysis路由到对应叶子节点执行
    2. reco | 方法: __init__, _init_default_tree, execute, record_usage, _ensure_loaded, _evict_one, unload_all, add_node, remove_node, get_tree, _load, save, get_status

class TaskTree:
    """
    任务模型树 — 按需加载的知识树

    类比课程体系:
    - 根节点 = 用户的全部知识领域
    - 分支节点 = 领域分类（编程/物理/写作/日常...）
    - 叶子节点 = 具体任务模型（python基础/力学/邮件写作...）

    核心操作:
    1. execute(): 按TaskAnalysis路由到对应叶子节点执行
    2. record_usage(): 记录使用情况，用于后续优化
    3. load/unload: 按需加载/卸载模型（内存管理）
    """

    DATA_DIR = "/home/admin/swarm/data/task_tree"
    MAX_LOADED = 3  # 同时最多加载的模型数

    def __init__(self, user_id: str = "default"):
        self.user_id = user_id
        self._nodes: Dict[str, TaskNode] = {}
        self._root_id = "root"
        self._loaded_models: Dict[str, float] = {}  # model_id -> load_time

        # 统计
        self._execute_count = 0
        self._hit_count = 0
        self._load_count = 0
        self._unload_count = 0

        # 初始化默认知识树
        self._init_default_tree()

        # 加载用户自定义树
        self._load()

    # ============================================================
    # 默认知识树
    # ============================================================

    def _init_default_tree(self):
        """初始化默认的任务模型知识树"""
        # 根节点
        root = TaskNode("root", "全部领域")
        self._nodes["root"] = root

        # 一级领域
        domains = {
            "coding": ("编程", ["python", "web", "algorithm", "database"]),
            "science": ("科学", ["physics", "math", "chemistry"]),
            "writing": ("写作", ["email", "report", "creative"]),
            "daily": ("日常", ["chat", "translate", "search"]),
            "work": ("工作", ["office", "project", "meeting"]),
        }

        for domain_id, (domain_name, leaf_names) in domains.items():
            # 创建领域分支
            domain_node = TaskNode(
                domain_id, domain_name,
                domain=domain_name, parent_id="root"
            )
            self._nodes[domain_id] = domain_node
            root.children.append(domain_id)

            # 创建叶子节点
            for leaf_name in leaf_names:
                leaf_id = f"{domain_id}


方法 TaskTree.record_usage():
        """记录使用情况，用于知识树优化"""
        intent = getattr(analysis, 'intent', 'chat')
        domains =

def record_usage(self):
        """记录使用情况，用于知识树优化"""
        intent = getattr(analysis, 'intent', 'chat')
        domains = getattr(analysis, 'knowledge_domains', [])
        route = getattr(analysis, 'route', '')

        # 记录到对应节点
        for domain in domains:
            domain_name_map = {
                "物理": "science", "编程": "coding", "数学": "science",
                "写作": "writing", "日常": "daily",
            }
            domain_id = domain_name_map.get(domain)
            if domain_id and domain_id in self._nodes:
                self._nodes[domain_id].use_count += 1
                self._nodes[domain_id].last_used = time.time()

    # ============================================================
    # 动态加载管理
    # ============================================================


方法 TaskTree.unload_all():
        """卸载所有模型"""
        self._loaded_models.clear()
        for node in self._nodes.values():


save

方法 TaskTree.save():
        """保存知识树"""
        os.makedirs(self.DATA_DIR, exist_ok=True)
        filepath = os.path.jo

def save(self):
        """保存知识树"""
        os.makedirs(self.DATA_DIR, exist_ok=True)
        filepath = os.path.join(self.DATA_DIR, f"{self.user_id}.json")

        custom_nodes = []
        for node in self._nodes.values():
            if node.node_id == "root" or "." not in node.node_id:
                continue  # 跳过默认节点
            custom_nodes.append(node.to_dict())

        try:
            with open(filepath, "w", encoding="utf-8") as f:
                json.dump({"custom_nodes": custom_nodes}, f, ensure_ascii=False, indent=2)
        except Exception as e:
            logger.warning(f"任务树保存失败: {e}")

    # ============================================================
    # 状态查询
    # ============================================================


文件 core/local_inference.py: 虫群本地推理后端
- 加载训练好的SwarmModel模型
- 提供统一的推理接口
- 支持多模型管理和切换
- 与MOA引擎集成 | 定义: class LocalModelBackend, def __init__, def _scan_models, def list_available, def get_model_info, def load, def unload, def infer, def get_status, def get_local_backend

os sys time json torch threading typing training.model training.tokenizer

#!/usr/bin/env python3
"""
虫群本地推理后端
- 加载训练好的SwarmModel模型
- 提供统一的推理接口
- 支持多模型管理和切换
- 与MOA引擎集成
"""

import os
import sys
import time
import json
import torch
import threading
from typing import Dict, List, Optional, Tuple

sys.path.insert(0, "/home/admin/swarm")

from training.model import SwarmModel
from training.tokenizer import SwarmTokenizer

class LocalModelBackend:
    """
    本地模型推理后端

    管理多个本地小模型的加载、推理和卸载。
    按需加载模型到内存，支持LRU淘汰。
    """

    def __init__(self, models_dir: str = "/ho


LocalModelBackend

类 LocalModelBackend 在 core/local_inference.py: 本地模型推理后端

    管理多个本地小模型的加载、推理和卸载。
    按需加载模型到内存，支持LRU淘汰。 | 方法: __init__, _scan_models, list_available, get_model_info, load, unload, infer, get_status

class LocalModelBackend:
    """
    本地模型推理后端

    管理多个本地小模型的加载、推理和卸载。
    按需加载模型到内存，支持LRU淘汰。
    """

    def __init__(self, models_dir: str = "/home/admin/swarm/training/models", max_loaded: int = 3):
        self.models_dir = models_dir
        self.max_loaded = max_loaded

        # 已加载的模型: model_id -> (model, tokenizer)
        self._loaded: Dict[str, Tuple[SwarmModel, SwarmTokenizer]] = {}
        self._load_times: Dict[str, float] = {}  # LRU时间戳
        self._lock = threading.Lock()

        # 可用模型列表
        self._available = self._scan_models()

        # 设备
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    def _scan_models(self) -> Dict[str, dict]:
        """扫描可用模型"""
        available = {}
        if not os.path.exists(self.models_dir):
            return available

        # 共享分词器路径
        shared_tok = os.path.join(self.models_dir, "shared_tokenizer.json")
        # v2分词器
        v2_tok = os.path.join(self.models_dir, "tokenizer_v2.json")

        for name in os.listdir(self.models_dir):
            model_dir = os.path.join(self.models_dir, name)
            if not os.path.isdir(model_dir):
                continue
            model_path = os.path.join(model_dir, "model.pt")
            meta_path = os.path.join(model_dir, "meta.json")

            if os.path.exists(model_path):
                meta = {}
                if os.path.exists(meta_path):
                    with open(meta_path, "r") as f:
                        meta = json.load(f)
                # 优先用模型目录下的分词器，否则用共享分词器或v2分词器
                tok_path = os.path.join(model_dir, "tokenizer.json")
                if not os.path.exists(tok_path) and os.path.exists(shared_tok):
                    tok_path = shared_tok
                if not os.path.exists(tok_path) and os.path.exists(v2_tok):
                    tok_path = v2_tok
                # 检测量化模型
                quantized = os.path.exists(os.path.join(model_dir,


文件 core/royal_agent.py: 虫群智能体系统 — 虫皇智能体
顶层协调器：接收用户输入 → MOA引擎处理 → 返回结果 | 定义: class RoyalAgent, def __init__, def chat, def chat_detailed, def get_status, def new_conversation, def create_royal_agent

#!/usr/bin/env python3
"""
虫群智能体系统 — 虫皇智能体
顶层协调器：接收用户输入 → MOA引擎处理 → 返回结果
"""

import logging
from datetime import datetime
from typing import Dict, Optional

from core.types import AggregationResult, AggregationMethod
from core.moa_engine import MOAEngine
from core.model_registry import get_registry, init_default_models
from core.memory_core import MemoryCore

logger = logging.getLogger(__name__)

class RoyalAgent:
    """虫皇智能体 — 系统的顶层入口"""

    def __init__(self):
        # 初始化模型注册表
        se


RoyalAgent

虫皇智能体 — 系统的顶层入口

类 RoyalAgent 在 core/royal_agent.py: 虫皇智能体 — 系统的顶层入口 | 方法: __init__, chat, chat_detailed, get_status, new_conversation

class RoyalAgent:
    """虫皇智能体 — 系统的顶层入口"""

    def __init__(self):
        # 初始化模型注册表
        self.registry = get_registry()
        init_default_models()

        # 初始化MOA引擎
        self.moa = MOAEngine(self.registry)

        # 会话状态
        self.conversation_id = datetime.now().strftime("%Y%m%d_%H%M%S")
        self.user_id = "default"

        logger.info("虫皇智能体初始化完成")

    def chat(self, message: str, user_id: str = None,
             method: AggregationMethod = None) -> str:
        """
        与虫皇对话
        Args:
            message: 用户消息
            user_id: 用户ID
            method: 聚合策略（默认自动选择）
        Returns:
            最终响应文本
        """
        if user_id:
            self.user_id = user_id

        try:
            result = self.moa.process(
                query=message,
                user_id=self.user_id,
                conversation_id=self.conversation_id,
                method=method,
            )
            return result.final_response
        except Exception as e:
            logger.error(f"虫皇处理异常: {e}")
            return f"处理出错: {str(e)}"

    def chat_detailed(self, message: str, user_id: str = None,
                      method: AggregationMethod = None) -> AggregationResult:
        """与虫皇对话（返回详细结果）"""
        if user_id:
            self.user_id = user_id
        try:
            return self.moa.process(
                query=message,
                user_id=self.user_id,
                conversation_id=self.conversation_id,
                method=method,
            )
        except Exception as e:
            logger.error(f"虫皇处理异常: {e}")
            return AggregationResult(
                query=message,
                final_response=f"处理出错: {str(e)}",
                primary_model="error",
            )

    # ============================================================
    # 状态查询
    # ============================================================

    def get_status(self) -> Dict:
        """获取系统状态"""
        registry_report = self.registry.ge


文件 core/__init__.py: 虫群智能体系统 v6 — 虫族生态体系

架构层级：
  虫皇(Overmind)  — 最高控制中心，管理整个虫群生态
  虫巢(Hive)      — 中央大模型集群，云端推理节点
  脑虫(Cerebrate) — 区域路由节点，协调虫后间的通信
  虫后(Queen)     — 个人模型系统，每个用户一套
  子虫(Drone)     — 功能型小模型，按需加载/卸载

通信流：
  | 定义:

#!/usr/bin/env python3
"""
虫群智能体系统 v6 — 虫族生态体系

架构层级：
  虫皇(Overmind)  — 最高控制中心，管理整个虫群生态
  虫巢(Hive)      — 中央大模型集群，云端推理节点
  脑虫(Cerebrate) — 区域路由节点，协调虫后间的通信
  虫后(Queen)     — 个人模型系统，每个用户一套
  子虫(Drone)     — 功能型小模型，按需加载/卸载

通信流：
  用户 → 虫后(元模型) → 脑虫(路由) → 子虫(执行) / 虫巢(大模型)
                                          ↓
                             其他虫后的子虫(跨用户协作)

命名灵感：星际争霸虫族(Zerg)生态体系
"""

from core.swarm_types import *

__version__ = "6.0.0"
__codename__ = "虫族生态"


文件 core/parametric_memory.py: 虫群v8 — 参数化记忆模型 (Parametric Memory Model)

核心理念：模型即数据库
- 传统方案：对话存数据库，检索靠关键词/向量匹配
- 参数化方案：将记忆编码为模型参数，推理时从参数直接生成

技术路线：
- 基座模型：SwarmModel small (11.8M参数)，CPU友好
- LoRA适配器：基座冻结，记忆通过LoRA增量写入
- 渐进式学习：每积累N条交互 | 定义: class LoRALayer, def __init__, def forward, def apply_lora_to_model, def get_lora_params, def get_lora_state, def set_lora_state, class MemoryEncoder, def encode_interaction, def encode_fact

copy hashlib json math os re sys time threading collections datetime typing torch torch.nn torch.nn.functional

#!/usr/bin/env python3
"""
虫群v8 — 参数化记忆模型 (Parametric Memory Model)

核心理念：模型即数据库
- 传统方案：对话存数据库，检索靠关键词/向量匹配
- 参数化方案：将记忆编码为模型参数，推理时从参数直接生成

技术路线：
- 基座模型：SwarmModel small (11.8M参数)，CPU友好
- LoRA适配器：基座冻结，记忆通过LoRA增量写入
- 渐进式学习：每积累N条交互，微调LoRA参数
- 灾难性遗忘防治：LoRA复合 + 定期蒸馏

与数据库方案的本质区别：
- 数据库：存储离散文本，检索后拼接到prompt
- 参数化：记忆融入模型参数，生成时自然流露个性化
"""

import copy
import hashlib
import json
import math
import os
import re
import sys
import time
import threading
from collections import deque
from datetime import dateti


LoRALayer

类 LoRALayer 在 core/parametric_memory.py: LoRA低秩适配层
    将记忆编码为低秩矩阵 ΔW = BA
    原始权重W冻结，只训练B和A | 方法: __init__, forward

class LoRALayer:
    """
    LoRA低秩适配层
    将记忆编码为低秩矩阵 ΔW = BA
    原始权重W冻结，只训练B和A
    """

    def __init__(self, original_linear: nn.Linear, rank: int = 8, alpha: float = 16.0):
        super().__init__()
        self.original = original_linear
        self.rank = rank
        self.alpha = alpha
        self.scaling = alpha / rank

        d_out, d_in = original_linear.weight.shape

        # LoRA矩阵: B(d_out x r) * A(r x d_in)
        self.lora_A = nn.Parameter(torch.zeros(rank, d_in))
        self.lora_B = nn.Parameter(torch.zeros(d_out, rank))

        # 初始化：A用kaiming，B用零 → 初始时ΔW=0，不影响基座
        nn.init.kaiming_uniform_(self.lora_A, a=math.sqrt(5))
        nn.init.zeros_(self.lora_B)

        # 冻结原始权重
        self.original.weight.requires_grad = False
        if self.original.bias is not None:
            self.original.bias.requires_grad = False

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # 原始变换 + LoRA增量
        original_out = self.original(x)
        lora_out = (x @ self.lora_A.T @ self.lora_B.T) * self.scaling
        return original_out + lora_out


MemoryEncoder

类 MemoryEncoder 在 core/parametric_memory.py: 将用户交互编码为模型可学习的训练样本

    格式: [BOS]用户:xxx[SEP]助手:xxx[EOS]

    关键设计：
    - 不同类型记忆用不同前缀标记
    - 重要信息重复编码强化记忆
    - 时序信息编码在特殊token中 | 方法: encode_interaction, encode_fact, encode_preference, encode_habit, encode_for_retrieval

class MemoryEncoder:
    """
    将用户交互编码为模型可学习的训练样本

    格式: [BOS]用户:xxx[SEP]助手:xxx[EOS]

    关键设计：
    - 不同类型记忆用不同前缀标记
    - 重要信息重复编码强化记忆
    - 时序信息编码在特殊token中
    """

    # 记忆类型前缀
    TYPE_PREFIX = {
        "chat": "",           # 普通对话
        "fact": "事实:",      # 事实性知识
        "preference": "偏好:", # 用户偏好
        "habit": "习惯:",     # 使用习惯
        "task": "任务:",      # 任务相关
        "emotion": "情感:",   # 情感状态
    }

    @staticmethod
    def encode_interaction(
        user_input: str,
        ai_response: str,
        memory_type: str = "chat",
        context: str = "",
        importance: float = 0.5,
    ) -> str:
        """
        编码单次交互为训练文本

        关键设计：将记忆编码为明确的问答对格式
        模型学习 "问:xxx 答:xxx" 的模式
        多次重复编码强化记忆（类似人类反复记忆）
        """
        prefix = MemoryEncoder.TYPE_PREFIX.get(memory_type, "")

        # 主要格式：问答对
        if context:
            encoded = f"[BOS]{prefix}{context}[SEP]问:{user_input}[SEP]答:{ai_response}[EOS]"
        else:
            encoded = f"[BOS]{prefix}问:{user_input}[SEP]答:{ai_response}[EOS]"

        return encoded

    @staticmethod
    def encode_fact(fact: str, source: str = "") -> str:
        """编码事实性知识"""
        if source:
            return f"[BOS]事实:来自{source}[SEP]问:{fact}[SEP]答:{fact}[EOS]"
        return f"[BOS]事实:[SEP]问:{fact}[SEP]答:{fact}[EOS]"

    @staticmethod
    def encode_preference(category: str, preference: str) -> str:
        """编码用户偏好"""
        return f"[BOS]偏好:{category}[SEP]问:你的{category}是什么[SEP]答:{preference}[EOS]"

    @staticmethod
    def encode_habit(trigger: str, behavior: str) -> str:
        """编码使用习惯"""
        return f"[BOS]习惯:[SEP]问:当{trigger}[SEP]答:{behavior}[EOS]"

    @staticmethod
    def encode_for_retrieval(query: str, memory_type: str = "") -> str:
        """编码检索查询"""
        prefix = MemoryEncoder.TYPE_PREFIX.get(memory_type, "") if memory_type else ""
        if prefix:
            return f"[BOS]{prefix}问:{query}[SEP]答:"
        return f"[B


ParametricMemoryModel

类 ParametricMemoryModel 在 core/parametric_memory.py: 参数化记忆模型 — 模型即数据库

    工作流程：
    1. 基座模型(SwarmModel) + LoRA适配器
    2. 用户交互 → 记忆编码器 → 训练样本
    3. 积累N条 → 微调LoRA → 记忆写入参数
    4. 检索时直接推理，从参数生成个性化回答

    关键优势：
    - 个性化自然流露，不是检索拼接
    - 参数压缩，比存原始 | 方法: __init__, _init_model, _load_pretrained_weights, _adapt_vocab, _init_tokenizer, store, store_fact, store_preference, _instant_write, _verify_memory, _trigger_write, _instant_write_loop, _write_memories_to_params_internal, _write_memories_to_params, recall, recall_with_context, _clean_response, _estimate_confidence, save, load, get_status, force_write, rollback

class ParametricMemoryModel:
    """
    参数化记忆模型 — 模型即数据库

    工作流程：
    1. 基座模型(SwarmModel) + LoRA适配器
    2. 用户交互 → 记忆编码器 → 训练样本
    3. 积累N条 → 微调LoRA → 记忆写入参数
    4. 检索时直接推理，从参数生成个性化回答

    关键优势：
    - 个性化自然流露，不是检索拼接
    - 参数压缩，比存原始文本省空间
    - 长期积累的参数高度贴合用户
    - 推理速度快，一次前向传播
    """

    def __init__(
        self,
        model_config: str = "small",     # 基座模型配置
        lora_rank: int = 8,               # LoRA秩
        lora_alpha: float = 16.0,         # LoRA缩放
        max_len: int = 512,               # 最大序列长度（必须匹配预训练权重）
        accumulate_steps: int = 10,       # 积累N条交互后微调
        learning_rate: float = 1e-4,      # 微调学习率
        micro_epochs: int = 3,            # 每次微调训练轮数
        write_mode: str = "instant",      # 'instant'即时写入 / 'batch'批量写入
        device: str = "auto",
        save_dir: str = "/home/admin/swarm/training/memory_model",
    ):
        self.model_config = model_config
        self.lora_rank = lora_rank
        self.lora_alpha = lora_alpha
        self.max_len = max_len
        self.accumulate_steps = accumulate_steps
        self.learning_rate = learning_rate
        self.micro_epochs = micro_epochs
        self.write_mode = write_mode
        self.save_dir = save_dir

        # 设备
        if device == "auto":
            self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        else:
            self.device = torch.device(device)

        # 初始化模型
        self._init_model()

        # 记忆缓冲区
        self.memory_buffer = deque(maxlen=1000)  # 待训练的记忆
        self.batch_fallback = deque()  # 即时写入失败时的批量回退队列
        self.total_memories = 0                    # 已写入的记忆总数
        self.total_train_steps = 0                 # 总训练步数

        # 训练线程锁
        self._train_lock = threading.Lock()
        self._is_training = False

        # 记忆快照历史（用于回滚和版本管理）
        self.snapshot_history = deque(maxlen=10)

        # 统计
        self.stats = {
            "memories_stored": 0,
            "memories_wri


save

方法 ParametricMemoryModel.save():
        """保存参数化记忆模型"""
        path = path or self.save_dir
        os.makedirs(path, exist_ok=Tru

def save(self):
        """保存参数化记忆模型"""
        path = path or self.save_dir
        os.makedirs(path, exist_ok=True)

        # 保存LoRA参数
        lora_state = get_lora_state(self.model)
        torch.save(lora_state, os.path.join(path, "lora_params.pt"))

        # 保存基座模型
        base_state = {k: v for k, v in self.model.state_dict().items()
                      if 'lora' not in k}
        torch.save(base_state, os.path.join(path, "base_model.pt"))

        # 保存分词器
        self.tokenizer.save(os.path.join(path, "tokenizer.json"))

        # 保存元信息
        meta = {
            "model_config": self.model_config,
            "lora_rank": self.lora_rank,
            "lora_alpha": self.lora_alpha,
            "max_len": self.max_len,
            "total_memories": self.total_memories,
            "total_train_steps": self.total_train_steps,
            "stats": self.stats,
            "model_info": self.model_info,
            "saved_at": datetime.now().isoformat(),


load

方法 ParametricMemoryModel.load():
        """加载参数化记忆模型"""
        path = path or self.save_dir

        # 加载LoRA参数
        lo

def load(self):
        """加载参数化记忆模型"""
        path = path or self.save_dir

        # 加载LoRA参数
        lora_path = os.path.join(path, "lora_params.pt")
        if os.path.exists(lora_path):
            lora_state = torch.load(lora_path, map_location=self.device)
            set_lora_state(self.model, lora_state)

        # 加载分词器
        tok_path = os.path.join(path, "tokenizer.json")
        if os.path.exists(tok_path):
            self.tokenizer.load(tok_path)

        # 加载元信息
        meta_path = os.path.join(path, "meta.json")
        if os.path.exists(meta_path):
            with open(meta_path) as f:
                meta = json.load(f)
            self.total_memories = meta.get("total_memories", 0)
            self.total_train_steps = meta.get("total_train_steps", 0)
            self.stats = meta.get("stats", self.stats)

        print(f"[ParametricMemory] 已加载: {self.total_memories}条记忆, {self.total_train_steps}步训练")

    # ====================================


方法 ParametricMemoryModel.force_write():
        """强制写入所有缓冲区记忆（不管阈值）"""
        if len(self.memory_buffer) > 0:
            self._write_mem

def force_write(self):
        """强制写入所有缓冲区记忆（不管阈值）"""
        if len(self.memory_buffer) > 0:
            self._write_memories_to_params()


rollback

方法 ParametricMemoryModel.rollback():
        """回滚到上一个快照"""
        if self.snapshot_history:
            last = self.snapshot_history.p

def rollback(self):
        """回滚到上一个快照"""
        if self.snapshot_history:
            last = self.snapshot_history.pop()
            set_lora_state(self.model, last["state"])
            print(f"[ParametricMemory] 已回滚到 {last['timestamp']}")
        else:
            print("[ParametricMemory] 无快照可回滚")

# ============================================================
# 记忆蒸馏 — 防止参数膨胀
# ============================================================


MemoryDistiller

类 MemoryDistiller 在 core/parametric_memory.py: 记忆蒸馏器 — 定期将LoRA参数蒸馏回基座

    问题：LoRA参数持续增长，可能偏离基座太远
    方案：定期将LoRA参数合并回基座权重，然后重置LoRA

    W_new = W_base + (B @ A) * scaling
    然后重置 B=0, A=kaiming | 方法: distill

class MemoryDistiller:
    """
    记忆蒸馏器 — 定期将LoRA参数蒸馏回基座

    问题：LoRA参数持续增长，可能偏离基座太远
    方案：定期将LoRA参数合并回基座权重，然后重置LoRA

    W_new = W_base + (B @ A) * scaling
    然后重置 B=0, A=kaiming
    """

    @staticmethod
    def distill(model: nn.Module) -> int:
        """将LoRA参数合并回基座，返回合并的层数"""
        merged_count = 0

        for name, module in model.named_modules():
            if isinstance(module, LoRALayer):
                # 合并: W = W + B @ A * scaling
                with torch.no_grad():
                    delta_w = (module.lora_B @ module.lora_A) * module.scaling
                    module.original.weight.data += delta_w

                    # 重置LoRA
                    nn.init.kaiming_uniform_(module.lora_A, a=math.sqrt(5))
                    nn.init.zeros_(module.lora_B)

                merged_count += 1

        print(f"[MemoryDistiller] 蒸馏完成: 合并{merged_count}层LoRA回基座")
        return merged_count

# ============================================================
# 快速测试
# ============================================================

if __name__ == "__main__":
    print("=" * 60)
    print("虫群v8 — 参数化记忆模型 测试")
    print("=" * 60)

    # 1. 创建记忆模型
    print("\n[1] 初始化参数化记忆模型...")
    pm = ParametricMemoryModel(
        model_config="tiny",  # 测试用tiny（小模型快速验证）
        lora_rank=4,
        accumulate_steps=5,   # 5条触发写入
        micro_epochs=5,       # 多训练几轮加深记忆
    )

    # 2. 存储记忆
    print("\n[2] 存储记忆...")
    memories = [
        ("你叫什么名字", "我是虫群助手，你的个人AI"),
        ("我喜欢用Python编程", "好的，我记住了你喜欢Python"),
        ("今天天气怎么样", "今天是晴天，适合出门"),
        ("帮我写一个函数", "好的，请告诉我函数的功能需求"),
        ("什么是虫群", "虫群是分布式小模型聚合系统"),
        ("我住在北京", "好的，我记住了你住在北京"),
        ("我的工作是什么", "你是一名软件开发工程师"),
        ("我喜欢的食物", "你喜欢川菜和火锅"),
        ("我的项目叫什么", "你的项目叫虫群Swarm"),
        ("我最近在忙什么", "你最近在开发参数化记忆模型"),
    ]

    for user, ai in memories:
        mid = pm.store(user, ai, memory_type="chat")
        print(f"  存储: {user} → {mi


加载LoORA参数（用于恢复记忆）

函数 set_lora_state(model: nn.Module, state: Dict[str, torch.Tensor]) 在 core/parametric_memory.py: 加载LoORA参数（用于恢复记忆）


文件 core/intent_recognizer.py: 意图识别器 - 从用户输入中识别真实意图 | 定义: class IntentRecognizer, def __init__, def recognize, def _match_shortcut, def _expand_abbreviation, def _match_pattern, def _fuzzy_match, def _get_default_params, def learn_from_interaction, def _extract_abbreviation

json uuid datetime typing .intent_memory_db

"""
意图识别器 - 从用户输入中识别真实意图
"""

import json
import uuid
from datetime import datetime
from typing import Optional, Dict, List, Any
from .intent_memory_db import IntentMemoryDB, IntentPattern, AbbreviationMap, UserPreferences

class IntentRecognizer:
    """意图识别器"""

    def __init__(self, db: IntentMemoryDB = None):
        self.db = db or IntentMemoryDB()

        # 常用缩写词库（可扩展）
        self.common_shortcuts = {
            "那个": "上一个任务",
            "这个": "当前任务",
            "刚才": "最


IntentRecognizer

类 IntentRecognizer 在 core/intent_recognizer.py: 意图识别器 | 方法: __init__, recognize, _match_shortcut, _expand_abbreviation, _match_pattern, _fuzzy_match, _get_default_params, learn_from_interaction, _extract_abbreviation, record_correction, _infer_format_preference, _infer_style_preference

class IntentRecognizer:
    """意图识别器"""

    def __init__(self, db: IntentMemoryDB = None):
        self.db = db or IntentMemoryDB()

        # 常用缩写词库（可扩展）
        self.common_shortcuts = {
            "那个": "上一个任务",
            "这个": "当前任务",
            "刚才": "最近一次",
            "整理": "整理文档",
            "看下": "查看状态",
            "跑一下": "执行任务",
        }

    def recognize(self, user_input: str, user_id: str = "default",
                  session_context: dict = None) -> Dict[str, Any]:
        """
        识别用户意图

        Returns:
            {
                "intent_type": str,      # 意图类型
                "entities": {},          # 提取的实体
                "filled_params": {},     # 补全的参数
                "confidence": float,     # 置信度
                "source": str,           # 来源：shortcut/pattern/model
                "needs_more_info": bool  # 是否需要更多信息
            }
        """
        context = session_context or {}
        result = {
            "original_input": user_input,
            "intent_type": None,
            "entities": {},
            "filled_params": {},
            "confidence": 0.0,
            "source": "unknown",
            "needs_more_info": False
        }

        # 步骤1：检查是否是已知缩写
        shortcut_result = self._match_shortcut(user_input, user_id)
        if shortcut_result:
            result.update(shortcut_result)
            result["source"] = "shortcut"
            return result

        # 步骤2：匹配历史意图模式
        pattern_result = self._match_pattern(user_input, user_id, context)
        if pattern_result:
            result.update(pattern_result)
            result["source"] = "pattern"
            return result

        # 步骤3：使用偏好补全（首次使用时的默认行为）
        prefs = self.db.get_preferences(user_id)
        if prefs:
            result["filled_params"] = {
                "format": prefs.default_format,
                "style": prefs.language_style,
                "granularity": prefs.task_granularity,
            }


方法 IntentRecognizer.learn_from_interaction():
        """从交互中学习"""

        # 创建新的意图模式
        pattern = IntentPattern(
            id=st

def learn_from_interaction(self):
        """从交互中学习"""

        # 创建新的意图模式
        pattern = IntentPattern(
            id=str(uuid.uuid4()),
            user_id=user_id,
            original_input=original_input,
            extracted_intent=final_intent.get("intent_type", "unknown"),
            entities_json=json.dumps(final_intent.get("entities", {})),
            filled_params_json=json.dumps(final_intent.get("filled_params", {})),
            success_score=user_satisfaction if user_satisfaction else 0.5,
            source="learned"
        )

        self.db.save_intent_pattern(pattern)

        # 提取缩写（如果原始输入很短但意图很明确）
        if len(original_input) <= 4 and len(final_intent.get("intent_type", "")) > 4:
            self._extract_abbreviation(user_id, original_input,
                                        final_intent["intent_type"])


方法 IntentRecognizer.record_correction():
        """记录用户纠错"""
        self.db.save_correction(user_id, original_output,

def record_correction(self):
        """记录用户纠错"""
        self.db.save_correction(user_id, original_output,
                                user_correction, correction_type)

        # 根据纠错类型更新偏好
        if correction_type == "format":
            # 推断新的格式偏好
            self._infer_format_preference(user_id, user_correction)
        elif correction_type == "style":
            # 推断新的风格偏好
            self._infer_style_preference(user_id, user_correction)


aggregation.py

文件 core/aggregation.py: 虫群智能体系统 — 聚合引擎
将多个模型的结果智能合并为最终响应 | 定义: class AggregationEngine, def __init__, def aggregate, def _by_confidence, def _by_weight, def _by_vote, def _by_sequential

#!/usr/bin/env python3
"""
虫群智能体系统 — 聚合引擎
将多个模型的结果智能合并为最终响应
"""

import logging
from typing import Dict, List
from datetime import datetime

from core.types import (
    AggregationMethod, AggregationResult, ModelResult, PerformanceStats
)

logger = logging.getLogger(__name__)

class AggregationEngine:
    """聚合引擎 — 合并多模型结果"""

    def __init__(self):
        self.method = AggregationMethod.CONFIDENCE

    def aggregate(self, query: str, results: List[ModelResult],
                  method: Agg


AggregationEngine

聚合引擎 — 合并多模型结果

类 AggregationEngine 在 core/aggregation.py: 聚合引擎 — 合并多模型结果 | 方法: __init__, aggregate, _by_confidence, _by_weight, _by_vote, _by_sequential

class AggregationEngine:
    """聚合引擎 — 合并多模型结果"""

    def __init__(self):
        self.method = AggregationMethod.CONFIDENCE

    def aggregate(self, query: str, results: List[ModelResult],
                  method: AggregationMethod = None) -> AggregationResult:
        """
        聚合多个模型的结果
        Args:
            query: 原始查询
            results: 各模型的处理结果列表
            method: 聚合策略（默认置信度优先）
        Returns:
            AggregationResult
        """
        method = method or self.method
        start = datetime.now()

        # 过滤失败结果
        successful = [r for r in results if r.success and r.response]
        if not successful:
            # 全部失败，收集错误并给出友好提示
            errors = [r.error for r in results if r.error]
            err_msg = "; ".join(errors[:2]) if errors else "所有模型均未返回有效结果"
            return AggregationResult(
                query=query,
                final_response=f"抱歉，暂时无法处理您的请求。原因: {err_msg}",
                method=method,
                model_results=results,
            )

        # 按策略聚合
        if method == AggregationMethod.CONFIDENCE:
            resp, primary, primary_conf = self._by_confidence(successful)
        elif method == AggregationMethod.WEIGHTED:
            resp, primary, primary_conf = self._by_weight(successful)
        elif method == AggregationMethod.VOTE:
            resp, primary, primary_conf = self._by_vote(successful)
        else:  # SEQUENTIAL
            resp, primary, primary_conf = self._by_sequential(successful)

        total_ms = sum(r.latency_ms for r in successful)

        return AggregationResult(
            query=query,
            final_response=resp,
            method=method,
            primary_model=primary,
            primary_confidence=primary_conf,
            model_results=results,
            total_latency_ms=total_ms,
        )

    # ============================================================
    # 聚合策略
    # ============================================================

    def _by_confidence(self, resul


文件 core/nim_inference.py: NVIDIA NIM推理适配器 — 虫群Swarm
通过NVIDIA NIM API调用大模型，作为Hive的增强推理后端 | 定义: class NIMInference, def __init__, def chat, def ask, def route, def ask_auto, def check_available, def get_stats

#!/usr/bin/env python3
"""
NVIDIA NIM推理适配器 — 虫群Swarm
通过NVIDIA NIM API调用大模型，作为Hive的增强推理后端
"""
import requests, time, json, threading
from typing import Optional, List, Dict

# NVIDIA NIM免费可用模型
NIM_MODELS = {
    "deepseek-v4-pro": {
        "model_id": "deepseek-ai/deepseek-v4-pro",
        "desc": "DeepSeek V4 Pro, MoE推理, 1M上下文",
        "params": "685B MoE",
        "strength": ["推理", "编码", "数学"],
    },
    "gemma-4-31b": {
        "model_id": "google/gemma-4-31b-it",
        "desc": "Gemma-4


NIMInference

类 NIMInference 在 core/nim_inference.py: NVIDIA NIM推理适配器 | 方法: __init__, chat, ask, route, ask_auto, check_available, get_stats

class NIMInference:
    """NVIDIA NIM推理适配器"""

    def __init__(self, api_key: str, base_url: str = "https://integrate.api.nvidia.com/v1"):
        self.api_key = api_key
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }
        self.stats = {"total": 0, "errors": 0, "total_ms": 0}
        self._available = None  # 缓存

    def chat(self, messages: List[Dict], model: str = "default",
             max_tokens: int = 512, temperature: float = 0.7,
             timeout: int = 60) -> Dict:
        """
        调用NIM模型
        Args:
            messages: OpenAI格式消息列表
            model: 模型名或任务类型(自动路由)
            max_tokens: 最大生成token数
            temperature: 温度
            timeout: 超时秒数
        Returns:
            {"text": str, "model": str, "ms": int, "usage": dict}
        """
        # 模型路由
        model_key = TASK_ROUTES.get(model, model)
        if model_key in NIM_MODELS:
            model_id = NIM_MODELS[model_key]["model_id"]
        elif "/" in model:
            model_id = model  # 完整模型ID
        else:
            model_id = NIM_MODELS["default"]["model_id"]

        t0 = time.time()
        self.stats["total"] += 1

        try:
            r = requests.post(
                f"{self.base_url}/chat/completions",
                headers=self.headers,
                json={
                    "model": model_id,
                    "messages": messages,
                    "max_tokens": max_tokens,
                    "temperature": temperature,
                },
                timeout=timeout,
            )
            ms = int((time.time() - t0) * 1000)
            self.stats["total_ms"] += ms

            if r.status_code == 200:
                data = r.json()
                text = data["choices"][0]["message"]["content"]
                usage = data.get("usage", {})
                return {
                    "text": text,
                    "model": model_id


文件 core/intent_memory.py: 意图记忆模块 - 整合存储与识别的统一接口
作为虫群记忆系统的核心组件 | 定义: class IntentMemory, def __init__, def recognize, def learn, def correct, def get_preferences, def set_preferences, def update_context, def get_context, def get_recent_corrections

"""
意图记忆模块 - 整合存储与识别的统一接口
作为虫群记忆系统的核心组件
"""

from .intent_memory_db import IntentMemoryDB
from .intent_recognizer import IntentRecognizer
from typing import Dict, Any, Optional

class IntentMemory:
    """
    意图记忆 - 记录和学习用户意图习惯

    核心功能：
    1. 识别用户简短指令的真实意图
    2. 记忆用户的输出格式、风格偏好
    3. 从纠错中学习，持续优化识别精度
    4. 提供上下文联想能力
    """

    def __init__(self, user_id: str = "default"):
        self.user_id = user_id
        self.db = IntentMemoryDB()
        self.recognizer = IntentRecognizer(


IntentMemory

类 IntentMemory 在 core/intent_memory.py: 意图记忆 - 记录和学习用户意图习惯

    核心功能：
    1. 识别用户简短指令的真实意图
    2. 记忆用户的输出格式、风格偏好
    3. 从纠错中学习，持续优化识别精度
    4. 提供上下文联想能力 | 方法: __init__, recognize, learn, correct, get_preferences, set_preferences, update_context, get_context, get_recent_corrections, get_intent_history

class IntentMemory:
    """
    意图记忆 - 记录和学习用户意图习惯

    核心功能：
    1. 识别用户简短指令的真实意图
    2. 记忆用户的输出格式、风格偏好
    3. 从纠错中学习，持续优化识别精度
    4. 提供上下文联想能力
    """

    def __init__(self, user_id: str = "default"):
        self.user_id = user_id
        self.db = IntentMemoryDB()
        self.recognizer = IntentRecognizer(self.db)

    def recognize(self, user_input: str, session_context: Dict = None) -> Dict[str, Any]:
        """
        识别用户输入的意图

        Args:
            user_input: 用户输入（可能很短，如"那个"、"整理"）
            session_context: 会话上下文（如当前项目、最近操作等）

        Returns:
            包含意图类型、实体、参数、置信度等的字典
        """
        return self.recognizer.recognize(user_input, self.user_id, session_context)

    def learn(self, original_input: str, final_intent: Dict,
              user_satisfaction: float = None):
        """
        从交互结果中学习

        Args:
            original_input: 用户原始输入
            final_intent: 最终执行的意图（包含intent_type, entities, filled_params）
            user_satisfaction: 用户满意度评分 0-1
        """
        self.recognizer.learn_from_interaction(
            self.user_id, original_input, final_intent, user_satisfaction
        )

    def correct(self, original_ai_output: str, user_correction: str,
                correction_type: str = "content"):
        """
        记录用户的纠正，并学习调整

        Args:
            original_ai_output: AI原来的输出
            user_correction: 用户的修正
            correction_type: 纠错类型（format/content/style/omission）
        """
        self.recognizer.record_correction(
            self.user_id, original_ai_output, user_correction, correction_type
        )

    def get_preferences(self) -> Dict[str, Any]:
        """获取用户的格式/风格偏好"""
        from .intent_memory_db import UserPreferences
        prefs = self.db.get_preferences(self.user_id)

        if prefs:
            return {
                "format": prefs.default_format,
                "style": prefs.language_style,
                "time_preferenc


learn

方法 IntentMemory.learn():
        """
        从交互结果中学习

        Args:
            original_input: 用户原始输入

def learn(self):
        """
        从交互结果中学习

        Args:
            original_input: 用户原始输入
            final_intent: 最终执行的意图（包含intent_type, entities, filled_params）
            user_satisfaction: 用户满意度评分 0-1
        """
        self.recognizer.learn_from_interaction(
            self.user_id, original_input, final_intent, user_satisfaction
        )


correct

方法 IntentMemory.correct():
        """
        记录用户的纠正，并学习调整

        Args:
            original_ai_output: AI原来的输出

def correct(self):
        """
        记录用户的纠正，并学习调整

        Args:
            original_ai_output: AI原来的输出
            user_correction: 用户的修正
            correction_type: 纠错类型（format/content/style/omission）
        """
        self.recognizer.record_correction(
            self.user_id, original_ai_output, user_correction, correction_type
        )


方法 IntentMemory.set_preferences():
        """设置用户偏好"""
        from .intent_memory_db import UserPreferences

        existin

def set_preferences(self):
        """设置用户偏好"""
        from .intent_memory_db import UserPreferences

        existing = self.db.get_preferences(self.user_id)
        if existing:
            for key, value in kwargs.items():
                if hasattr(existing, key):
                    setattr(existing, key, value)
            self.db.save_preferences(existing)
        else:
            prefs = UserPreferences(user_id=self.user_id, **kwargs)
            self.db.save_preferences(prefs)


方法 IntentMemory.update_context():
        """更新会话上下文"""
        self.db.update_context(
            self.user_id, session_id,

def update_context(self):
        """更新会话上下文"""
        self.db.update_context(
            self.user_id, session_id,
            current_entity, active_project, recent_intents
        )


快速学习意图（单次调用）

函数 learn_intent(user_input: str, intent: Dict,
                 user_id: str = "default", satisfaction: float = None) 在 core/intent_memory.py: 快速学习意图（单次调用）

def learn_intent(user_input: str, intent: Dict,
                 user_id: str = "default", satisfaction: float = None):
    """快速学习意图（单次调用）"""
    memory = IntentMemory(user_id)
    memory.learn(user_input, intent, satisfaction)

# 测试
if __name__ == "__main__":
    import json

    memory = IntentMemory("test_user")

    # 1. 首次识别（无历史）
    print("=== 首次识别 ===")
    result = memory.recognize("整理那个", {"active_project": "虫群开发"})
    print(json.dumps(result, ensure_ascii=False, indent=2))

    # 2. 学习
    print("\n=== 学习意图 ===")
    memory.learn(
        "整理那个",
        {
            "intent_type": "整理项目文档",
            "entities": {"project": "虫群开发"},
            "filled_params": {"format": "markdown表格", "style": "简洁"}
        },
        user_satisfaction=0.8
    )

    # 3. 再次识别（已有学习）
    print("\n=== 再次识别 ===")
    result2 = memory.recognize("整理那个", {"active_project": "虫群开发"})
    print(json.dumps(result2, ensure_ascii=False, indent=2))

    # 4. 记录纠错
    print("\n=== 记录纠错 ===")
    memory.correct("详细报告", "太长了，用表格简洁展示", "format")

    # 5. 获取偏好
    print("\n=== 当前偏好 ===")
    prefs = memory.get_preferences()
    print(json.dumps(prefs, ensure_ascii=False, indent=2))


文件 core/moa_engine.py: 虫群智能体系统 — MOA多模型聚合引擎
Mixtures of Agents: 路由 → 并行执行 → 聚合 | 定义: class MOAEngine, def __init__, def pipeline, def process, def _execute_models, def _exec_local, def _exec_local_inference, def _exec_api, def process_stream, def _stream_api

#!/usr/bin/env python3
"""
虫群智能体系统 — MOA多模型聚合引擎
Mixtures of Agents: 路由 → 并行执行 → 聚合
"""

import logging
import os
import time
import json
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Dict, List, Optional

import requests

from core.types import (
    ModelResult, AggregationResult, AggregationMethod,
    TaskContext, ComplexityLevel, ModelType
)
from core.model_registry import ModelRegistry, get_registry
from core.router import SwarmRouter
from core.aggregati


MOAEngine

MOA多模型聚合引擎 — 核心处理流水线

类 MOAEngine 在 core/moa_engine.py: MOA多模型聚合引擎 — 核心处理流水线 | 方法: __init__, pipeline, process, _execute_models, _exec_local, _exec_local_inference, _exec_api, process_stream, _stream_api, _load_api_keys, _get_api_model_name, _quick_match, _run_skill_pipeline

class MOAEngine:
    """MOA多模型聚合引擎 — 核心处理流水线"""

    def __init__(self, registry: ModelRegistry = None):
        self.registry = registry or get_registry()
        self.router = SwarmRouter(self.registry)
        self.aggregator = AggregationEngine()
        self.memory = MemoryCore()
        # 配置中心
        self._config = get_config()
        # 加载API密钥（优先从配置中心读取）
        self._api_keys = self._load_api_keys()
        # 技能管线（延迟初始化）
        self._pipeline = None
        # 性能监控
        self._monitor = get_monitor()
        # 对话上下文管理
        self._conv_mgr = get_conversation_manager()
        # 健康检查
        self._health = get_health_checker()
        # 智能缓存
        self._cache = get_cache()

        logger.info("MOA引擎初始化完成(含配置中心+日志系统)")

    @property
    def pipeline(self):
        """延迟加载技能管线"""
        if self._pipeline is None:
            try:
                from skills import create_default_pipeline
                self._pipeline = create_default_pipeline()
                logger.info("技能管线初始化完成")
            except Exception as e:
                logger.warning(f"技能管线初始化失败: {e}")
        return self._pipeline

    # ============================================================
    # 主入口
    # ============================================================

    def process(self, query: str, user_id: str = "default",
                conversation_id: str = "",
                method: AggregationMethod = None) -> AggregationResult:
        """
        处理用户查询的完整流水线：
        0. 技能管线预处理（安全检查 + 文本分析 + 任务分类）
        1. 路由分析（复杂度 + 模型链推荐）
        2. 并行执行模型
        3. 聚合结果
        4. 存储记忆
        """
        start_time = time.time()

        # -1. 缓存查询
        cached = self._cache.get(query)
        if cached:
            logger.info(f"缓存命中: {query[:30]} (命中{cached.hit_count}次)")
            return AggregationResult(
                query=query,
                final_response=cached.response,
                primary_model=f"{cached.model_id}(cached)",
            )

        # 0. 技能管线预处理


pipeline

方法 MOAEngine.pipeline():
        """延迟加载技能管线"""
        if self._pipeline is None:
            try:
                from ski

def pipeline(self):
        """延迟加载技能管线"""
        if self._pipeline is None:
            try:
                from skills import create_default_pipeline
                self._pipeline = create_default_pipeline()
                logger.info("技能管线初始化完成")
            except Exception as e:
                logger.warning(f"技能管线初始化失败: {e}")
        return self._pipeline

    # ============================================================
    # 主入口
    # ============================================================


方法 MOAEngine.process_stream():
        """
        流式处理用户查询，逐字返回结果。
        生成器模式：yield (chunk_text, metadata_dict)
        """

def process_stream(self):
        """
        流式处理用户查询，逐字返回结果。
        生成器模式：yield (chunk_text, metadata_dict)
        """
        # 0. 技能管线预处理
        skill_analysis = self._run_skill_pipeline(query, user_id, conversation_id)

        if skill_analysis and not skill_analysis.get("is_safe", True):
            yield ("抱歉，您的请求包含不安全内容，无法处理。",
                   {"model": "safety_filter", "done": True})
            return

        # 1. 快速规则匹配
        quick = self._quick_match(query)
        if quick:
            yield (quick, {"model": "local_memory", "done": True})
            return

        # 2. 路由分析
        ctx = self.router.analyze(query, user_id, conversation_id)

        # 技能分析调整
        if skill_analysis and ctx.metadata is not None:
            ctx.metadata["skill_analysis"] = skill_analysis
            task_cat = skill_analysis.get("task_category", "")
            if task_cat in ("code", "analysis"):
                if ctx.complexity_score < 0.50:
                    ctx.complexity_score = min(ctx.comple


文件 core/meta_model.py: 虫群v7 — 元模型(Meta Model)
虫后的核心调度器：意图识别 → 任务拆分 → 路由决策

设计思路：
- 元模型是虫后的"大脑"，负责分析用户输入并决定如何响应
- 当前基于规则+关键词实现，后续可替换为1B以下的小模型
- 输出TaskAnalysis，包含意图、复杂度、路由、子任务 | 定义: class MetaModel, def __init__, def analyze, def _detect_intent, def _assess_complexity, def _decide_route, def _decompose, def _detect_domains, def _intent_to_drone, def _calc_confidence

logging re uuid typing datetime core.types

#!/usr/bin/env python3
"""
虫群v7 — 元模型(Meta Model)
虫后的核心调度器：意图识别 → 任务拆分 → 路由决策

设计思路：
- 元模型是虫后的"大脑"，负责分析用户输入并决定如何响应
- 当前基于规则+关键词实现，后续可替换为1B以下的小模型
- 输出TaskAnalysis，包含意图、复杂度、路由、子任务
"""

import logging
import re
import uuid
from typing import Dict, List, Optional
from datetime import datetime

from core.types import (
    TaskAnalysis, SubTask, DroneType, TaskPriority,
)

logger = logging.getLogger(__name__)

# ============================================================
# 意图识别规则
# ================


MetaModel

类 MetaModel 在 core/meta_model.py: 元模型 — 虫后的核心调度器

    三步走：
    1. analyze(): 意图识别 + 复杂度评估
    2. decompose(): 任务拆分（复杂任务才需要）
    3. route(): 路由决策（选模型/虫巢/其他虫后） | 方法: __init__, analyze, _detect_intent, _assess_complexity, _decide_route, _decompose, _detect_domains, _intent_to_drone, _calc_confidence, get_status

class MetaModel:
    """
    元模型 — 虫后的核心调度器

    三步走：
    1. analyze(): 意图识别 + 复杂度评估
    2. decompose(): 任务拆分（复杂任务才需要）
    3. route(): 路由决策（选模型/虫巢/其他虫后）
    """

    def __init__(self, user_id: str = "default"):
        self.user_id = user_id
        self._analyze_count = 0
        self._last_analysis: Optional[TaskAnalysis] = None

    # ============================================================
    # 核心方法: analyze — 三步合一
    # ============================================================

    def analyze(self, message: str, context: str = "") -> TaskAnalysis:
        """
        分析用户输入 → 返回TaskAnalysis

        Args:
            message: 用户消息
            context: 记忆上下文（来自MemoryModel）
        Returns:
            TaskAnalysis: 意图+复杂度+路由+子任务
        """
        self._analyze_count += 1

        # Step 1: 意图识别
        intent = self._detect_intent(message)

        # Step 2: 复杂度评估
        complexity = self._assess_complexity(message, intent)

        # Step 3: 路由决策
        route, assigned_model = self._decide_route(intent, complexity, context)

        # Step 4: 子任务拆分（复杂任务才拆）
        subtasks = []
        if complexity > 0.6 or intent == "multi":
            subtasks = self._decompose(message, intent)

        # Step 5: 知识领域识别
        domains = self._detect_domains(message)

        # 组装结果
        analysis = TaskAnalysis(
            query=message,
            intent=intent,
            complexity=complexity,
            route=route,
            assigned_model=assigned_model,
            subtasks=subtasks,
            confidence=self._calc_confidence(intent, complexity),
            requires_memory=bool(context),
            knowledge_domains=domains,
            reasoning_chain=[
                f"意图={intent}",
                f"复杂度={complexity:.2f}",
                f"路由={route}",
                f"子任务数={len(subtasks)}",
            ],
        )

        self._last_analysis = analysis
        logger.debug(f"元模型分析: intent=


文件 core/smart_cache.py: 虫群智能体系统 — 智能缓存层
缓存重复查询结果，减少API调用
LRU + TTL + 语义相似度匹配 | 定义: class CacheEntry, def __init__, def is_expired, def age_seconds, def hit, def to_dict, def from_dict, class SmartCache, def __new__, def initialize

hashlib json logging os threading time collections typing

#!/usr/bin/env python3
"""
虫群智能体系统 — 智能缓存层
缓存重复查询结果，减少API调用
LRU + TTL + 语义相似度匹配
"""

import hashlib
import json
import logging
import os
import threading
import time
from collections import OrderedDict
from typing import Dict, List, Optional, Tuple

logger = logging.getLogger(__name__)

DEFAULT_CACHE_DIR = "/home/admin/swarm/data/cache"

class CacheEntry:
    """缓存条目"""

    def __init__(self, query: str, response: str, model_id: str,
                 confidence: float, ttl: int = 3600):


CacheEntry

类 CacheEntry 在 core/smart_cache.py: 缓存条目 | 方法: __init__, is_expired, age_seconds, hit, to_dict, from_dict

class CacheEntry:
    """缓存条目"""

    def __init__(self, query: str, response: str, model_id: str,
                 confidence: float, ttl: int = 3600):
        self.query = query
        self.response = response
        self.model_id = model_id
        self.confidence = confidence
        self.created_at = time.time()
        self.ttl = ttl  # 秒
        self.hit_count = 0
        self.last_hit_at = None

    @property
    def is_expired(self) -> bool:
        return time.time() - self.created_at > self.ttl

    @property
    def age_seconds(self) -> float:
        return time.time() - self.created_at

    def hit(self):
        """记录一次命中"""
        self.hit_count += 1
        self.last_hit_at = time.time()

    def to_dict(self) -> Dict:
        return {
            "query": self.query,
            "response": self.response,
            "model_id": self.model_id,
            "confidence": self.confidence,
            "created_at": self.created_at,
            "ttl": self.ttl,
            "hit_count": self.hit_count,
            "last_hit_at": self.last_hit_at,
        }

    @classmethod
    def from_dict(cls, d: Dict) -> "CacheEntry":
        entry = cls(d["query"], d["response"], d["model_id"],
                    d["confidence"], d.get("ttl", 3600))
        entry.created_at = d.get("created_at", time.time())
        entry.hit_count = d.get("hit_count", 0)
        entry.last_hit_at = d.get("last_hit_at")
        return entry


hit

方法 CacheEntry.hit():
        """记录一次命中"""
        self.hit_count += 1
        self.last_hit_at = time.time()

def hit(self):
        """记录一次命中"""
        self.hit_count += 1
        self.last_hit_at = time.time()


SmartCache

类 SmartCache 在 core/smart_cache.py: 智能缓存 — 单例
    特性：
    - LRU淘汰（容量上限）
    - TTL过期（时间上限）
    - 语义相似度匹配（相似问题命中缓存）
    - 关键词去重（核心词相同视为同一查询） | 方法: __new__, initialize, get, put, invalidate, clear, _find_similar, _extract_keywords, _update_keyword_index, _make_key, _should_skip, get_stats, get_top_entries, _save, _load

class SmartCache:
    """
    智能缓存 — 单例
    特性：
    - LRU淘汰（容量上限）
    - TTL过期（时间上限）
    - 语义相似度匹配（相似问题命中缓存）
    - 关键词去重（核心词相同视为同一查询）
    """

    _instance = None
    _lock = threading.Lock()

    # 缓存配置
    MAX_ENTRIES = 500        # 最大条目数
    DEFAULT_TTL = 3600       # 默认1小时过期
    SIMILARITY_THRESHOLD = 0.8  # 相似度阈值

    def __new__(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super().__new__(cls)
                cls._instance._cache = OrderedDict()  # key -> CacheEntry
                cls._instance._keyword_index = {}     # 关键词集合 -> cache_key
                cls._instance._stats = {
                    "hits": 0, "misses": 0, "evictions": 0, "expirations": 0
                }
                cls._instance._initialized = False
            return cls._instance

    def initialize(self):
        """初始化缓存"""
        # 尝试加载持久化缓存
        self._load()
        self._initialized = True
        logger.info(f"智能缓存初始化: {len(self._cache)}条缓存")

    # ----------------------------------------------------------
    # 核心：查询/存储
    # ----------------------------------------------------------

    def get(self, query: str) -> Optional[CacheEntry]:
        """
        查询缓存
        策略：精确匹配 → 关键词匹配 → 无命中
        """
        # 1. 精确匹配
        key = self._make_key(query)
        entry = self._cache.get(key)
        if entry and not entry.is_expired:
            entry.hit()
            self._stats["hits"] += 1
            # LRU：移到末尾
            self._cache.move_to_end(key)
            logger.debug(f"缓存命中(精确): {query[:30]}")
            return entry
        elif entry and entry.is_expired:
            # 过期，删除
            del self._cache[key]
            self._stats["expirations"] += 1

        # 2. 关键词相似度匹配
        similar = self._find_similar(query)
        if similar:
            similar.hit()
            self._stats["hits"] += 1
            logger.debug(f"缓存命中(相似): {query[:30]} → {similar.query[:30]}")
            return similar

        self._stat


initialize

方法 SmartCache.initialize():
        """初始化缓存"""
        # 尝试加载持久化缓存
        self._load()
        self._initialized = True


put

方法 SmartCache.put():
        """
        存储到缓存
        仅缓存有意义的查询（太短/太常见的跳过）
        """
        # 过滤不需要缓存的查询
        if

def put(self):
        """
        存储到缓存
        仅缓存有意义的查询（太短/太常见的跳过）
        """
        # 过滤不需要缓存的查询
        if self._should_skip(query):
            return

        key = self._make_key(query)
        entry = CacheEntry(query, response, model_id, confidence,
                           ttl or self.DEFAULT_TTL)

        # 容量检查：LRU淘汰
        while len(self._cache) >= self.MAX_ENTRIES:
            oldest_key = next(iter(self._cache))
            del self._cache[oldest_key]
            self._stats["evictions"] += 1

        self._cache[key] = entry
        # 更新关键词索引
        self._update_keyword_index(key, query)

        # 持久化（节流：每10次写入持久化一次）
        if self._stats["misses"] % 10 == 0:
            self._save()


invalidate

方法 SmartCache.invalidate():
        """使指定查询的缓存失效"""
        key = self._make_key(query)
        if key in self._cache:

def invalidate(self):
        """使指定查询的缓存失效"""
        key = self._make_key(query)
        if key in self._cache:
            del self._cache[key]


clear

方法 SmartCache.clear():
        """清空缓存"""
        self._cache.clear()
        self._keyword_index.clear()
        self._sa


文件 core/moa_aggregator.py: MOA聚合器 — Mixture of Agents
将多个模型的回答聚合为最优答案
支持策略：投票/质量评分/级联/自适应 | 定义: class AggregationStrategy, class
class, def answer_hash, class
class, class QualityScorer, def score, class VotingAggregator, def aggregate, class QualityAggregator, def __init__

time logging hashlib typing dataclasses enum

"""
MOA聚合器 — Mixture of Agents
将多个模型的回答聚合为最优答案
支持策略：投票/质量评分/级联/自适应
"""
import time
import logging
import hashlib
from typing import List, Dict, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum

logger = logging.getLogger(__name__)

class AggregationStrategy(Enum):
    """聚合策略"""
    VOTING = "voting"           # 多数投票
    QUALITY = "quality"         # 质量评分
    CASCADING = "cascading"     # 级联(先快后精)
    ADAPTIVE = "adaptive"       # 自适应(根据问题选择)

@dataclass
class Model


AggregationStrategy

类 AggregationStrategy 在 core/moa_aggregator.py: 聚合策略 | 方法:

class AggregationStrategy:
    """聚合策略"""
    VOTING = "voting"           # 多数投票
    QUALITY = "quality"         # 质量评分
    CASCADING = "cascading"     # 级联(先快后精)
    ADAPTIVE = "adaptive"       # 自适应(根据问题选择)

@dataclass


ModelAnswer

类 ModelAnswer 在 core/moa_aggregator.py: 单个模型的回答 | 方法: answer_hash

class ModelAnswer:
    """单个模型的回答"""
    answer: str
    model: str
    provider: str
    confidence: float = 0.0
    latency_ms: float = 0.0
    source: str = "api"    # api / local / memory

    @property
    def answer_hash(self) -> str:
        return hashlib.md5(self.answer.strip().encode()).hexdigest()[:8]

@dataclass


MOAResult

类 MOAResult 在 core/moa_aggregator.py: MOA聚合结果 | 方法:

class MOAResult:
    """MOA聚合结果"""
    final_answer: str
    strategy: str
    contributors: List[str]
    confidence: float
    details: Dict = field(default_factory=dict)


QualityScorer

类 QualityScorer 在 core/moa_aggregator.py: 回答质量评分器 | 方法: score

class QualityScorer:
    """回答质量评分器"""

    # source权重：API模型回答更可靠
    SOURCE_WEIGHTS = {
        "api": 0.15,       # API模型回答加分
        "memory": 0.0,     # 本地记忆不加不扣
        "local": -0.1,     # 本地tiny模型可能乱码
        "swarm": 0.05,     # 远程节点中等
    }

    def score(self, answer: str, question: str = "", source: str = "") -> float:
        """评分0-1，越高越好"""
        if not answer or not answer.strip():
            return 0.0

        score = 0.5  # 基础分

        # source权重
        score += self.SOURCE_WEIGHTS.get(source, 0.0)

        # 乱码检测：单字比例过高=乱码
        chars = [c for c in answer if '\u4e00' <= c <= '\u9fff']
        if chars:
            unique_chars = set(chars)
            char_repeat_ratio = 1.0 - len(unique_chars) / max(len(chars), 1)
            if char_repeat_ratio > 0.5:
                score -= 0.3  # 字符重复率过高，明显乱码

        # 单字散布检测：乱码特征=大量无意义单字间隔
        words = answer.split()
        if len(words) > 10:
            avg_word_len = sum(len(w) for w in words) / len(words)
            if avg_word_len < 1.5:  # 平均词长太短=乱码
                score -= 0.35

        # 长度合理性(太短太长都扣分)
        length = len(answer)
        if 20 <= length <= 500:
            score += 0.15
        elif 10 <= length <= 1000:
            score += 0.08
        elif length < 10:
            score -= 0.2

        # 是否包含有用的结构
        useful_patterns = [
            ("因为", 0.05), ("所以", 0.05), ("首先", 0.03),
            ("建议", 0.05), ("可以", 0.03), ("根据", 0.05),
            ("是", 0.02), ("有", 0.02)
        ]
        for pattern, bonus in useful_patterns:
            if pattern in answer:
                score += bonus

        # 扣分：AI拒绝回答
        reject_patterns = ["我不能", "我无法", "作为AI", "我是一个AI", "I cannot"]
        for pattern in reject_patterns:
            if pattern in answer:
                score -= 0.3
                break

        # 扣分：重复内容
        if len(words) > 5:
            unique_ratio = len(set(words)) / len(words)
            if


VotingAggregator

投票聚合 — 相似回答计票

类 VotingAggregator 在 core/moa_aggregator.py: 投票聚合 — 相似回答计票 | 方法: aggregate

class VotingAggregator:
    """投票聚合 — 相似回答计票"""

    def aggregate(self, answers: List[ModelAnswer]) -> MOAResult:
        if not answers:
            return MOAResult("", "voting", [], 0.0)

        if len(answers) == 1:
            return MOAResult(answers[0].answer, "voting",
                           [answers[0].model], answers[0].confidence)

        # 简单投票：找最长的有效回答(避免短回答和拒绝)
        scorer = QualityScorer()
        scored = [(a, scorer.score(a.answer, source=a.source)) for a in answers]
        scored.sort(key=lambda x: x[1], reverse=True)

        best_answer, best_score = scored[0]

        # 检查是否有相似回答(半数以上一致)
        best_words = set(best_answer.answer.split()[:20])
        similar_count = 1
        for a, s in scored[1:]:
            a_words = set(a.answer.split()[:20])
            overlap = len(best_words & a_words)
            if overlap > len(best_words) * 0.3:
                similar_count += 1

        confidence = min(1.0, best_score + similar_count * 0.1)

        return MOAResult(
            final_answer=best_answer.answer,
            strategy="voting",
            contributors=[a.model for a, _ in scored[:3]],
            confidence=confidence,
            details={"similar_count": similar_count, "scores": {a.model: float(s) for a, s in scored}}
        )


QualityAggregator

质量聚合 — 选质量最高的回答

类 QualityAggregator 在 core/moa_aggregator.py: 质量聚合 — 选质量最高的回答 | 方法: __init__, aggregate

class QualityAggregator:
    """质量聚合 — 选质量最高的回答"""

    def __init__(self):
        self.scorer = QualityScorer()

    def aggregate(self, answers: List[ModelAnswer]) -> MOAResult:
        if not answers:
            return MOAResult("", "quality", [], 0.0)

        scored = []
        for a in answers:
            q_score = self.scorer.score(a.answer, source=a.source)
            # 综合分 = 质量分*0.6 + 置信度*0.3 + 速度奖励*0.1
            speed_bonus = max(0, 1.0 - a.latency_ms / 10000) * 0.1
            total = q_score * 0.6 + a.confidence * 0.3 + speed_bonus
            scored.append((a, total, q_score))

        scored.sort(key=lambda x: x[1], reverse=True)
        best = scored[0]

        return MOAResult(
            final_answer=best[0].answer,
            strategy="quality",
            contributors=[a.model for a, _, _ in scored[:3]],
            confidence=best[1],
            details={"quality_scores": {a.model: float(q) for a, _, q in scored}}
        )


CascadingAggregator

类 CascadingAggregator 在 core/moa_aggregator.py: 级联聚合 — 先快后精 | 方法: __init__, aggregate

class CascadingAggregator:
    """级联聚合 — 先快后精"""

    def __init__(self, fast_threshold_ms: float = 2000):
        self.fast_threshold_ms = fast_threshold_ms

    def aggregate(self, answers: List[ModelAnswer]) -> MOAResult:
        if not answers:
            return MOAResult("", "cascading", [], 0.0)

        scorer = QualityScorer()

        # 第一阶段：快速回答
        fast_answers = [a for a in answers if a.latency_ms < self.fast_threshold_ms]

        if fast_answers:
            best_fast = max(fast_answers, key=lambda a: scorer.score(a.answer, source=a.source))
            fast_score = scorer.score(best_fast.answer, source=best_fast.source)

            # 如果快速回答已经够好，直接返回
            if fast_score >= 0.7:
                return MOAResult(
                    final_answer=best_fast.answer,
                    strategy="cascading",
                    contributors=[best_fast.model],
                    confidence=fast_score,
                    details={"stage": "fast", "fast_score": float(fast_score)}
                )

        # 第二阶段：用所有回答选最优
        all_scored = [(a, scorer.score(a.answer, source=a.source)) for a in answers]
        all_scored.sort(key=lambda x: x[1], reverse=True)
        best = all_scored[0]

        return MOAResult(
            final_answer=best[0].answer,
            strategy="cascading",
            contributors=[a.model for a, _ in all_scored[:3]],
            confidence=best[1],
            details={"stage": "refined", "fast_available": len(fast_answers)}
        )


AdaptiveAggregator

自适应聚合 — 根据问题类型选择策略

类 AdaptiveAggregator 在 core/moa_aggregator.py: 自适应聚合 — 根据问题类型选择策略 | 方法: __init__, _classify_question, aggregate

class AdaptiveAggregator:
    """自适应聚合 — 根据问题类型选择策略"""

    def __init__(self):
        self.voting = VotingAggregator()
        self.quality = QualityAggregator()
        self.cascading = CascadingAggregator()

    def _classify_question(self, question: str) -> str:
        """问题分类"""
        if any(kw in question for kw in ["什么", "定义", "解释", "what", "define"]):
            return "factual"    # 事实型
        elif any(kw in question for kw in ["怎么", "如何", "方法", "how"]):
            return "procedural" # 过程型
        elif any(kw in question for kw in ["推荐", "建议", "哪个好", "suggest"]):
            return "advisory"   # 建议型
        else:
            return "general"    # 通用

    def aggregate(self, answers: List[ModelAnswer], question: str = "") -> MOAResult:
        if not answers:
            return MOAResult("", "adaptive", [], 0.0)

        if len(answers) == 1:
            return MOAResult(answers[0].answer, "adaptive",
                           [answers[0].model], answers[0].confidence)

        q_type = self._classify_question(question)

        if q_type == "factual":
            result = self.voting.aggregate(answers)  # 事实型用投票
        elif q_type == "procedural":
            result = self.quality.aggregate(answers)  # 过程型用质量
        elif q_type == "advisory":
            result = self.cascading.aggregate(answers) # 建议型用级联
        else:
            result = self.quality.aggregate(answers)  # 默认质量

        result.strategy = f"adaptive({q_type}->{result.strategy})"
        return result


MOAAggregator

类 MOAAggregator 在 core/moa_aggregator.py: MOA聚合器入口 | 方法: __init__, aggregate, set_strategy

class MOAAggregator:
    """MOA聚合器入口"""

    def __init__(self, strategy: AggregationStrategy = AggregationStrategy.ADAPTIVE):
        self.strategy = strategy
        self.strategies = {
            AggregationStrategy.VOTING: VotingAggregator(),
            AggregationStrategy.QUALITY: QualityAggregator(),
            AggregationStrategy.CASCADING: CascadingAggregator(),
            AggregationStrategy.ADAPTIVE: AdaptiveAggregator(),
        }
        self.stats = {"total_aggregations": 0, "by_strategy": {}}

    def aggregate(self, answers: List[ModelAnswer], question: str = "") -> MOAResult:
        """聚合多个模型的回答"""
        if not answers:
            return MOAResult("", self.strategy.value, [], 0.0)

        aggregator = self.strategies.get(self.strategy)
        if not aggregator:
            aggregator = self.strategies[AggregationStrategy.QUALITY]

        if isinstance(aggregator, AdaptiveAggregator):
            result = aggregator.aggregate(answers, question)
        else:
            result = aggregator.aggregate(answers)

        # 更新统计
        self.stats["total_aggregations"] += 1
        base_strategy = result.strategy.split("->")[-1] if "->" in result.strategy else result.strategy
        self.stats["by_strategy"][base_strategy] = self.stats["by_strategy"].get(base_strategy, 0) + 1

        logger.info(f"[MOA] 聚合策略={result.strategy}, 贡献者={result.contributors}, 置信度={result.confidence:.2f}")
        return result

    def set_strategy(self, strategy: AggregationStrategy):
        self.strategy = strategy


方法 MOAAggregator.set_strategy():
        self.strategy = strategy

def set_strategy(self):
        self.strategy = strategy


文件 core/task_dispatcher.py: 虫群任务调度器 — 主控模型拆分任务，分配给最优模型执行 | 定义: class TaskStatus, class TaskType, class
class, class
class, class TaskDispatcher, def __init__, def _init_adapters, def select_model, def execute_subtask, def execute_plan

os json time asyncio typing dataclasses enum core.model_adapter core.model_registry

#!/usr/bin/env python3
"""
虫群任务调度器 — 主控模型拆分任务，分配给最优模型执行
"""

import os
import json
import time
import asyncio
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field, asdict
from enum import Enum

from core.model_adapter import (
    ModelAdapter, ZhipuAdapter, NvidiaNimAdapter, SiliconFlowAdapter,
    CallResult, create_adapter
)
from core.model_registry import ModelRegistry, ModelProvider, ModelInfo, model_registry

class TaskStatus(Enum):
    PENDING = "pending"


TaskStatus

类 TaskStatus 在 core/task_dispatcher.py:  | 方法:

class TaskStatus:
    PENDING = "pending"
    RUNNING = "running"
    DONE = "done"
    FAILED = "failed"


TaskType

类 TaskType 在 core/task_dispatcher.py:  | 方法:

class TaskType:
    REASONING = "reasoning"      # 推理分析
    CODING = "coding"            # 编程开发
    WRITING = "writing"          # 文本写作
    TRANSLATION = "translation"  # 翻译
    MATH = "math"                # 数学计算
    PLANNING = "planning"        # 规划拆分
    TOOL_CALL = "tool_call"      # 工具调用
    CHAT = "chat"                # 简单对话
    SUMMARY = "summary"          # 摘要汇总

@dataclass


SubTask

类 SubTask 在 core/task_dispatcher.py: 子任务 | 方法:

class SubTask:
    """子任务"""
    id: str                          # 任务ID
    description: str                 # 任务描述
    task_type: TaskType              # 任务类型
    status: TaskStatus = TaskStatus.PENDING
    assigned_model: str = ""         # 分配的模型ID
    assigned_provider: str = ""      # 提供商
    result: str = ""                 # 执行结果
    tool_calls: List[Dict] = field(default_factory=list)
    latency_ms: float = 0
    error: str = ""

@dataclass


TaskPlan

类 TaskPlan 在 core/task_dispatcher.py: 任务计划 | 方法:

class TaskPlan:
    """任务计划"""
    task_id: str                     # 总任务ID
    original_request: str            # 原始请求
    subtasks: List[SubTask] = field(default_factory=list)
    final_result: str = ""           # 汇总结果
    total_latency_ms: float = 0
    created_at: float = field(default_factory=time.time)

# 任务类型到模型能力的映射
TASK_TO_CAPABILITY = {
    TaskType.REASONING: "reasoning",
    TaskType.CODING: "coding",
    TaskType.WRITING: "writing",
    TaskType.TRANSLATION: "translation",
    TaskType.MATH: "math",
    TaskType.PLANNING: "reasoning",
    TaskType.TOOL_CALL: "tool_use",
    TaskType.CHAT: "chat",
    TaskType.SUMMARY: "reasoning",
}

# 任务类型优先提供商（国内硅基流动优先，智谱次之，NIM兜底）
TASK_PREFERRED_PROVIDER = {
    TaskType.REASONING: ["siliconflow", "zhipu", "nvidia_nim"],
    TaskType.CODING: ["siliconflow", "nvidia_nim", "zhipu"],
    TaskType.WRITING: ["siliconflow", "zhipu", "nvidia_nim"],
    TaskType.TRANSLATION: ["siliconflow", "zhipu", "nvidia_nim"],
    TaskType.MATH: ["siliconflow", "zhipu", "nvidia_nim"],
    TaskType.PLANNING: ["siliconflow", "zhipu", "nvidia_nim"],
    TaskType.TOOL_CALL: ["zhipu"],      # 只有智谱FC验证过
    TaskType.CHAT: ["siliconflow", "zhipu", "nvidia_nim"],
    TaskType.SUMMARY: ["siliconflow", "zhipu", "nvidia_nim"],
}


TaskDispatcher

类 TaskDispatcher 在 core/task_dispatcher.py: 任务调度器 | 方法: __init__, _init_adapters, select_model, execute_subtask, execute_plan, test

class TaskDispatcher:
    """任务调度器"""

    def __init__(self, registry: ModelRegistry = None):
        self.registry = registry or model_registry
        self.adapters: Dict[str, ModelAdapter] = {}
        self._init_adapters()

    def _init_adapters(self):
        """初始化已配置的适配器"""
        # 智谱
        zhipu_key = os.environ.get("GLM_API_KEY", "")
        if zhipu_key:
            self.adapters["zhipu"] = ZhipuAdapter(zhipu_key)

        # NIM
        nim_key = os.environ.get("NVIDIA_KEY", "")
        if nim_key:
            self.adapters["nvidia_nim"] = NvidiaNimAdapter(nim_key)

        # 硅基流动
        sf_key = os.environ.get("SILICONFLOW_KEY", "")
        if sf_key:
            self.adapters["siliconflow"] = SiliconFlowAdapter(sf_key)

    def select_model(self, task_type: TaskType, max_latency: float = 5000) -> Optional[tuple]:
        """为任务选择最优模型，返回 (provider, model_id)"""
        providers = TASK_PREFERRED_PROVIDER.get(task_type, ["zhipu", "nvidia_nim"])
        capability = TASK_TO_CAPABILITY.get(task_type, "chat")

        for provider in providers:
            if provider not in self.adapters:
                continue
            # 在注册表中找该提供商最合适的模型
            candidates = self.registry.list_models(
                provider=ModelProvider(provider),
                only_free=True,
                min_reliability=0.5
            )
            for model in candidates:
                if capability in model.capabilities and model.latency_avg <= max_latency:
                    return (provider, model.model_id)

        # 降级：随便选一个可用的
        for provider in providers:
            if provider in self.adapters:
                models = self.registry.list_models(provider=ModelProvider(provider), only_free=True)
                if models:
                    return (provider, models[0].model_id)

        return None

    async def execute_subtask(self, subtask: SubTask, context: str = "") -> SubTask:
        """执行单个子任务"""


test

方法 TaskDispatcher.test():
        os.environ["GLM_API_KEY"] = "a357dd87003f45fa8070381675d64c4e.JLzEDqn5vXYkYlpF"
        os.

def test(self):
        os.environ["GLM_API_KEY"] = "a357dd87003f45fa8070381675d64c4e.JLzEDqn5vXYkYlpF"
        os.environ["NVIDIA_KEY"] = "nvapi-[REDACTED]_eBR6V0gmvpLUIxGBkMPXqn6OI8x"

        print("=== 任务调度器测试 ===\n")

        dispatcher = TaskDispatcher()

        # 测试模型选择
        for tt in [TaskType.CODING, TaskType.CHAT, TaskType.TOOL_CALL]:
            sel = dispatcher.select_model(tt)
            print(f"{tt.value}: {sel}")

        # 测试子任务执行
        subtask = SubTask(
            id="t1",
            description="用中文说一句话鼓励程序员",
            task_type=TaskType.CHAT
        )
        result = await dispatcher.execute_subtask(subtask)
        print(f"\n子任务结果: {result.result[:100]}")
        print(f"模型: {result.assigned_provider}/{result.assigned_model}")
        print(f"延迟: {result.latency_ms}ms")

        print("\n✅ 调度器测试完成")

    asyncio.run(test())


文件 core/modal_glm.py: 虫群云端推理后端 — Modal GLM-5.1
- 调用Modal平台托管的GLM-5.1-FP8推理端点
- OpenAI兼容API格式
- 支持流式和非流式推理
- 带思维链(reasoning)输出 | 定义: class ModalGLMBackend, def __init__, def chat, def simple_ask, def get_status, def health_check, def get_glm_backend

#!/usr/bin/env python3
"""
虫群云端推理后端 — Modal GLM-5.1
- 调用Modal平台托管的GLM-5.1-FP8推理端点
- OpenAI兼容API格式
- 支持流式和非流式推理
- 带思维链(reasoning)输出
"""

import os
import time
import json
import httpx
from typing import Dict, Optional

class ModalGLMBackend:
    """
    云端推理后端 — 支持智谱GLM和Modal GLM

    优先使用智谱GLM（国内直连）：
      https://open.bigmodel.cn/api/paas/v4/chat/completions
    降级使用Modal GLM-5.1（需代理）：
      https://api.us-west-2.modal.direct/v1/chat/completions
    """

    # Modal GLM-5.1端点配置
    DEF


ModalGLMBackend

类 ModalGLMBackend 在 core/modal_glm.py: 云端推理后端 — 支持智谱GLM和Modal GLM

    优先使用智谱GLM（国内直连）：
      https://open.bigmodel.cn/api/paas/v4/chat/completions
    降级使用Modal GLM-5.1（需代理）：
      https://api.us-west-2.modal.direct/v1/chat/completion | 方法: __init__, chat, simple_ask, get_status, health_check

class ModalGLMBackend:
    """
    云端推理后端 — 支持智谱GLM和Modal GLM

    优先使用智谱GLM（国内直连）：
      https://open.bigmodel.cn/api/paas/v4/chat/completions
    降级使用Modal GLM-5.1（需代理）：
      https://api.us-west-2.modal.direct/v1/chat/completions
    """

    # Modal GLM-5.1端点配置
    DEFAULT_BASE_URL = "https://api.us-west-2.modal.direct/v1"
    DEFAULT_MODEL = "zai-org/GLM-5.1-FP8"
    DEFAULT_API_KEY = "modalresearch_m7wFgRkq4LQ1vxVd2FZ0r3o2Ixz66SISJoAvwuUTkCc"

    def __init__(
        self,
        base_url: str = None,
        api_key: str = None,
        model: str = None,
        timeout: float = 30.0,
    ):
        # 优先从config.yaml加载智谱GLM配置
        from core.config import get_api_key, get_config
        cfg = get_config()
        cloud_cfg = cfg.get("models", {}).get("cloud", {})

        glm_key = get_api_key("glm")
        glm_url = cfg.get("api_keys", {}).get("glm_base_url", "")
        glm_model = cloud_cfg.get("primary", "glm-4-flash")

        if glm_key and glm_url:
            # 使用智谱GLM（国内直连）
            self.base_url = glm_url
            self.api_key = glm_key
            self.model = glm_model
            self._backend_name = "zhipu-glm"
        else:
            # 降级到Modal GLM
            self.base_url = base_url or os.environ.get(
                "MODAL_GLM_BASE_URL", self.DEFAULT_BASE_URL
            )
            self.api_key = api_key or os.environ.get(
                "MODAL_GLM_API_KEY", self.DEFAULT_API_KEY
            )
            self.model = model or os.environ.get(
                "MODAL_GLM_MODEL", self.DEFAULT_MODEL
            )
            self._backend_name = "modal-glm-5.1"

        self.timeout = timeout

        # 统计
        self._total_calls = 0
        self._total_errors = 0
        self._total_latency_ms = 0

    def chat(
        self,
        messages: list,
        max_tokens: int = 2048,
        temperature: float = 0.7,
        top_p: float = 0.9,
    ) -> Dict:
        """
        聊天推理接口


文件 core/model_registry.py: 虫群模型注册表 — 统一管理所有AI模型API
支持动态添加、负载均衡、故障转移、成本优化 | 定义: class ModelProvider, class ModelType, class
class, def to_dict, class ModelRegistry, def __init__, def load_builtin_models, def add_model, def remove_model, def get_model

#!/usr/bin/env python3
"""
虫群模型注册表 — 统一管理所有AI模型API
支持动态添加、负载均衡、故障转移、成本优化
"""

import json
import time
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, asdict
from enum import Enum

class ModelProvider(Enum):
    """模型提供商"""
    ZHIPU = "zhipu"           # 智谱AI
    SILICONFLOW = "siliconflow"  # 硅基流动
    NVIDIA_NIM = "nvidia_nim"    # NVIDIA NIM
    IFLYTEK = "iflytek"        # 星火讯飞
    MODAL = "modal"            # Modal云平台
    ANTHROPIC = "anthropic"    # Anthropi


ModelProvider

类 ModelProvider 在 core/model_registry.py: 模型提供商 | 方法:

class ModelProvider:
    """模型提供商"""
    ZHIPU = "zhipu"           # 智谱AI
    SILICONFLOW = "siliconflow"  # 硅基流动
    NVIDIA_NIM = "nvidia_nim"    # NVIDIA NIM
    IFLYTEK = "iflytek"        # 星火讯飞
    MODAL = "modal"            # Modal云平台
    ANTHROPIC = "anthropic"    # Anthropic
    OPENAI = "openai"         # OpenAI
    CUSTOM = "custom"          # 自定义


ModelType

类 ModelType 在 core/model_registry.py: 模型类型 | 方法:

class ModelType:
    """模型类型"""
    CHAT = "chat"              # 对话模型
    REASONING = "reasoning"    # 推理模型
    CODING = "coding"          # 编程模型
    VISION = "vision"          # 视觉模型
    AUDIO = "audio"            # 音频模型
    EMBEDDING = "embedding"    # 嵌入模型
    TOOL_USE = "tool_use"      # 工具调用模型
    OCR = "ocr"                # OCR识别模型
    IMAGE_GEN = "image_gen"    # 图像生成模型
    TRANSLATION = "translation" # 翻译模型
    RERANKER = "reranker"      # 重排序模型

@dataclass