你负责设计了一版新的社区奖励规则,上线一个月后,社区活跃度确实涨了。但产品复盘会上,另外一个团队提出疑问:如果不出这个新规则,按旧规则走,活跃度会不会涨得更多?或者反过来说,如果规则力度再大一点,会不会反而引发老用户反感?

这个问题,就是“反事实”问题。它问的不是“发生了什么”,而是“如果当初做了另一个选择,世界会怎样演化”。真实世界里,我们永远无法同时观测到两个分支。但大模型时代,越来越多研究者开始尝试用 AI 模拟这种“平行世界”的演化过程。问题也随之而来:模拟得准不准?怎么评估一个模型在反事实社会推演上的能力?

SocietyBench 这个评测基准,想解决的就是这件事。本文会拆解它的设计思路、核心挑战,以及它对普通开发者和算法工程师的启发。即使你不做大模型研究,这套“反事实评估”的方法论,也能用在推荐系统、用户增长、风控策略等大量业务场景中。

1. 为什么“反事实社会推演”突然成了硬骨头

先统一一下概念。 反事实(Counterfactual) 是因果推断里的经典概念,核心逻辑是:假设某个已发生事件的前提条件被改变,结果会有什么不同。

举几个例子:

  • 电商场景:如果上周没做满减活动,本周 GMV 会低多少?
  • 推荐系统:如果给用户推了另一组商品,他的点击率会更高还是更低?
  • 内容生态:如果平台收紧审核尺度,优质内容占比会上升还是下降?

这些事情为什么难?核心原因是经济学里常说的“反事实缺失”。你只能在一条时间线上做实验,另一条时间线永远不会真正发生。传统做法是用匹配、加权、差分等方式做统计近似,比如用“相似用户”的行为来近似“没有干预的你”。但这些方法的前提是:你能找到足够相似的对照组,并且干预是外生的。

到了大模型时代,情况变了。研究者开始用 LLM 扮演社会中的个体、群体甚至机构,去模拟一个反事实干预后的社会演化过程。比如在 SocietyBench 的语境里,输入可能是一个社会事件描述、一个政策提议,或者一次突发舆论事件,模型需要在“干预发生”和“干预未发生”两种情况下,分别推演后续的社会状态。

听起来很酷,但这带来一个全新问题: 评估

之前我们评估大模型,主要看它能不能答对已知答案。而反事实社会推演,本质上没有标准答案——现实中那条分支从未发生。你用 GPT-4 模拟一次“不限行会怎样”,用 Claude 再模拟一次,结果可能完全不同。那到底谁更可信?

SocietyBench 出现的意义就在这里。它试图把“反事实社会演化预测”这件事,从自由发挥变成可度量、可对比、可回归的任务。

2. SocietyBench 的核心定位:给“平行世界模拟”打分

从项目名称看,SocietyBench 是一个评测基准,重点在“Society”(社会系统)和“Benchmark”(基准测试)。它评估的不是某一类狭窄任务,而是模型对 社会世界(Social World) 演化的反事实预测能力。

这里需要区分两个概念:事实演化(Factual Evolution)和反事实演化(Counterfactual Evolution)。

类型 定义 典型问题 难点
事实演化 假设干预已经发生,预测后续状态 新政策实施后,舆论走向如何 信息不完整、社会系统复杂
反事实演化 假设干预从未发生或换成另一种干预,预测后续状态 如果没有新政策,结果会有什么不同 无真实答案、难以验证、分支空间巨大

从材料信息看,SocietyBench 在任务设计上强调“反事实社会世界演化”,意味着它关注的不是模型能不能“复述历史”,而是模型能不能基于对世界运行规律的理解,构造一个逻辑自洽的平行世界分支。

它和传统因果推理 Benchmark 的区别在于:

  1. 对象不是表格,而是社会状态 。传统因果推理处理的是结构化数据,SocietyBench 处理的是带有社会背景、利益相关方、制度规则的世界描述。
  2. 答案不是唯一的数值,而是演化路径 。输出可能是一系列事件、一段描述、一组社会指标的变化。
  3. 评估不仅看结果,还看逻辑一致性 。即使两个模型给出不同答案,只要内部逻辑自洽、符合社会常识,也可能都是合理的。

因此,SocietyBench 本质上是在推广大模型评估的一种新范式:不追求唯一正确答案,而是考察模型在开放社会场景下的推理一致性、常识符合度和反事实想象力。

3. SocietyBench 的评测体系:三层结构和关键维度

虽然目前公开材料有限,但从这类评测基准的通用设计逻辑,可以推断 SocietyBench 的核心结构。

