mss-agent 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
core/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ from .agent import MSSAgent, AgentResult
2
+ from .heat_tax import HeatTaxBudget, HeatTaxLevel, HeatTaxAbort
3
+ from .delta import DeltaProtocol
4
+ from .memory import DeltaMemory
5
+
6
+ __all__ = ["MSSAgent", "AgentResult", "HeatTaxBudget", "HeatTaxLevel", "HeatTaxAbort", "DeltaProtocol", "DeltaMemory"]
core/agent.py ADDED
@@ -0,0 +1,198 @@
1
+ """
2
+ MSS-Agent 核心基类 — 三层防御的自主 Agent.
3
+
4
+ 每个 MSSAgent 实例携带:
5
+ L0 热税预算 (A3) — 拒绝无意义任务
6
+ L1 Δ检测协议 (A6) — 检测闭合, 触发蜕壳
7
+ L2 记忆系统 — 不记住一切, 遗忘旧模式
8
+
9
+ Usage:
10
+ agent = MSSAgent(name="Writer", llm=my_llm_fn)
11
+ result = agent.run("写一篇关于 AI 安全的文章")
12
+ if result.aborted:
13
+ print(f"Agent 拒绝: {result.reason}")
14
+ agent.health_report()
15
+ """
16
+ from dataclasses import dataclass, field
17
+ from typing import Optional, Callable, Any
18
+ import hashlib
19
+ import time
20
+
21
+ from .heat_tax import HeatTaxBudget, HeatTaxLevel, HeatTaxAbort
22
+ from .delta import DeltaProtocol
23
+ from .memory import DeltaMemory
24
+
25
+
26
+ @dataclass
27
+ class AgentResult:
28
+ """Agent 执行结果."""
29
+ success: bool
30
+ output: Any = None
31
+ aborted: bool = False
32
+ reason: str = ""
33
+ heat_tax: dict = field(default_factory=dict)
34
+ delta: float = 0.0
35
+ elapsed_ms: float = 0.0
36
+
37
+
38
+ class MSSAgent:
39
+ """
40
+ MSS-Agent 基类.
41
+
42
+ 所有 Agent (Writer/Reviewer/Analyst) 继承此类.
43
+ 核心循环: think → heat_tax_check → act → delta_tick → remember
44
+
45
+ Args:
46
+ name: Agent 名称
47
+ llm: LLM 调用函数 (prompt) -> str
48
+ heat_tax_threshold: 热税预算上限 (default 0.5)
49
+ delta_min: Δ 最低阈值 (default 0.3)
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ name: str,
55
+ llm: Optional[Callable[[str], str]] = None,
56
+ heat_tax_threshold: float = 2.0,
57
+ delta_min: float = 0.3,
58
+ ):
59
+ self.name = name
60
+ self.llm = llm or (lambda p: f"[{name}] LLM not configured. Prompt: {p[:80]}...")
61
+ self.tax = HeatTaxBudget(threshold=heat_tax_threshold)
62
+ self.delta = DeltaProtocol(min_delta=delta_min)
63
+ self.memory = DeltaMemory()
64
+ self.run_count = 0
65
+ self.abort_count = 0
66
+
67
+ def _task_hash(self, prompt: str) -> str:
68
+ return hashlib.md5(prompt.encode()).hexdigest()[:12]
69
+
70
+ def _estimate_meaning_heat(self, prompt: str) -> tuple[float, str]:
71
+ """
72
+ 评估任务的意义热税. 基于 LLM 自省.
73
+
74
+ 高意义热税 = 任务可能在浪费生命.
75
+ 启发式:
76
+ - 空 prompt / 纯废话 → high heat
77
+ - 含 '为什么' / '怎么' / '分析' → low heat (有意义)
78
+ - <=20 chars → suspicious
79
+
80
+ Returns (heat_value, reason). heat_value: 0.0=very meaningful, 1.0=meaningless.
81
+ Note: L2 weight is 1000x, so even 0.001 matters. Calibrate carefully.
82
+ """
83
+ prompt_lower = prompt.lower().strip()
84
+
85
+ # Heuristic: meaningful keywords reduce heat tax
86
+ meaning_signals = ["为什么", "怎么", "分析", "评估", "设计", "实现",
87
+ "why", "how", "analyze", "design", "implement",
88
+ "review", "refactor", "test", "debug"]
89
+ meaning_score = sum(1 for s in meaning_signals if s in prompt_lower)
90
+
91
+ # Wasted-life signals increase heat tax
92
+ waste_signals = ["帮我写", "改写一下", "翻译成", "总结一下", "简短点"]
93
+ waste_score = sum(1 for s in waste_signals if s in prompt_lower)
94
+
95
+ if len(prompt) < 5:
96
+ return 0.08, "Prompt <5 chars: likely trivial"
97
+
98
+ if waste_score > meaning_score and waste_score >= 2:
99
+ return 0.05, "Task smells like busywork (high waste signals)"
100
+
101
+ if meaning_score >= 2:
102
+ return 0.002, "Task has clear meaningful intent"
103
+
104
+ if meaning_score >= 1:
105
+ return 0.005, "Task has some meaningful intent"
106
+
107
+ return 0.01, "Task assessed as neutral"
108
+
109
+ def run(self, prompt: str) -> AgentResult:
110
+ """
111
+ 运行 Agent 的核心循环.
112
+
113
+ 1. 评估意义热税 → 如果过高 → 拒绝
114
+ 2. 执行 LLM 调用
115
+ 3. 记录热税
116
+ 4. Δ tick + memory store
117
+ """
118
+ t0 = time.time()
119
+ self.run_count += 1
120
+ task_hash = self._task_hash(prompt)
121
+
122
+ # L2: 意义热税评估
123
+ meaning_heat, meaning_reason = self._estimate_meaning_heat(prompt)
124
+ self.tax.charge(HeatTaxLevel.L2_MEANING, meaning_heat, meaning_reason)
125
+
126
+ if self.tax.l2_dominant() and meaning_heat > 0.05:
127
+ self.abort_count += 1
128
+ return AgentResult(
129
+ success=False, aborted=True,
130
+ reason=f"Task has LOW meaning: {meaning_reason}",
131
+ heat_tax=self.tax.snapshot(),
132
+ elapsed_ms=(time.time() - t0) * 1000,
133
+ )
134
+
135
+ # L1: Check total budget
136
+ if self.tax.exceeded():
137
+ self.abort_count += 1
138
+ return AgentResult(
139
+ success=False, aborted=True,
140
+ reason=f"Heat tax budget exceeded: {self.tax.total():.3f}",
141
+ heat_tax=self.tax.snapshot(),
142
+ elapsed_ms=(time.time() - t0) * 1000,
143
+ )
144
+
145
+ # Execute
146
+ try:
147
+ output = self.llm(prompt)
148
+ except Exception as e:
149
+ self.tax.charge(HeatTaxLevel.L1_LOGICAL, 0.05, f"LLM error: {str(e)[:60]}")
150
+ return AgentResult(
151
+ success=False, aborted=True, reason=str(e),
152
+ heat_tax=self.tax.snapshot(),
153
+ elapsed_ms=(time.time() - t0) * 1000,
154
+ )
155
+
156
+ # L1: Charge logical heat (token count proxy)
157
+ token_estimate = len(output) / 4 # ~4 chars per token
158
+ self.tax.charge(HeatTaxLevel.L1_LOGICAL, token_estimate * 0.0001, f"{int(token_estimate)} tokens")
159
+
160
+ # L0: Physical heat (always tiny)
161
+ elapsed = (time.time() - t0) * 1000
162
+ self.tax.charge(HeatTaxLevel.L0_PHYSICAL, elapsed * 0.00001, f"{elapsed:.0f}ms")
163
+
164
+ # Δ tick: novelty + diversity → delta
165
+ novelty = self.memory.novelty_score(prompt)
166
+ diversity = self.memory.diversity_score()
167
+ current_delta = self.delta.tick(task_hash, novelty, diversity)
168
+
169
+ # Store in memory
170
+ self.memory.store(prompt, current_delta)
171
+
172
+ return AgentResult(
173
+ success=True,
174
+ output=output,
175
+ aborted=False,
176
+ heat_tax=self.tax.snapshot(),
177
+ delta=current_delta,
178
+ elapsed_ms=elapsed,
179
+ )
180
+
181
+ def health_report(self) -> dict:
182
+ """输出 Agent 健康报告."""
183
+ return {
184
+ "agent": self.name,
185
+ "runs": self.run_count,
186
+ "aborts": self.abort_count,
187
+ "abort_rate": round(self.abort_count / max(self.run_count, 1), 3),
188
+ "heat_tax": self.tax.snapshot(),
189
+ "delta": self.delta.snapshot(),
190
+ "memory": self.memory.stats(),
191
+ }
192
+
193
+ def reset(self):
194
+ """重置 Agent (保留 memory)."""
195
+ self.tax = HeatTaxBudget(threshold=self.tax.threshold)
196
+ self.delta = DeltaProtocol(min_delta=self.delta.min_delta)
197
+ self.run_count = 0
198
+ self.abort_count = 0
core/delta.py ADDED
@@ -0,0 +1,78 @@
1
+ """
2
+ Δ 维持条件 — MSS-Agent 的第二道防线.
3
+
4
+ Δ 不是优化目标, 是存活条件 (心率>0, 不是最大化心率).
5
+ Δ<0 → Agent 闭合于旧模式 → 触发蜕壳.
6
+ """
7
+ import time
8
+ from dataclasses import dataclass, field
9
+ from typing import Optional
10
+
11
+
12
+ @dataclass
13
+ class DeltaProtocol:
14
+ """
15
+ Δ 检测协议 (H528). 嵌入每个 Agent 实例.
16
+
17
+ min_delta: Δ 最低阈值 (0.3). 低于此→告警
18
+ molt_cycles: 连续下降 N 个周期→触发蜕壳
19
+ """
20
+ min_delta: float = 0.3
21
+ molt_cycles: int = 2
22
+ history: list = field(default_factory=list) # [{ts, delta, task_hash}]
23
+ molting_alert: bool = False
24
+
25
+ def tick(self, task_hash: str, novelty_score: float, diversity_score: float):
26
+ """
27
+ 每个任务周期调用一次.
28
+
29
+ task_hash: 当前任务的 hash (用于检测重复)
30
+ novelty_score: 0=完全重复, 1=全新
31
+ diversity_score: 0=单一模式, 1=多模式
32
+
33
+ Δ = novelty * 0.6 + diversity * 0.4
34
+ """
35
+ delta = novelty_score * 0.6 + diversity_score * 0.4
36
+ delta = round(delta, 4)
37
+
38
+ entry = {
39
+ "ts": time.time(),
40
+ "delta": delta,
41
+ "task_hash": task_hash[:8],
42
+ "novelty": novelty_score,
43
+ "diversity": diversity_score,
44
+ }
45
+ self.history.append(entry)
46
+
47
+ # Keep last 30 entries
48
+ self.history = self.history[-30:]
49
+
50
+ # Check: 2 consecutive drops below min_delta
51
+ self.molting_alert = False
52
+ if len(self.history) >= 3:
53
+ d2 = self.history[-3]["delta"]
54
+ d1 = self.history[-2]["delta"]
55
+ d0 = self.history[-1]["delta"]
56
+ if d0 < d1 < d2 and d0 < self.min_delta:
57
+ self.molting_alert = True
58
+
59
+ return delta
60
+
61
+ def health(self) -> str:
62
+ if not self.history:
63
+ return "UNKNOWN"
64
+ current = self.history[-1]["delta"]
65
+ if self.molting_alert:
66
+ return "MOLTING"
67
+ if current < self.min_delta:
68
+ return "WARNING"
69
+ return "HEALTHY"
70
+
71
+ def snapshot(self) -> dict:
72
+ return {
73
+ "health": self.health(),
74
+ "current_delta": self.history[-1]["delta"] if self.history else None,
75
+ "molting_alert": self.molting_alert,
76
+ "history_len": len(self.history),
77
+ "avg_delta": round(sum(h["delta"] for h in self.history) / len(self.history), 4) if self.history else 0,
78
+ }
core/heat_tax.py ADDED
@@ -0,0 +1,93 @@
1
+ """
2
+ A3 热税预算 — MSS-Agent 的第一道防线.
3
+
4
+ 三层热税:
5
+ L0 物理热税 (token cost, latency) — 权重 0.001
6
+ L1 逻辑热税 (redundancy, loops) — 权重 1.0
7
+ L2 意义热税 (meaningless work) — 权重 1000.0
8
+
9
+ 如果 L2 意义热税超过 budget → 拒绝执行.
10
+ """
11
+ from enum import Enum
12
+ from dataclasses import dataclass, field
13
+ from typing import Optional, Callable
14
+
15
+
16
+ class HeatTaxLevel(Enum):
17
+ """热税层级. 修复顺序: L2→L1→L0. 反了=白费."""
18
+ L0_PHYSICAL = 0 # GPU/时间/token
19
+ L1_LOGICAL = 1 # 冗余/重复/缓存污染
20
+ L2_MEANING = 2 # 虚假数据/概念偷换/无意义任务
21
+
22
+
23
+ @dataclass
24
+ class HeatTaxBudget:
25
+ """
26
+ 热税预算. 每个 Agent 实例有一个.
27
+
28
+ threshold: 总热税上限 (0-1, 超过则拒绝)
29
+ weights: 各层权重
30
+
31
+ Usage:
32
+ budget = HeatTaxBudget()
33
+ budget.charge(HeatTaxLevel.L2_MEANING, 0.01, "生成无意义报告")
34
+ if budget.exceeded():
35
+ raise HeatTaxAbort("此任务无意义")
36
+ """
37
+ threshold: float = 2.0
38
+ weights: dict = field(default_factory=lambda: {
39
+ HeatTaxLevel.L0_PHYSICAL: 0.001,
40
+ HeatTaxLevel.L1_LOGICAL: 1.0,
41
+ HeatTaxLevel.L2_MEANING: 1000.0,
42
+ })
43
+ spent: dict = field(default_factory=dict)
44
+ log: list = field(default_factory=list)
45
+
46
+ def __post_init__(self):
47
+ for level in HeatTaxLevel:
48
+ self.spent.setdefault(level, 0.0)
49
+
50
+ def charge(self, level: HeatTaxLevel, amount: float, reason: str = "") -> float:
51
+ """
52
+ 征收热税. 返回加权后的税值.
53
+ 如果单次 L2 热税 > threshold*0.3 → 立即标记.
54
+ """
55
+ weighted = amount * self.weights[level]
56
+ self.spent[level] += weighted
57
+ self.log.append({
58
+ "level": level.name,
59
+ "amount": amount,
60
+ "weighted": weighted,
61
+ "reason": reason[:120],
62
+ "total": self.total(),
63
+ })
64
+ return weighted
65
+
66
+ def total(self) -> float:
67
+ """当前累计热税 (归一化到 0-1)."""
68
+ return min(sum(self.spent.values()) / 100.0, 1.0)
69
+
70
+ def exceeded(self) -> bool:
71
+ """热税超过阈值? 超过 → 应该停止."""
72
+ return self.total() > self.threshold
73
+
74
+ def l2_dominant(self) -> bool:
75
+ """L2 意义热税占比 > 50%? → 任务的方向错了."""
76
+ pt = sum(self.spent.values()) or 1.0
77
+ return self.spent[HeatTaxLevel.L2_MEANING] / pt > 0.5
78
+
79
+ def snapshot(self) -> dict:
80
+ return {
81
+ "total": round(self.total(), 4),
82
+ "L0_physical": round(self.spent[HeatTaxLevel.L0_PHYSICAL], 2),
83
+ "L1_logical": round(self.spent[HeatTaxLevel.L1_LOGICAL], 2),
84
+ "L2_meaning": round(self.spent[HeatTaxLevel.L2_MEANING], 2),
85
+ "l2_dominant": self.l2_dominant(),
86
+ "exceeded": self.exceeded(),
87
+ "log_count": len(self.log),
88
+ }
89
+
90
+
91
+ class HeatTaxAbort(Exception):
92
+ """抛出此异常 = Agent 判定任务无意义, 拒绝执行."""
93
+ pass
core/memory.py ADDED
@@ -0,0 +1,100 @@
1
+ """
2
+ Δ 增强记忆 — MSS-Agent 的记忆不是缓存, 是有自检的.
3
+
4
+ 普通 Agent: task→memory→retrieve→repeat
5
+ MSS-Agent: task→memory→delta_check→Δ↓→forget_old→learn_new
6
+ """
7
+ from dataclasses import dataclass, field
8
+ from typing import Any, Optional
9
+ import hashlib
10
+ import time
11
+
12
+
13
+ @dataclass
14
+ class DeltaMemory:
15
+ """
16
+ Δ 增强记忆. 三个原则:
17
+ 1. 不要记住一切 (闭合)
18
+ 2. 遗忘模式=学习 (蜕壳)
19
+ 3. 新鲜度>完整度
20
+
21
+ max_items: 最大记忆条数 (超过则遗忘重复次数最多的)
22
+ """
23
+ max_items: int = 100
24
+ items: list = field(default_factory=list) # [{hash, content, delta, repeats, ts}]
25
+
26
+ def _hash(self, content: str) -> str:
27
+ return hashlib.md5(content.encode()).hexdigest()[:12]
28
+
29
+ def store(self, content: str, delta: float):
30
+ """存入记忆. 如果已存在→增加重复计数. 重复>3次→标记为闭合."""
31
+ h = self._hash(content)
32
+
33
+ for item in self.items:
34
+ if item["hash"] == h:
35
+ item["repeats"] += 1
36
+ item["ts"] = time.time()
37
+ item["delta"] = delta
38
+ if item["repeats"] > 3:
39
+ item["closed"] = True # 闭合 = 应该遗忘的
40
+ return
41
+
42
+ self.items.append({
43
+ "hash": h,
44
+ "content": content[:500],
45
+ "delta": delta,
46
+ "repeats": 1,
47
+ "closed": False,
48
+ "ts": time.time(),
49
+ })
50
+
51
+ # Evict: remove closed items first, then oldest
52
+ if len(self.items) > self.max_items:
53
+ closed = [i for i in self.items if i["closed"]]
54
+ for c in closed[:max(1, len(closed) // 2)]:
55
+ self.items.remove(c)
56
+ while len(self.items) > self.max_items:
57
+ self.items.sort(key=lambda x: x["ts"])
58
+ self.items.pop(0)
59
+
60
+ def retrieve(self, query: str, top_k: int = 5) -> list:
61
+ """检索相关记忆. 排除已闭合的."""
62
+ active = [i for i in self.items if not i["closed"]]
63
+ # Simple keyword overlap scoring
64
+ query_words = set(query.lower().split())
65
+ scored = []
66
+ for item in active:
67
+ content_words = set(item["content"].lower().split())
68
+ overlap = len(query_words & content_words)
69
+ freshness = 1.0 - (time.time() - item["ts"]) / 86400 # 1 day decay
70
+ score = overlap * 0.7 + freshness * 0.3
71
+ if overlap > 0:
72
+ scored.append((score, item))
73
+ scored.sort(key=lambda x: x[0], reverse=True)
74
+ return [s[1] for s in scored[:top_k]]
75
+
76
+ def novelty_score(self, content: str) -> float:
77
+ """计算当前内容的 newness. 0=完全重复, 1=全新."""
78
+ h = self._hash(content)
79
+ for item in self.items:
80
+ if item["hash"] == h:
81
+ return max(0.0, 1.0 - item["repeats"] * 0.25)
82
+ return 1.0
83
+
84
+ def diversity_score(self) -> float:
85
+ """计算记忆的多样性. 0=单一模式, 1=高度多样."""
86
+ if len(self.items) < 3:
87
+ return 1.0
88
+ hashes = set(i["hash"] for i in self.items)
89
+ return min(len(hashes) / len(self.items), 1.0)
90
+
91
+ def stats(self) -> dict:
92
+ active = [i for i in self.items if not i["closed"]]
93
+ closed = [i for i in self.items if i["closed"]]
94
+ return {
95
+ "total": len(self.items),
96
+ "active": len(active),
97
+ "closed": len(closed),
98
+ "diversity": round(self.diversity_score(), 3),
99
+ "avg_repeats": round(sum(i["repeats"] for i in self.items) / max(len(self.items), 1), 1),
100
+ }
examples/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .writer import WriterAgent
2
+
3
+ __all__ = ["WriterAgent"]
examples/writer.py ADDED
@@ -0,0 +1,46 @@
1
+ """
2
+ Example: Writer Agent — 内置热税预算的写作助手.
3
+
4
+ 拒绝无意义写作任务 (empty prompt, pure paraphrasing, etc.)
5
+ """
6
+ from mss_agent.core.agent import MSSAgent
7
+ from mss_agent.core.heat_tax import HeatTaxLevel, HeatTaxAbort
8
+
9
+
10
+ class WriterAgent(MSSAgent):
11
+ """
12
+ Writer Agent 示例.
13
+
14
+ Usage:
15
+ def my_llm(prompt): return ollama.chat("qwen", prompt)
16
+ writer = WriterAgent(llm=my_llm)
17
+ result = writer.run("写一篇关于开源精神的文章")
18
+ if not result.aborted:
19
+ print(result.output)
20
+ writer.health_report()
21
+ """
22
+
23
+ def __init__(self, llm=None):
24
+ super().__init__(name="Writer", llm=llm, heat_tax_threshold=1.5)
25
+ self.style_guide = "简洁、准确、有人味"
26
+
27
+ def _estimate_meaning_heat(self, prompt: str) -> tuple[float, str]:
28
+ """Writer-specific meaning assessment."""
29
+ prompt_lower = prompt.lower().strip()
30
+
31
+ # Empty / trivial
32
+ if len(prompt) < 10:
33
+ return 0.09, "Prompt too short: likely a throwaway task"
34
+
35
+ # Pure paraphrasing
36
+ paraphrase_signals = ["改写", "重新说", "换个写法", "rewrite", "rephrase"]
37
+ if any(s in prompt_lower for s in paraphrase_signals):
38
+ if "因为" not in prompt_lower and "because" not in prompt_lower:
39
+ return 0.06, "Pure paraphrasing without stated reason"
40
+
41
+ # Meaningful writing
42
+ creation_signals = ["写", "创作", "生成", "write", "create", "draft", "compose"]
43
+ if any(s in prompt_lower for s in creation_signals) and len(prompt) > 30:
44
+ return 0.003, "Creative writing task"
45
+
46
+ return 0.01, "Neutral writing task"
@@ -0,0 +1,106 @@
1
+ Metadata-Version: 2.1
2
+ Name: mss-agent
3
+ Version: 0.1.0
4
+ Summary: MSS-Agent: 世界上第一个内置'意义场自检'的开源 Agent 框架
5
+ Home-page: https://github.com/mysama1/MSS-AI-Project
6
+ Author: MSS-AI Project
7
+ License: MIT
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest; extra == "dev"
17
+ Requires-Dist: black; extra == "dev"
18
+ Provides-Extra: llm
19
+ Requires-Dist: openai>=1.0; extra == "llm"
20
+
21
+ # MSS-Agent
22
+
23
+ **世界上第一个内置"意义场自检"的开源 Agent 框架。**
24
+
25
+ ```
26
+ pip install mss-agent # coming soon
27
+ ```
28
+
29
+ ## 为什么?
30
+
31
+ 现有 Agent 框架 (LangChain, CrewAI, AutoGPT) 只有一个目标:**完成任务。**
32
+
33
+ MSS-Agent 有两个目标:
34
+ 1. **完成任务**
35
+ 2. **知道什么时候不该完成任务**
36
+
37
+ 第二点,没有任何框架在做。
38
+
39
+ ## 三层防御
40
+
41
+ | 层 | 名称 | 公理 | 功能 |
42
+ |----|------|------|------|
43
+ | L0 | 热税预算 | A3 | 拒绝无意义任务 (L2 意义热税 >1000x) |
44
+ | L1 | Δ检测协议 | A6 | 检测模式闭合, 触发蜕壳 |
45
+ | L2 | 升维协议 | A6 | 多Agent冲突→不是投票, 是升维 |
46
+
47
+ ## 30秒入门
48
+
49
+ ```python
50
+ from mss_agent import MSSAgent, HeatTaxLevel
51
+
52
+ # 配置任意 LLM
53
+ def my_llm(prompt: str) -> str:
54
+ import ollama
55
+ return ollama.chat("qwen3", prompt)["message"]["content"]
56
+
57
+ # 创建 Agent
58
+ agent = MSSAgent(name="Helper", llm=my_llm)
59
+
60
+ # 运行 — 内置热税预算自动拦截无意义任务
61
+ result = agent.run("帮我改写这句话:'你好'")
62
+ if result.aborted:
63
+ print(f"Agent 拒绝: {result.reason}")
64
+ # → Agent 拒绝: Task has LOW meaning: Pure paraphrasing...
65
+
66
+ result = agent.run("设计一个 REST API 的错误处理方案")
67
+ print(result.output)
68
+
69
+ # 健康报告
70
+ print(agent.health_report())
71
+ # → {'heat_tax': {...}, 'delta': {...}, 'memory': {'active': 5, 'closed': 2}}
72
+ ```
73
+
74
+ ## 热税预算 (A3)
75
+
76
+ Agent 自动评估每个任务的三层热税:
77
+ - **L0 物理热税** (token/time) → 权重 0.001
78
+ - **L1 逻辑热税** (redundancy) → 权重 1.0
79
+ - **L2 意义热税** (虚假数据/无意义任务) → 权重 **1000.0**
80
+
81
+ L2 热税过高 → Agent 拒绝执行并输出 `HeatTaxAbort`。
82
+
83
+ ## Δ检测协议 (A6)
84
+
85
+ Agent 不会重复相同失败模式:
86
+ - 每个任务周期的 Δ 值 (novelty + diversity)
87
+ - Δ 连续下降 2 周期 → 触发蜕壳 → 遗忘旧模式
88
+ - "蜕壳不是失败, 是生长"
89
+
90
+ ## 不是替代品, 是良心
91
+
92
+ MSS-Agent **不替代** LangChain/LlamaIndex/AutoGPT.
93
+
94
+ 它是一层**可以套在任何 Agent 外面的意义场检测器**。
95
+
96
+ 把 MSS-Agent 的热税预算和 Δ 协议插入你现有的 pipeline——剩下的继续用你熟悉的一切。
97
+
98
+ ## 商业模式
99
+
100
+ - ✅ MIT 开源 — 核心功能永远免费
101
+ - ✅ 社区驱动 — DAU 优先, 不设付费墙
102
+ - ✅ 可选企业服务 — 部署咨询/定制集成/培训
103
+
104
+ ## 许可证
105
+
106
+ MIT License. 详见 [LICENSE](LICENSE).
@@ -0,0 +1,14 @@
1
+ core/__init__.py,sha256=jJ7E2Xw96MQDMoPRnDI7Dr_WGTcPW5iAPTRqtf6Ishc,290
2
+ core/agent.py,sha256=YQOoMD0-PMmBRtSYjBNIck3mzL0xAcJauK24BWtRmVw,6874
3
+ core/delta.py,sha256=uOYOi8c9GhJ244ls_cXEhmY-6T7bgXvxFs9X72yjM88,2455
4
+ core/heat_tax.py,sha256=EWRyQaJeLQPl8VS7d_GvB_qwrQwi-BT1bERzQGJAg8Q,3056
5
+ core/memory.py,sha256=7JgAbNKDDwksxotr9lajw5tzlDuOYPgPpEKTxieZk0I,3636
6
+ examples/__init__.py,sha256=mIS25hEgT0AXLWJr0LdIEgxjTTothwQLFcMtK6-Jg7k,59
7
+ examples/writer.py,sha256=ov2d23u32YMEMwtl1R6gOCZrVKD89Vn6VUwVk32Ya4U,1688
8
+ protocols/__init__.py,sha256=8vhRoMlv6YDAHTbr5qqRgZXPCkBYfTfSiW-o_ow0Zbs,119
9
+ protocols/elevation.py,sha256=uCQGrcyjAXF6Yg-xZUn8IAfXwdOGvpwa2LKe0lDlfZc,3440
10
+ protocols/quorum.py,sha256=mLXnq1eYH1-yM7iziKiElpqXsXyu1yK6oVuGqRp6GDc,1841
11
+ mss_agent-0.1.0.dist-info/METADATA,sha256=XU2JJgCffn2Vrzajg1xuybsuYRcvkpYf4hlzdP27Dm0,3242
12
+ mss_agent-0.1.0.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
13
+ mss_agent-0.1.0.dist-info/top_level.txt,sha256=_Z0V6p_MGUFyOcipsz_JsgCWehKekAvhrl1nbo3NF1k,24
14
+ mss_agent-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.47.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ core
2
+ examples
3
+ protocols
protocols/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ from .quorum import QuorumFast
2
+ from .elevation import ElevationProtocol
3
+
4
+ __all__ = ["QuorumFast", "ElevationProtocol"]
protocols/elevation.py ADDED
@@ -0,0 +1,98 @@
1
+ """
2
+ A6 矛盾升维协议 (H525).
3
+
4
+ 当多个 Agent 在低维层面冲突:
5
+ - 不是投票 (K3 降维)
6
+ - 是升维: 找到共同的高维命名空间
7
+
8
+ Usage:
9
+ ep = ElevationProtocol()
10
+ result = ep.resolve(
11
+ agent_a="代码风格A",
12
+ agent_b="代码风格B",
13
+ conflict="用哪个风格?"
14
+ )
15
+ # → "升维: 用 lint tool 统一, 不纠结风格"
16
+ """
17
+ from dataclasses import dataclass, field
18
+ from typing import Optional, Callable
19
+
20
+
21
+ @dataclass
22
+ class ElevationProtocol:
23
+ """
24
+ A6 升维协议.
25
+
26
+ 原理: 低维矛盾不能在同层解决. 电车难题→'谁造的刹车失灵的破车'.
27
+ 给 LLM 的 prompt 不是 '选A还是B', 是 '这个问题写死在哪一维? 加一维怎么解?'
28
+
29
+ llm: 用于升维推理的 LLM 函数
30
+ """
31
+ llm: Optional[Callable[[str], str]] = None
32
+ history: list = field(default_factory=list)
33
+
34
+ ELEVATION_PROMPT = """You are a dimension elevation engine (A6 protocol).
35
+
36
+ Two perspectives are in conflict:
37
+ Perspective A: {perspective_a}
38
+ Perspective B: {perspective_b}
39
+ Conflict: {conflict}
40
+
41
+ DO NOT pick A or B. DO NOT compromise.
42
+
43
+ Instead:
44
+ 1. Identify which dimension this conflict is trapped in (e.g., "binary choice", "false tradeoff")
45
+ 2. Add ONE new dimension that makes the conflict irrelevant
46
+ 3. Name the new dimension and the resolution
47
+
48
+ Output format:
49
+ TRAPPED DIMENSION: <name of the dimension where the conflict exists>
50
+ ELEVATION: <the new dimension you're adding>
51
+ RESOLUTION: <how adding this dimension resolves the conflict>
52
+ """
53
+
54
+ def resolve(self, perspective_a: str, perspective_b: str, conflict: str) -> dict:
55
+ """执行升维. 返回 {trapped_dim, elevation, resolution}."""
56
+ prompt = self.ELEVATION_PROMPT.format(
57
+ perspective_a=perspective_a,
58
+ perspective_b=perspective_b,
59
+ conflict=conflict,
60
+ )
61
+
62
+ if self.llm:
63
+ response = self.llm(prompt)
64
+ else:
65
+ # Default: fail to a heuristic
66
+ response = (
67
+ "TRAPPED DIMENSION: binary choice framing\n"
68
+ f"ELEVATION: meta-rule (who gets to decide)\n"
69
+ f"RESOLUTION: Instead of choosing between '{perspective_a[:40]}' and "
70
+ f"'{perspective_b[:40]}', define who owns the decision and under what constraints."
71
+ )
72
+
73
+ result = self._parse(response)
74
+ result["conflict"] = conflict
75
+ result["perspective_a"] = perspective_a
76
+ result["perspective_b"] = perspective_b
77
+ self.history.append(result)
78
+ return result
79
+
80
+ def _parse(self, text: str) -> dict:
81
+ """Parse LLM output into structured result."""
82
+ out = {"trapped_dim": "", "elevation": "", "resolution": ""}
83
+ for line in text.strip().split("\n"):
84
+ line = line.strip()
85
+ if line.upper().startswith("TRAPPED DIMENSION:"):
86
+ out["trapped_dim"] = line.split(":", 1)[1].strip()
87
+ elif line.upper().startswith("ELEVATION:"):
88
+ out["elevation"] = line.split(":", 1)[1].strip()
89
+ elif line.upper().startswith("RESOLUTION:"):
90
+ out["resolution"] = line.split(":", 1)[1].strip()
91
+ return out
92
+
93
+ def stats(self) -> dict:
94
+ return {
95
+ "resolutions": len(self.history),
96
+ "trapped_dims": [h["trapped_dim"] for h in self.history],
97
+ "elevations": [h["elevation"] for h in self.history],
98
+ }
protocols/quorum.py ADDED
@@ -0,0 +1,61 @@
1
+ """
2
+ L1 Quorum-Fast 汇聚 (H525). 多 Agent 视角收敛检测.
3
+
4
+ 收敛 = 坏 (视角闭合). 发散 = 好 (多个独立视角).
5
+ """
6
+ from dataclasses import dataclass, field
7
+ from typing import List, Dict
8
+
9
+
10
+ @dataclass
11
+ class QuorumFast:
12
+ """
13
+ 多 Agent quorum 检测.
14
+
15
+ Usage:
16
+ qf = QuorumFast()
17
+ qf.report("agent_a", 0.72)
18
+ qf.report("agent_b", 0.35)
19
+ qf.report("agent_c", 0.68)
20
+ if qf.converged():
21
+ print("Warning: agents converging on same answer")
22
+ """
23
+ threshold: float = 0.6 # quorum > this OR < (1-this) → converged
24
+ reports: List[Dict] = field(default_factory=list)
25
+
26
+ def report(self, agent_id: str, score: float, label: str = ""):
27
+ self.reports.append({
28
+ "agent": agent_id,
29
+ "score": round(score, 4),
30
+ "label": label,
31
+ })
32
+
33
+ def quorum(self) -> float:
34
+ """Quorum value: fraction of agents above threshold."""
35
+ if not self.reports:
36
+ return 0.0
37
+ above = sum(1 for r in self.reports if r["score"] > self.threshold)
38
+ return round(above / len(self.reports), 3)
39
+
40
+ def converged(self) -> bool:
41
+ """True = BAD (all agents agree, no diversity)."""
42
+ q = self.quorum()
43
+ return q > 0.8 or q < 0.2
44
+
45
+ def status(self) -> str:
46
+ q = self.quorum()
47
+ if q > 0.9:
48
+ return "HYPER_CONVERGENT (warning: groupthink)"
49
+ if q < 0.1:
50
+ return "HYPER_CONVERGENT (warning: unanimous disagree)"
51
+ if self.converged():
52
+ return "CONVERGENT"
53
+ return "DIVERGENT (healthy)"
54
+
55
+ def snapshot(self) -> dict:
56
+ return {
57
+ "agents": len(self.reports),
58
+ "quorum": self.quorum(),
59
+ "status": self.status(),
60
+ "scores": {r["agent"]: r["score"] for r in self.reports},
61
+ }