| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- """
- Memory 数据模型
- Experience: 经验规则(条件 + 规则 + 证据)
- Skill: 技能(从经验归纳的高层知识)
- """
- from dataclasses import dataclass, field
- from datetime import datetime
- from typing import Dict, Any, List, Optional, Literal
- import uuid
- @dataclass
- class Experience:
- """
- 经验规则
- 从执行过程或人工反馈中提取的规则,格式:
- - condition: 什么情况下适用
- - rule: 应该怎么做
- - evidence: 证据(step_ids)
- """
- exp_id: str
- scope: str # "agent:{type}" 或 "user:{uid}"
- # 核心三元组
- condition: str
- rule: str
- evidence: List[str] = field(default_factory=list) # step_ids
- # 元数据
- source: Literal["execution", "feedback", "manual"] = "feedback"
- confidence: float = 0.5
- usage_count: int = 0
- success_rate: float = 0.0
- # 时间
- created_at: datetime = field(default_factory=datetime.now)
- updated_at: datetime = field(default_factory=datetime.now)
- @classmethod
- def create(
- cls,
- scope: str,
- condition: str,
- rule: str,
- evidence: List[str] = None,
- source: Literal["execution", "feedback", "manual"] = "feedback",
- confidence: float = 0.5,
- ) -> "Experience":
- """创建新的 Experience"""
- now = datetime.now()
- return cls(
- exp_id=str(uuid.uuid4()),
- scope=scope,
- condition=condition,
- rule=rule,
- evidence=evidence or [],
- source=source,
- confidence=confidence,
- created_at=now,
- updated_at=now,
- )
- def to_dict(self) -> Dict[str, Any]:
- """转换为字典"""
- return {
- "exp_id": self.exp_id,
- "scope": self.scope,
- "condition": self.condition,
- "rule": self.rule,
- "evidence": self.evidence,
- "source": self.source,
- "confidence": self.confidence,
- "usage_count": self.usage_count,
- "success_rate": self.success_rate,
- "created_at": self.created_at.isoformat() if self.created_at else None,
- "updated_at": self.updated_at.isoformat() if self.updated_at else None,
- }
- def to_prompt_text(self) -> str:
- """转换为可注入 Prompt 的文本"""
- return f"当 {self.condition} 时,{self.rule}"
- @dataclass
- class Skill:
- """
- 技能 - 从经验归纳的高层知识
- 技能可以形成层次结构(通过 parent_id)
- """
- skill_id: str
- scope: str # "agent:{type}" 或 "user:{uid}"
- name: str
- description: str
- category: str # 分类,如 "search", "reasoning", "writing"
- # 层次结构
- parent_id: Optional[str] = None
- # 内容
- content: Optional[str] = None # 完整的 skill 内容(Markdown)
- guidelines: List[str] = field(default_factory=list)
- derived_from: List[str] = field(default_factory=list) # experience_ids
- # 版本
- version: int = 1
- # 时间
- created_at: datetime = field(default_factory=datetime.now)
- updated_at: datetime = field(default_factory=datetime.now)
- @classmethod
- def create(
- cls,
- scope: str,
- name: str,
- description: str,
- category: str = "general",
- content: Optional[str] = None,
- guidelines: List[str] = None,
- derived_from: List[str] = None,
- parent_id: Optional[str] = None,
- ) -> "Skill":
- """创建新的 Skill"""
- now = datetime.now()
- return cls(
- skill_id=str(uuid.uuid4()),
- scope=scope,
- name=name,
- description=description,
- category=category,
- parent_id=parent_id,
- content=content,
- guidelines=guidelines or [],
- derived_from=derived_from or [],
- created_at=now,
- updated_at=now,
- )
- def to_dict(self) -> Dict[str, Any]:
- """转换为字典"""
- return {
- "skill_id": self.skill_id,
- "scope": self.scope,
- "name": self.name,
- "description": self.description,
- "category": self.category,
- "parent_id": self.parent_id,
- "content": self.content,
- "guidelines": self.guidelines,
- "derived_from": self.derived_from,
- "version": self.version,
- "created_at": self.created_at.isoformat() if self.created_at else None,
- "updated_at": self.updated_at.isoformat() if self.updated_at else None,
- }
- def to_prompt_text(self) -> str:
- """
- 转换为可注入 Prompt 的文本
- 优先使用完整的 content(如果有),否则使用 description + guidelines
- """
- # 如果有完整的 content,直接使用
- if self.content:
- return self.content.strip()
- # 否则使用旧的格式(向后兼容)
- lines = [f"### {self.name}", self.description]
- if self.guidelines:
- lines.append("指导原则:")
- for g in self.guidelines:
- lines.append(f"- {g}")
- return "\n".join(lines)
|