一位开发者花了二十年,在 Telegram、VK、Instagram、Facebook 等平台上积累了超过 120 万条个人聊天记录。然后他做了一件大多数人不敢做的事——把这些记录喂给大模型,让它回答一个问题:"我是个糟糕的朋友吗?"
这个叫 "Am I a Bad Friend?" 的项目,本质上是一个"数字人生档案馆"。它不只是数据可视化,更像是对人际关系做了一次全量审计。结果让人既好奇又不安:你二十年的社交行为,被一个模型看得比你自己还清楚。
120 万条消息从哪来
从 2000 年代初开始,作者几乎没删过聊天记录。数据横跨多个平台:
- Telegram——导出最友好,直接用内置工具就能拿到 JSON
- VK(俄罗斯社交平台)——有 API,但需要处理编码和分页
- Instagram / Facebook——官方数据下载工具提供 HTML 或 JSON,格式混乱,解析最痛苦
核心难点不是"能不能拿到数据",而是格式统一。120 万条消息来自五六个平台,时间格式、消息结构、媒体引用方式各不相同。清洗和归一化才是真正耗时的环节。
大模型怎么分析人际关系
项目没有简单地把 120 万条消息一股脑丢给 GPT。那样做既超上下文窗口,也缺乏结构化结论。实际路径更像是分桶 + 抽样 + 聚合:
- 按联系人分桶——把所有消息按对话对象分组,每个朋友一个桶
- 按时间切片——把每个桶的消息按年或季度切分,观察关系随时间的变化
- 抽样摘要——对每个切片抽取代表性消息(比如高频词、情绪极性、回复延迟),生成结构化摘要
- 全局评估——把所有摘要拼成一份"友谊报告",让大模型从回复频率、主动发起比例、情绪支持度等维度打分
最终输出不是一句"你是好朋友"或"你是坏朋友",而是每个朋友的关系时间线:哪年聊得最多,哪年开始冷淡,谁总是主动找你,谁你总是忘记回复。
自己动手:聊天记录友谊分析最小项目
下面是一个可运行的 Python 示例,用 Telegram 导出的 JSON 聊天记录做简化版友谊分析。假设你已经用 Telegram 的导出功能拿到了 result.json。
前提:你需要一个 OpenAI API Key(或其他兼容接口),以及 Telegram 导出的聊天数据。替换
API_KEY和文件路径后再运行。
import json
import os
from collections import defaultdict
from datetime import datetime
from openai import OpenAI
# ---------- 配置 ----------
API_KEY = "sk-你的key"
TELEGRAM_EXPORT_PATH = "telegram_export/result.json"
MODEL = "gpt-4o-mini" # 用便宜模型做摘要即可
client = OpenAI(api_key=API_KEY)
# ---------- 第一步:加载并按联系人分桶 ----------
with open(TELEGRAM_EXPORT_PATH, "r", encoding="utf-8") as f:
data = json.load(f)
buckets = defaultdict(list) # key: 联系人名, value: 消息列表
for chat in data.get("chats", {}).get("list", []):
name = chat.get("name", "unknown")
for msg in chat.get("messages", []):
if msg.get("type") != "message":
continue
buckets[name].append({
"date": msg.get("date", ""),
"from": msg.get("from", ""),
"text": msg.get("text", "") if isinstance(msg.get("text"), str) else "",
})
print(f"共 {len(buckets)} 个联系人,总消息 {sum(len(v) for v in buckets.values())} 条")
# ---------- 第二步:按年切片 + 统计基础指标 ----------
def yearly_stats(messages):
stats = defaultdict(lambda: {
"total": 0, "sent": 0, "received": 0,
"avg_delay_min": 0, "texts_sample": []
})
prev_date = None
for msg in messages:
try:
dt = datetime.strptime(msg["date"][:10], "%Y-%m-%d")
except ValueError:
continue
year = dt.year
s = stats[year]
s["total"] += 1
if msg["from"] == "我自己的名字": # ← 替换成你在 Telegram 中的显示名
s["sent"] += 1
else:
s["received"] += 1
# 取每年第 10 条消息做抽样,避免摘要过长
if s["total"] % 10 == 0 and msg["text"]:
s["texts_sample"].append(msg["text"][:80])
return dict(stats)
# ---------- 第三步:用大模型生成友谊摘要 ----------
def summarize_friend(name, stats_dict):
prompt_parts = []
for year, s in sorted(stats_dict.items()):
prompt_parts.append(
f"{year}年: 共{s['total']}条, 我发{s['sent']}条/收到{s['received']}条, "
f"抽样内容: {'; '.join(s['texts_sample'][:5])}"
)
prompt = (
f"以下是我和朋友「{name}」的逐年聊天统计摘要:\n"
+ "\n".join(prompt_parts)
+ "\n\n请从以下维度评价这段友谊:\n"
"1. 主动发起聊天的比例(我主动 vs 对方主动)\n"
"2. 关系热度变化趋势(升温/平稳/降温)\n"
"3. 情绪支持度(对方倾诉时我的回应质量推测)\n"
"4. 总体评价:我是个好朋友吗?给出具体理由。\n"
"用中文回答,简洁有力。"
)
resp = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": prompt}],
max_tokens=500,
)
return resp.choices[0].message.content
# ---------- 执行 ----------
for name, msgs in list(buckets.items())[:5]: # 先分析前 5 个联系人
if len(msgs) < 50: # 太少的跳过
continue
stats = yearly_stats(msgs)
summary = summarize_friend(name, stats)
print(f"\n{'='*40}")
print(f"朋友: {name} | 消息数: {len(msgs)}")
print(summary)
运行前需要改的地方:
API_KEY——换成你的真实 keyTELEGRAM_EXPORT_PATH——指向你导出的result.json"我自己的名字"——替换成你在 Telegram 聊天中显示的发送者名称list(buckets.items())[:5]——去掉[:5]可以分析所有联系人,但 API 调用成本会上升
这个脚本做的是最简版本:按年统计发送/接收比例,抽样文本交给大模型评估。原项目还做了回复延迟计算、情绪极性标注、话题聚类等更深的分析,但上面的代码已经能跑出有意义的结论。
看到结果之后的不安
项目名字叫"Am I a Bad Friend?",这个问号不是修辞。当你看到模型告诉你——"2020 年之后你和 X 的对话,90% 是对方主动发起的,你的回复平均延迟从 2 分钟变成了 4 小时"——那种感觉不是被审判,而是被提醒了你已经忘记的事。
技术上,这个项目揭示了几件事:
- 个人数据是未被开采的矿。二十年聊天记录的信息密度远超任何问卷或自我报告。
- 大模型擅长"软测量"。回复延迟、主动比例、语气变化——这些传统 NLP 很难量化的指标,大模型通过摘要 + 评分可以给出有意义的估计。
- 分桶-切片-摘要-聚合是处理超长个人数据的实用架构,绕过了上下文窗口限制。
但风险同样真实:
- 隐私——你分析的不只是你自己的数据,还有每个朋友说过的每一句话
- 归因偏差——模型说"你回复变慢了",但原因可能是你换了工作而不是你不在乎
- 过度量化——友谊不是回复延迟的函数,把关系压缩成指标会丢失最重要的部分
在做之前想清楚的事
如果你想复现类似分析,建议先过一遍这个清单:
| 检查项 | 说明 |
|---|---|
| 只分析自己的数据吗? | 朋友的消息也包含在内,你是否征得了他们的同意? |
| 结论的用途是什么? | 是自我反思,还是要拿结果去"对质"?前者有用,后者危险 |
| 数据存储安全吗? | 120 万条聊天记录是极度敏感的个人信息,不要放在云端明文存储 |
| 模型调用成本可控吗? | 每个联系人一次摘要调用,100 个朋友就是 100 次,估算后再跑 |
| 接受意外结论吗? | 模型可能告诉你"你和最亲密的朋友,关系已经单向化了"——你准备好了吗? |
这个项目最有价值的地方不是技术实现——分桶、切片、摘要,任何一个工程师都能写出来。真正有价值的是那个问题本身:我是个糟糕的朋友吗?
技术给了你一面镜子。照不照,怎么照,照完之后做什么,是技术以外的事。