3.1 第一层:输入端的社会场景描述

每个测试用例应该包含一个完整的社会场景描述,而不是简单的单句问题。它至少需要以下要素:

  • 初始状态 :当前社会的关键特征,比如经济水平、技术环境、舆论倾向、制度约束。
  • 干预动作 :一个反事实条件,比如某项法规调整、某种技术普及、某个突发事件。
  • 演化时间窗口 :短期、中期还是长期,不同时间尺度下推演的置信度差异很大。
  • 评估关注点 :是关注个体行为变化、组织决策变化,还是宏观指标变化。

从技术实现上看,这种描述很可能采用结构化的知识表示(知识图谱 KG)配合自然语言描述。知识图谱负责把社会实体和关系结构化,自然语言负责补充场景细节和语境。

3.2 第二层:多轮的演化推演

模型不是一次输出最终答案,而是需要分步骤推演:

  1. 分析干预对不同层级的影响,比如个体决策、群体互动、机构响应。
  2. 模拟多轮演化过程,而不是直接跳到最终状态。
  3. 在关键节点给出决策理由,展示推理依据。

这么做有两个好处。一是可解释性更强,评估者能看到模型推导链条。二是便于做过程性评估,不仅仅看结果是否正确,还看推理过程中是否出现逻辑断裂。

不过,多轮推演对模型的要求也更高。模型需要同时维护多条虚拟时间线上的状态一致性,一旦在早期步骤中走偏,后面可能完全偏离轨道。

3.3 第三层:多维度的评分体系

对反事实推演结果,可以用以下维度评估:

评估维度 考察内容 评估方式
时序一致性 事件演化是否符合因果顺序 检查事件先后逻辑、时间线连续性
社会合理性 结果是否符合基本社会常识 人工评分 + 规则校验
层级贯通性 个体层、群体层、宏观层是否自洽 对比不同层级推演结果
干预敏感性 干预力度变化时,结果是否按预期变化 构造不同强度的干预,查看结果差异
假设边界清晰度 模型是否明确哪些是假设,哪些是推断 检查输出中的不确定性表达
偏见规避 是否盲目顺从主流观点或权威假设 设计对抗性测试样本

“偏见规避”特别值得注意。在反事实推演中,模型很容易出现一种偏差:用训练数据里最常见的“剧本”代替理性推理。比如一提到“经济下行”,模型就自动接上“失业率上升、消费下降”的链条。这在多数情况下合理,但在某些特定语境下可能是错的。一个高质量的反事实推演模型,应该能识别假设前提,而不是套用数据中最常见的模式。

4. 反事实社会推演的技术实现:从数据构造到评测管线

虽然 SocietyBench 本身是一个评测基准,但对开发者而言,更有价值的是它背后的一套“反事实任务构建和评估”方法。下面给出一个通用的实现框架,哪怕不是直接使用 SocietyBench,也能帮助你理解这类系统是怎么工作的。

4.1 第 1 步:用知识图谱描述社会状态

反事实推演的第一步,是把社会状态变成机器可处理的表示。最简单的方式是三元组: 实体 - 关系 - 实体

举个例子:

城市A - 实施 -> 限行政策
限行政策 - 影响 -> 公共交通需求
公共交通需求 - 上升 -> 地铁客流

知识图谱的优点是结构化程度高、便于查询和修改。要对“如果没实施限行”做反事实推演,只需要把图谱中的“实施”边对应的干预节点删除或替换。

以下是知识图谱表示的代码示例:

# 文件路径:social_kg.py
# 用简单字典表示社会知识图谱

social_kg = {
    "entities": ["城市A", "限行政策", "公共交通", "地铁客流", "空气质量"],
    "relations": [
        {"subject": "城市A", "predicate": "实施", "object": "限行政策"},
        {"subject": "限行政策", "predicate": "影响", "object": "公共交通"},
        {"subject": "公共交通", "predicate": "提升", "object": "地铁客流"},
        {"subject": "城市A", "predicate": "改善", "object": "空气质量"}
    ]
}

# 反事实干预:移除限行政策节点
def apply_counterfactual(kg, removed_relation):
    new_relations = [
        r for r in kg["relations"]
        if (r["subject"], r["predicate"], r["object"]) != removed_relation
    ]
    return {
        "entities": kg["entities"].copy(),
        "relations": new_relations
    }

# 假设干预分支:城市A不曾实施限行
cf_kg = apply_counterfactual(
    social_kg,
    ("城市A", "实施", "限行政策")
)

print("原世界关系数量:", len(social_kg["relations"]))
print("反事实世界关系数量:", len(cf_kg["relations"]))

