feat: 添加观点传播系统
- 新增 Stance 数据结构 (optimism/fear) - 情绪影响 stance (happy→乐观, anxious→恐惧) - 实现 apply_social_influence 社交影响函数 - 确定性随机选择接触对象 - 单次变化限制 ±0.1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -229,3 +229,69 @@ def test_opinion_cleared_when_no_effect(client):
|
||||
# 无世界事件时,opinion 应为 None
|
||||
for agent_id, agent in data["world_state"]["agents"].items():
|
||||
assert agent["opinion"] is None
|
||||
|
||||
|
||||
def test_stance_exists_in_agent(client):
|
||||
"""测试 agent 包含 stance 字段"""
|
||||
resp = client.post("/step", json={"events": []})
|
||||
data = resp.json()
|
||||
|
||||
for agent_id, agent in data["world_state"]["agents"].items():
|
||||
assert "stance" in agent
|
||||
assert "optimism" in agent["stance"]
|
||||
assert "fear" in agent["stance"]
|
||||
assert 0.0 <= agent["stance"]["optimism"] <= 1.0
|
||||
assert 0.0 <= agent["stance"]["fear"] <= 1.0
|
||||
|
||||
|
||||
def test_stance_changes_on_world_event(client):
|
||||
"""测试世界事件触发时 stance 变化"""
|
||||
# 记录初始 stance
|
||||
resp1 = client.post("/step", json={"events": []})
|
||||
initial_stances = {
|
||||
aid: agent["stance"].copy()
|
||||
for aid, agent in resp1.json()["world_state"]["agents"].items()
|
||||
}
|
||||
|
||||
# 触发世界事件
|
||||
events = [
|
||||
{"type": "chaos", "text": f"chaos{i}", "user": "test", "ts": i}
|
||||
for i in range(20)
|
||||
]
|
||||
resp2 = client.post("/step", json={"events": events})
|
||||
data = resp2.json()
|
||||
|
||||
# 验证事件触发
|
||||
assert data["global_event"]["triggered"] is True
|
||||
|
||||
# stance 应该有变化(由于情绪和社交影响)
|
||||
for aid, agent in data["world_state"]["agents"].items():
|
||||
# stance 值仍在有效范围内
|
||||
assert 0.0 <= agent["stance"]["optimism"] <= 1.0
|
||||
assert 0.0 <= agent["stance"]["fear"] <= 1.0
|
||||
|
||||
|
||||
def test_social_influence_deterministic(client):
|
||||
"""测试社交影响是确定性的(同输入同输出)"""
|
||||
events = [{"type": "comment", "text": "hello", "user": "test", "ts": 1}]
|
||||
|
||||
# 第一次执行
|
||||
save_state(get_default_state())
|
||||
resp1 = client.post("/step", json={"events": events})
|
||||
stances1 = {
|
||||
aid: agent["stance"]
|
||||
for aid, agent in resp1.json()["world_state"]["agents"].items()
|
||||
}
|
||||
|
||||
# 重置并再次执行
|
||||
save_state(get_default_state())
|
||||
resp2 = client.post("/step", json={"events": events})
|
||||
stances2 = {
|
||||
aid: agent["stance"]
|
||||
for aid, agent in resp2.json()["world_state"]["agents"].items()
|
||||
}
|
||||
|
||||
# 结果应该相同
|
||||
for aid in stances1:
|
||||
assert stances1[aid]["optimism"] == stances2[aid]["optimism"]
|
||||
assert stances1[aid]["fear"] == stances2[aid]["fear"]
|
||||
|
||||
Reference in New Issue
Block a user