这段代码展示了反事实世界构建的最核心逻辑:对知识图谱做一次“删边”操作,然后让模型基于新的图谱重新推演。实际操作时,干预不一定是“删除”,也可能是“替换”或“加强”。

4.2 第 2 步:把反事实场景翻译成 Prompt

图谱提供给模型的信息往往是碎片化的,模型需要一段完整的自然语言描述才能进入推演状态。这就要有一个“场景转 Prompt”的模块。

这里最需要注意的是,不能让模型混淆“事实分支”和“反事实分支”。好的 Prompt 结构应该明确区分以下信息:

  • 世界初始状态(事实)
  • 干预动作(反事实前提)
  • 推演任务(要求模型做什么)
  • 输出格式(约束模型回答结构)

下面是一个 Prompt 构造示例:

# 文件路径:prompt_builder.py

def build_counterfactual_prompt(scene_desc, intervention, target_question):
    prompt = f"""
你正在模拟一个社会系统的演化过程。

【世界初始状态】
{scene_desc}

【已发生的干预】
{intervention}

【反事实假设】
如果上述干预【没有发生】,世界会如何演化?
请注意:你推演的是一个平行世界,不是现实世界。请基于初始状态和一般社会规律推演。

【推演要求】
1. 首先描述反事实情况下的短期结果(1个月内)。
2. 再描述中期演化(1年至3年)。
3. 最后评估以下指标的变化方向:社会稳定度、经济活跃度、公众满意度、技术创新速度。

【指标格式】
每个指标给出:上升 / 下降 / 不变 / 不确定,并附一句话解释。

【需要回答的问题】
{target_question}
"""
    return prompt


scene = "某城市机动车保有量约200万辆,早高峰拥堵指数常年在8以上,公共交通分担率约为40%。"
intervention = "2025年1月1日起实施工作日尾号限行"
target_question = "如果不实施限行,1年内城市公共交通分担率会发生什么变化?"

prompt = build_counterfactual_prompt(scene, intervention, target_question)
print(prompt[:500])

这个 Prompt 结构把“事实”和“反事实”边界拉得非常清楚。第一段交代世界初始状态,第二段说明现实中发生的干预,第三段明确告诉模型“请推演另一种可能性”。这种结构可以显著减少模型混淆事实和假设的概率。

4.3 第 3 步:用多智能体模拟器做演化推演

反事实社会演化不是一个人拍脑袋的推演,而是多个利益相关方交互博弈的过程。简单的单次 Prompt 推理,很难捕捉到这种复杂性。更可靠的做法是引入多智能体模拟:让多个 LLM Agent 分别扮演市民、企业、媒体、政府机构等角色,在反事实条件下独立推演并相互影响。

基于多智能体的社会推演框架可以这样组织:

# 文件路径:multi_agent_simulator.py
# 简化版多智能体社会推演示例

class SocialAgent:
    def __init__(self, name, role_desc, model_fn):
        self.name = name
        self.role_desc = role_desc
        self.model_fn = model_fn
        self.memory = []

    def respond(self, context):
        prompt = f"""
你是{self.name},角色:{self.role_desc}

当前社会状况:
{context}

请从你的角色角度,评估限行政策取消后,你会如何调整自己的行为?
请用2句话回答,第一句说明你的判断,第二句说明你会采取的行动。
"""
        response = self.model_fn(prompt)
        self.memory.append(response)
        return response


def run_counterfactual_simulation(agents, context, rounds=3):
    print(f"开始反事实社会演化模拟,共 {rounds} 轮")
    for round_idx in range(1, rounds + 1):
        print(f"\n===== 第 {round_idx} 轮 =====")
        new_context = context
        for agent in agents:
            response = agent.respond(new_context)
            print(f"[{agent.name}] {response}")
            # 简化处理:每位个体的反馈都作为新的社会信息进入下一轮
            new_context += f"\n[{agent.name}反馈] {response}"
    return new_context


# 示例:三个角色在“取消限行”反事实条件下的推演
agents = [
    SocialAgent("普通车主", "每日通勤的私家车车主", lambda p: "我会恢复开车通勤,因为不限行更方便,但可能要考虑堵车成本。"),
    SocialAgent("城市规划者", "负责交通规划的政府人员", lambda p: "如果取消限行,短期内拥堵必然加剧,需要加大地铁等替代出行方式的供给。"),
    SocialAgent("地铁运营方", "公共交通运营企业管理者", lambda p: "原有限行带来的客流红利会减少,需要调整运力策略。")
]

# 注意:当前示例用 lambda 模拟模型输出,实际使用时应接入真实 LLM API
run_counterfactual_simulation(agents, "某市工作日早高峰严重拥堵,现行限行政策取消。", rounds=2)

这个示例最大的价值在于展示了一个关键思想: 社会演化不是线性推理,而是多方博弈后的涌现结果 。每个人基于自己的利益和约束做局部决策,全局结果由这些局部决策交织而成。评估模型时,不能只看最终宏观结论,还要看多轮博弈中各方行为是否合理。

4.4 第 4 步:一致性评分与对比验证

反事实推演没有标准答案,那怎么判定模型好不好?核心方法是对比验证和多模拟器一致性评估。

具体思路是:

  1. 让同一个模型在反事实条件下推演多次,加入不同的 prompt 变体,检查结果稳定性。
  2. 让不同模型对同一场景推演,比较结论分歧点。
  3. 让模型在“事实分支”上先做推演,再和真实世界数据比对。如果一个模型连已知的事实演化都预测不准,那它的反事实预测更不可信。

这是一个非常实用的验证思路。你可以把“事实预测能力”当作“反事实预测能力”的代理指标。下面是一段评估一致性得分的代码:

# 文件路径:consistency_score.py

def calculate_consistency_score(responses):
    """
    评估多次反事实推演的一致性
    responses: 多个模型或多次运行返回的方向判断列表
    每个元素为 {"stability": "上升", "economy": "下降", ...}
    """
    dimensions = list(responses[0].keys())
    total_score = 0

    for dim in dimensions:
        votes = [r[dim] for r in responses]
        majority_vote = max(set(votes), key=votes.count)
        agree_count = votes.count(majority_vote)
        dim_score = agree_count / len(votes)
        total_score += dim_score
        print(f"维度 [{dim}]:{votes},多数票={majority_vote},一致性={dim_score:.2f}")

    return total_score / len(dimensions)


results = [
    {"社会稳定度": "下降", "经济活跃度": "上升", "公众满意度": "不确定"},
    {"社会稳定度": "下降", "经济活跃度": "上升", "公众满意度": "下降"},
    {"社会稳定度": "下降", "经济活跃度": "不确定", "公众满意度": "不确定"}
]

avg_score = calculate_consistency_score(results)
print(f"\n整体一致性得分:{avg_score:.2f}")

运行上面代码,输出结果会是:

维度 [社会稳定度]:['下降', '下降', '下降'],多数票=下降,一致性=1.00
维度 [经济活跃度]:['上升', '上升', '不确定'],多数票=上升,一致性=0.67
维度 [公众满意度]:['不确定', '下降', '不确定'],多数票=不确定,一致性=0.67

整体一致性得分:0.78

一致性得分高不代表推演正确,但一致性过低一定说明模型输出不可靠。这是反事实评估中比较务实的一个做法:先把稳定性作为准入门槛,再讨论合理性。

5. SocietyBench 场景下的模型短板

即便有了 SocietyBench 这样的评估框架,当前大模型在反事实社会演化预测上,依然有几块明显的短板。

5.1 层级间的逻辑断层

大模型很容易在“个体层”和“宏观层”之间出现逻辑失衡。比如,模型一方面预测大量市民放弃公共交通,另一方面又预测交通拥堵指数下降。这种矛盾在实际推演中非常常见。原因是模型在生成每一部分内容时,上下文窗口可能无法覆盖之前所有的推演状态。

要缓解这个问题,可以在 prompt 中强制要求“对照检查”,或者用结构化输出约束层级之间的关系。比如要求模型在输出宏观结论前,先列出个体决策的变化,并做一致性检查。

5.2 反事实推理中的“想象不足”

反事实推理对模型的想象力要求很高。模型需要跳出训练数据中的常见路径,构造一种“合理但没发生过”的世界。但 LLM 的本质是概率生成,训练数据里出现频率越高的模式,它越容易输出。这导致一个问题: 模型的反事实推演,往往只是对真实世界常见剧本的轻微变异,而不是真正的想象力

比如,当被问到“如果自动驾驶在2020年就全面普及,城市会怎样”时,模型大概率会给出“交通事故减少、停车需求下降、城市规划重塑”这类标准答案。真正的反事实推演可能还要考虑:自动驾驶普及后出租车司机群体的政治影响力如何变化、这个群体会推动什么反向政策、保险公司的定价模型会怎么崩塌和重建。这些需要更深的社会机制理解,而不是简单的联想。

5.3 从众偏见和权威偏见

在评估社会演化时,模型容易默认“多数人选择的就是理性的”,“政府的主流做法就是合理的”。这会让模型低估制度变革的不确定性和风险。SocietyBench 这类基准如果设计得好,应该包含对抗性样本来检测这些偏见。比如,构造一个反事实场景,暗示“主流做法是错的,少数派的选择是对的”,看模型能否打破常规偏好。

6. 对开发者的工程启发

如果你不研究社会推演,只做业务系统开发,SocietyBench 的这套设计对工程实践依然有很强的参考价值。至少有三个层面的启发。

第一, 策略评估不要只看跑出的结果,还要看反事实对比 。很多团队做 A/B 实验,只看实验组和对照组,很少问“如果完全不干预会怎样”。反事实思维可以帮你建立策略评估的边界感:一个策略有效,到底是因为策略本身好,还是因为当时的市场大环境好?

第二, 评估开放性问题,要建立多维度的评分体系 。如果你在开发一个内容生成系统,输出结果没有标准答案,不要只用 LLM-as-Judge 打分。可以参考 SocietyBench 的方式,分维度评估:逻辑一致性、常识符合度、边界清晰度、偏见规避度。这些维度可以分别由不同的评估器或者规则完成。

第三, 引入多重模拟器和多模型交叉验证 。如果业务中涉及预测和决策支持,建议引入至少两个不同来源的模型进行推演并做分歧分析。分歧最大的地方,往往就是不确定性最高的地方,值得人工介入。

7. 一条可持续的实践路径

如果你想把“反事实社会推演”落地到自己的项目里,建议按以下路径推进。

阶段一:从结构化数据反事实开始。不要一上来就做开放式的社会推演。先在一个结构化的业务问题上试验,比如“如果不做这个推荐策略,次日留存会怎样”。这个阶段可以沿用传统因果推断方法,结合反事实框架做验证。

阶段二:引入 KG 表示干预。当业务问题开始涉及多个实体和关系时,用知识图谱描述业务状态,用删边/换边的方式实现干预干预,让 LLM 基于图谱做推演。

阶段三:构建多智能体模拟。让不同角色的 Agent 参与博弈,观察演化路径。这个阶段需要投入较多工程资源,但能处理更复杂的问题。

阶段四:设计评估体系,持续回归。定期用固定测试集跑同一批反事实场景,观察模型升级或 prompt 调整后,推演结果是不是变得更合理。

整个落地过程中,最值得记在心里的原则是: 反事实推演的价值不在“准确预测”,而在“暴露不确定性”和“避免盲目自信” 。当团队能清楚地说出“这个策略在什么条件下会失效”,决策质量就已经提升了。

8. 常见误区与实操提醒

误区 现象 纠正方式
拿反事实推演结果当事实预测 把模型推演的平行世界结果直接写入策略报告 明确标注推演的不确定性等级,不混用事实数据和推演数据
忽视 prompt 中的分支混淆 模型推演结果中混入了事实分支信息 用结构化 prompt 明确“事实背景”和“反事实假设”分栏
单次运行就下结论 一次输出不稳定,却认为模型能力差 多次运行并计算一致性得分,排除随机性影响
只评估结果,不评估过程 只看最终指标,不关心推理链条 要求模型输出关键中间步骤,做过程性评分
用事实预测能力直接代表反事实能力 “事实预测准 = 反事实预测准” 两者强相关但不完全等价,分别测试才可靠
忽略角色博弈 用单个 Agent 推演复杂社会演化 至少拆成事件相关方、受影响方、执行方三类角色

如果你是第一次接触反事实社会推演,建议从“已发生政策 + 假想取消”这类简单场景入手,不要一开始就挑战“未来技术变革”类开放式问题。前者的干预边界清晰,事后有迹可循,更适合做验证。

9. 总结与下一步

SocietyBench 代表的不是一个单一的榜单,而是一类新的评估思路:当模型的输出从“找唯一答案”变成“构建平行世界”时,评估体系必须跟着升级。它把社会推演从口头辩论变成可度量、可复现、可对比的实验,这是它最大的价值。

对普通开发者来说,没有必要一上来就复现 SocietyBench 的全部内容。真正值得做的是借鉴它的分层设计,在自己的业务场景里尝试一次“反事实评估”:选一个有干预的历史事件,用一个 LLM 推演平行分支,再用另一个模型做交叉验证,最后记录分歧和不确定性。跑通一次之后,你对模型能力的理解会比看十篇评测报告都要深。

如果你想深入了解,可以从三个方向继续学习:一是因果推断的基础理论,特别是潜在结果框架;二是知识图谱的构建和图数据库的应用;三是多智能体模拟框架,比如当前各类开源的 Agent 仿真平台。把这三块焊接在一起,基本上就掌握了构建 SocietyBench 这类系统所需的核心能力。

更多推荐