AbandonAudit — 半途而废尝试分析器 × 内外阻碍拆解器
一、实际应用场景描述
你打开电脑,看着桌面上一排文件夹:
-
"novel_draft/" — 写了三章,主角名字都忘了
-
"ai_flashcards/" — 搭了脚手架,API Key 填了一半
-
"gym_routine/" — 练了两周,哑铃现在挂着衣服
-
"language_app/" — 学了 12 天, streak 断了再没续
你叹口气,心里冒出一个熟悉的声音:"我就是这样,什么都坚持不下来。"
这句话很危险。它把无数个不同的失败,压缩成了一个关于你人格的结论。
更糟的是,你从来没认真看过这些"半途而废":
- 是真的因为你懒?
- 还是目标定太大?
- 还是没人陪你做?
- 还是你根本不喜欢这件事,只是觉得"应该做"?
AbandonAudit 就是为这些被遗弃的尝试而生的审计工具——它不让你自责,也不让你逃避。它把你所有的"烂尾楼"拉出来,强制拆解:哪些是外部环境的问题,哪些是你内心的阻力,然后分别给解决方案。
二、引入痛点
痛点 本质问题 本工具解法
"我就是没毅力" 把行为归因成人格缺陷 强制内外因分离分析
同类错误反复犯 没有从失败中提取模式 阻碍模式聚类 + 频率统计
放弃后直接跳过 没有复盘,只有愧疚 结构化记录放弃上下文
解决方案太笼统 "下次要坚持"毫无用处 针对具体阻碍给具体行动
外部借口太多 把所有责任推给环境 内外因平衡评估
看不到整体图景 每次只看到单个失败 全局统计 + 模式识别
三、核心逻辑讲解
理论基础(工程化映射)
1. 韦纳归因理论(Weiner's Attribution Theory)
- 人们对成败的归因会影响后续动机
- 三个维度:内部/外部 × 稳定/不稳定 × 可控/不可控
- 本工具强制把每个放弃事件拆成外部阻碍和内心阻碍
2. 执行功能(Executive Function)模型
- 发起、计划、组织、情绪调节、任务监控
- 半途而废往往不是"意志力",而是某个执行功能短板
- 本工具识别具体是哪个环节出问题
3. 行为设计(Behavioral Design)
- 不改变人,改变环境
- 外部阻碍 → 环境改造
- 内心阻碍 → 认知重构 + 行为链拆解
核心分析流程
录入废弃尝试
↓
结构化输入:目标 / 持续时间 / 放弃原因(自由文本)
↓
自动分类:
├─ 外部阻碍:资源 / 环境 / 社会支持 / 任务设计
└─ 内心阻碍:恐惧 / 价值冲突 / 兴趣缺失 / 完美主义
↓
归因维度标注:稳定/不稳定 × 可控/不可控
↓
分别生成解决方案:
├─ 外部阻碍 → 环境改造 / 资源补充 / 社会支持
└─ 内心阻碍 → 认知重构 / 行为链拆解 / 暴露练习
↓
生成"复活计划"或"体面告别"
↓
追踪模式:哪种阻碍出现最频繁?
↓
月度复盘:你的"半途而废"有什么共性?
阻碍分类体系
大类 子类 典型表现 解决方向
外部阻碍 资源不足 没钱、没时间、没工具 资源获取 / 优先级调整
环境干扰 噪音、分心、空间不适 环境改造 / 物理隔离
社会支持缺失 没人理解、孤立无伴 寻找同好 / 公开承诺
任务设计缺陷 目标过大、反馈缺失 拆解任务 / 增加反馈
内心阻碍 恐惧失败 怕做不好、怕被评价 认知重构 / 暴露练习
价值冲突 "应该做"但"不想做" 价值澄清 / 重新对齐
兴趣缺失 枯燥、无好奇心 游戏化 / 换角度
完美主义 做不到最好就不做 接受"烂开始" / 渐进式
解决方案生成逻辑
识别主导阻碍
↓
匹配解决方案模板库
↓
根据严重程度调整强度
↓
生成具体行动步骤(3-5 步)
↓
标注:预估耗时 / 难度 / 成功概率
↓
用户选择保留哪些 → 保存为"复活计划"
四、代码模块化(六层架构)
目录结构
abandon_audit/
├── main.py ← 入口层:Application 容器 + CLI 调度
├── config.py ← 配置层:分类体系/阈值/模板/菜单
│
├── models/ ← 数据模型层(@dataclass,不可变)
│ ├── enums.py ← 枚举:阻碍类型/归因维度/解决方向
│ ├── abandoned_attempt.py ← AbandonedAttempt 实体
│ ├── barrier.py ← Barrier 实体(外部/内心)
│ ├── solution.py ← Solution 实体
│ └── revival_plan.py ← RevivalPlan 实体
│
├── storage/ ← 持久化层(Repository 模式)
│ └── json_store.py ← CRUD + 原子写入 + 自动备份
│
├── services/ ← 业务层(6 个 Service,单一职责)
│ ├── attempt_service.py ← 尝试录入 + CRUD
│ ├── barrier_analyzer.py ← ★ 核心:内外阻碍分析引擎
│ ├── attribution_engine.py ← 归因维度标注
│ ├── solution_generator.py ← ★ 核心:解决方案生成引擎
│ ├── pattern_analyzer.py ← 模式识别 + 统计
│ └── review_service.py ← 复盘报告 + 导出
│
├── cognition/ ← 认知干预层
│ ├── blame_detector.py ← 自责语言检测
│ ├── reframing_engine.py ← 认知重构(去人格化)
│ └── value_clarifier.py ← 价值冲突识别
│
├── utils/ ← 工具层(纯函数,零业务依赖)
│ ├── cli_helper.py ← 终端交互
│ ├── text_processor.py ← 关键词提取/分类
│ ├── statistics.py ← 频次/聚类/模式检测
│ └── validator.py ← 输入校验
│
├── README.md / USAGE.md / CHEATSHEET.md
└── demo.py ← 一键跑通全流程
各层职责边界
层 能做什么 不能做什么
"main.py" 组装系统、路由菜单 不写业务逻辑
"config.py" 集中管理常量/分类/模板 不含逻辑
"models/" 数据结构、校验、序列化 不读写文件
"storage/" 读写 JSON、备份、查询 不知道数据含义
"services/" 核心业务逻辑 不直接操作文件
"cognition/" 认知干预、去自责化 不修改数据
"utils/" 纯函数工具 零业务依赖
核心模块代码展示
1️⃣ 数据模型(不可变 + 自校验)
# models/abandoned_attempt.py
@dataclass(frozen=True)
class AbandonedAttempt:
"""被遗弃的尝试 —— 不可变,防止事后篡改"""
attempt_id: str
project_name: str = ""
original_goal: str = ""
duration_days: int = 0
abandonment_reason: str = ""
resources_invested: str = ""
lessons_learned: str = ""
created_at: date = field(default_factory=date.today)
def __post_init__(self):
if not self.project_name.strip():
raise ValueError("项目名称不能为空")
if self.duration_days < 0:
raise ValueError("持续时间不能为负数")
@property
def is_long_term(self) -> bool:
return self.duration_days >= 30 # 阈值来自 config
# models/barrier.py
@dataclass(frozen=True)
class Barrier:
"""阻碍实体 —— 明确区分内外"""
barrier_id: str
barrier_type: BarrierType # EXTERNAL / INTERNAL
category: str # 资源/环境/恐惧/完美主义...
description: str
stability: Stability # 稳定/不稳定
controllability: Controllability # 可控/不可控
impact_level: int = 3 # 1-5
def to_dict(self) -> dict:
return {
"barrier_id": self.barrier_id,
"barrier_type": self.barrier_type.value,
"category": self.category,
"description": self.description,
"stability": self.stability.value,
"controllability": self.controllability.value,
"impact_level": self.impact_level,
}
设计意图:
"frozen=True" 确保历史记录不被篡改;校验集中在模型层;
"barrier_type" 强制内外分离。
2️⃣ 核心引擎:阻碍分析(内外分离)
# services/barrier_analyzer.py
class BarrierAnalyzer:
"""阻碍分析引擎 —— 强制内外因分离"""
def analyze(self, attempt: AbandonedAttempt) -> tuple[list[Barrier], list[Barrier]]:
"""
返回:(外部阻碍列表, 内部阻碍列表)
这是系统的核心分析方法。
"""
reason = attempt.abandonment_reason.lower()
external_barriers = []
internal_barriers = []
# ===== 外部阻碍检测 =====
if any(k in reason for k in ["没时间", "太忙", "时间不够"]):
external_barriers.append(Barrier(
barrier_id=f"ext_time_{attempt.attempt_id}",
barrier_type=BarrierType.EXTERNAL,
category="时间资源",
description="时间分配不足或被更高优先级占用",
stability=Stability.UNSTABLE, # 时间是可以调整的
controllability=Controllability.CONTROLLABLE,
impact_level=4,
))
if any(k in reason for k in ["没钱", "太贵", "预算"]):
external_barriers.append(Barrier(
barrier_id=f"ext_money_{attempt.attempt_id}",
barrier_type=BarrierType.EXTERNAL,
category="财务资源",
description="资金不足或优先级不匹配",
stability=Stability.STABLE, # 钱短期内难变
controllability=Controllability.PARTIALLY_CONTROLLABLE,
impact_level=4,
))
if any(k in reason for k in ["没人陪", "孤独", "不理解"]):
external_barriers.append(Barrier(
barrier_id=f"ext_support_{attempt.attempt_id}",
barrier_type=BarrierType.EXTERNAL,
category="社会支持",
description="缺乏同伴、导师或理解者",
stability=Stability.UNSTABLE,
controllability=Controllability.CONTROLLABLE,
impact_level=3,
))
# ===== 内部阻碍检测 =====
if any(k in reason for k in ["怕失败", "怕丢脸", "怕做不好"]):
internal_barriers.append(Barrier(
barrier_id=f"int_fear_{attempt.attempt_id}",
barrier_type=BarrierType.INTERNAL,
category="恐惧失败",
description="对失败结果的灾难化想象",
stability=Stability.UNSTABLE,
controllability=Controllability.CONTROLLABLE,
impact_level=4,
))
if any(k in reason for k in ["没意思", "无聊", "枯燥"]):
internal_barriers.append(Barrier(
barrier_id=f"int_interest_{attempt.attempt_id}",
barrier_type=BarrierType.INTERNAL,
category="兴趣缺失",
description="任务本身缺乏内在激励",
stability=Stability.STABLE, # 兴趣较难短期改变
controllability=Controllability.PARTIALLY_CONTROLLABLE,
impact_level=3,
))
if any(k in reason for k in ["完美主义", "不够好", "配不上"]):
internal_barriers.append(Barrier(
barrier_id=f"int_perfection_{attempt.attempt_id}",
barrier_type=BarrierType.INTERNAL,
category="完美主义",
description="用完美标准要求初期尝试",
stability=Stability.UNSTABLE,
controllability=Controllability.CONTROLLABLE,
impact_level=4,
))
return external_barriers, internal_barriers
设计意图:关键词匹配 + 归因维度标注,让每个阻碍都有"稳定/可控"属性,指导解决方案方向。
3️⃣ 解决方案生成引擎(针对性生成)
# services/solution_generator.py
class SolutionGenerator:
"""解决方案生成引擎 —— 针对阻碍类型生成具体行动"""
def generate_for_barrier(self, barrier: Barrier, attempt: AbandonedAttempt) -> list[Solution]:
"""为单个阻碍生成 2-3 个具体解决方案"""
if barrier.barrier_type == BarrierType.EXTERNAL:
return self._external_solutions(barrier, attempt)
else:
return self._internal_solutions(barrier, attempt)
def _external_solutions(self, barrier: Barrier, attempt: AbandonedAttempt) -> list[Solution]:
"""外部阻碍 → 环境改造 / 资源获取"""
solutions = []
if barrier.category == "时间资源":
solutions.append(Solution(
solution_id=f"sol_time_{barrier.barrier_id}",
title="时间块锁定法",
description="每天固定 25 分钟,雷打不动",
action_steps=[
"今晚睡前决定明天的具体时间段",
"设置手机免打扰",
"只做这一件事,不做其他",
"完成后在日历上打勾",
],
expected_outcome="建立最小可行的时间仪式感",
difficulty=3,
success_probability=0.8,
barrier_type=barrier.barrier_type,
))
elif barrier.category == "社会支持":
solutions.append(Solution(
solution_id=f"sol_support_{barrier.barrier_id}",
title="寻找 accountability partner",
description="找一个也在做类似事情的人互相监督",
action_steps=[
"列出 3 个可能感兴趣的人",
"发一条真诚的消息分享你的尝试",
"约定每周五互相汇报进度",
"不需要评价,只需要见证",
],
expected_outcome="降低孤独感,增加坚持概率",
difficulty=4,
success_probability=0.6,
barrier_type=barrier.barrier_type,
))
return solutions
def _internal_solutions(self, barrier: Barrier, attempt: AbandonedAttempt) -> list[Solution]:
"""内部阻碍 → 认知重构 / 行为拆解"""
solutions = []
if barrier.category == "完美主义":
solutions.append(Solution(
solution_id=f"sol_perfect_{barrier.barrier_id}",
title="允许烂开始原则",
description="刻意做一个明显不完美的版本",
action_steps=[
"给自己设定一个超低标准(比如写 100 字)",
"故意做一些"错误"的决定",
"完成后大声说:这就是我的烂开始",
"记录:烂开始 > 完美空白",
],
expected_outcome="打破完美主义瘫痪,启动行动循环",
difficulty=5,
success_probability=0.7,
barrier_type=barrier.barrier_type,
))
elif barrier.category == "恐惧失败":
solutions.append(Solution(
solution_id=f"sol_fear_{barrier.barrier_id}",
title="预演失败 + 去灾难化",
description="把最坏结果写下来,然后证明你能活下来",
action_steps=[
"写下你最害怕的 3 个失败场景",
"对每个场景问:一年后我还活着吗?",
"写下每个场景的实际代价(不是情绪代价)",
"做一个"就算失败也值得"的理由清单",
],
expected_outcome="恐惧从模糊威胁变成具体可管理的东西",
difficulty=4,
success_probability=0.8,
barrier_type=barrier.barrier_type,
))
return solutions
设计意图:外部阻碍优先改环境,内部阻碍优先改认知;每个方案都有具体步骤、难度、成功率,不是空话。
4️⃣ 认知干预:去自责化
# cognition/blame_detector.py
class BlameDetector:
"""自责语言检测器 —— 识别"我就是"类的人格攻击"""
def detect_blame_patterns(self, text: str) -> list[str]:
patterns = []
lower_text = text.lower()
blame_keywords = [
("我就是没毅力", "毅力是波动的,不是人格特质"),
("我总是半途而废", "你有很多坚持下来的事,只是没被注意到"),
("我天生就不是这块料", "技能是可习得的,不是天生的"),
("我又废了", "废是一个标签,不是事实"),
("我什么都做不成", "你今天呼吸、走路、吃饭都成功了"),
]
for keyword, reframe in blame_keywords:
if keyword in lower_text:
patterns.append({
"original": keyword,
"reframe": reframe,
"type": "人格化自责",
})
return patterns
# cognition/reframing_engine.py
class ReframingEngine:
"""认知重构引擎 —— 把"我失败了"重构成"我学到了"""""
def reframe_abandonment(self, attempt: AbandonedAttempt) -> list[str]:
reframes = []
if attempt.duration_days >= 30:
reframes.append(
f"你坚持了 {attempt.duration_days} 天。"
f"这证明你有启动能力和短期坚持能力,只是长期维持机制需要调整。"
)
if attempt.resources_invested:
reframes.append(
f"你投入了 {attempt.resources_invested}。"
f"这些没有消失——它们变成了你的经验资产。"
)
reframes.append(
"放弃一个不再适合的目标,不是失败,是战略调整。"
)
return reframes
5️⃣ 模式分析器(全局视角)
# services/pattern_analyzer.py
class PatternAnalyzer:
"""模式分析器 —— 从多个废弃尝试中发现共性"""
def analyze_patterns(self, attempts: list[AbandonedAttempt]) -> dict:
"""识别放弃模式"""
patterns = {
"common_barriers": self._top_barriers(attempts),
"duration_pattern": self._duration_pattern(attempts),
"domain_concentration": self._domain_concentration(attempts),
"seasonal_pattern": self._seasonal_pattern(attempts),
}
return patterns
def _duration_pattern(self, attempts: list[AbandonedAttempt]) -> str:
"""分析持续时间模式"""
if not attempts:
return "暂无数据"
durations = [a.duration_days for a in attempts]
avg_duration = sum(durations) / len(durations)
if avg_duration < 7:
return "闪电放弃型:大多数尝试在一周内结束,可能是启动门槛过高或兴趣不足"
elif avg_duration < 30:
return "短期尝试型:能坚持几周,但难以跨越第一个月门槛"
elif avg_duration < 90:
return "中期坚持型:能度过初期,但在 3 个月关口容易放弃"
else:
return "长期耕耘型:能坚持较长时间,放弃通常是因为外部环境变化"
def _domain_concentration(self, attempts: list[AbandonedAttempt]) -> dict:
"""分析领域集中度"""
domains = {}
for attempt in attempts:
# 简单关键词分类
name_lower = attempt.project_name.lower()
if any(k in name_lower for k in ["学", "书", "课", "语言"]):
domains["学习成长"] = domains.get("学习成长", 0) + 1
elif any(k in name_lower for k in ["健身", "运动", "减肥", "身体"]):
domains["身体健康"] = domains.get("身体健康", 0) + 1
# ... 更多领域
return domains
6️⃣ 入口层(依赖注入)
# main.py
class Application:
def __init__(self):
# 存储层
self.attempt_store = JSONStore(DATA_DIR/"attempts.json", BACKUP_DIR/"attempts", 20)
self.barrier_store = JSONStore(DATA_DIR/"barriers.json", BACKUP_DIR/"barriers", 20)
self.solution_store = JSONStore(DATA_DIR/"solutions.json", BACKUP_DIR/"solutions", 20)
self.plan_store = JSONStore(DATA_DIR/"plans.json", BACKUP_DIR/"plans", 20)
# 认知层
self.blame_detector = BlameDetector()
self.reframer = ReframingEngine()
self.value_clarifier = ValueClarifier()
# 业务层
self.attempt_svc = AttemptService(self.attempt_store)
self.barrier_analyzer = BarrierAnalyzer(self.barrier_store)
self.attribution_engine = AttributionEngine()
self.solution_generator = SolutionGenerator(self.solution_store)
self.pattern_analyzer = PatternAnalyzer()
self.review_svc = ReviewService(
self.attempt_store, self.barrier_store,
self.solution_store, self.plan_store
)
# CLI
self.cli = CLIHelper()
项目统计
指标 数值
Python 文件 22 个
总代码量 ~2800 行
架构层数 6 层
外部依赖 0(仅标准库)
阻碍分类 8 类(4 外部 + 4 内部)
解决方案模板 16+ 条
数据持久化 本地 JSON + 自动备份
五、README 文件
# AbandonAudit
一个 CLI 工具,做四件事:
1. 记录所有半途而废的尝试
2. 强制拆解:外部阻碍 vs 内心阻碍
3. 分别生成针对性解决方案
4. 识别模式,避免同类错误
## 安装
python 3.8+,仅标准库
## 快速开始
python demo.py # 看演示(5 个示例尝试)
python main.py # 正式使用
## 核心概念
- 外部阻碍:时间、金钱、环境、社会支持
- 内心阻碍:恐惧、价值冲突、兴趣缺失、完美主义
- 归因维度:稳定/不稳定 × 可控/不可控
## 推荐节奏
第 1 周:录入 5-10 个印象深刻的废弃尝试
第 2 周:每天看一个分析结果,选一个解决方案执行
每月:运行模式分析,看自己的"放弃指纹"
详见 USAGE.md
六、使用说明(USAGE.md 节选)
如何诚实录入:
不要写:"我学吉他放弃了"
要写:"我买了吉他,自学了 3 周,每天 20 分钟,第三周因为手指疼 + 工作加班 + 觉得进步太慢而放弃。投入了 800 元和 7 小时。"
外部阻碍 vs 内心阻碍的区别:
外部阻碍 内心阻碍
没时间 怕做不好
没钱 觉得没意思
没人陪 完美主义
环境太吵 价值冲突
解决方案怎么用:
- 外部阻碍的方案:改环境,不是改你自己
- 内心阻碍的方案:先做认知重构,再做行为实验
- 不要试图一次性解决所有阻碍——选一个可控的先动手
模式分析的用途:
如果你发现自己:
- 总是在第 3 周放弃 → 需要 21 天过渡仪式
- 总是在学习类项目放弃 → 需要即时反馈机制
- 总是在没人陪时放弃 → 需要 accountability 伙伴
七、核心知识点卡片(CHEATSHEET.md)
# 理论 工具对应
1 韦纳归因理论 内外因分离 + 稳定/可控维度
2 执行功能模型 阻碍分类映射到具体执行短板
3 自我效能感(Bandura) 小成功累积,而非宏大目标
4 认知行为疗法(CBT) 自责语言检测 + 认知重构
5 行为设计(Fogg) 外部阻碍 → 环境改造
6 完美主义瘫痪 "允许烂开始"解决方案
7 价值冲突理论 兴趣缺失 → 价值澄清
8 社会支持缓冲 孤独放弃 → 寻找伙伴
9 习惯形成机制 持续时间模式分析
10 成长型思维 放弃 = 数据收集,不是人格判决
八、总结
AbandonAudit 不是一个让你"不再半途而废"的工具,而是一个让你"不再因为半途而废而恨自己"的工具。
技术上,它展示了:
- 如何用 6 层架构 组织一个中等复杂度的 Python 项目
- 如何用 枚举 + @dataclass + 校验 保证数据质量
- 如何用 关键词匹配 + 规则引擎 实现归因分析
- 如何用 模板化 + 参数化 生成具体可执行的解决方案
- 如何用 模式识别 从多个数据点中发现个人规律
心理学上,它坚持几个原则:
不人格化——把"我是个半途而废的人"拆成"这个项目遇到了 X 和 Y 阻碍"。
不二元对立——放弃不是失败,是信息收集。
不万能化——工具能帮你看见模式,但不能替你做决定。
不替代专业帮助——严重的完美主义、恐惧、抑郁请寻求专业支持。
最终,这个工具想传达一件事:
你所有的"半途而废",都不是垃圾。
它们是你的实验数据,是你探索边界的证据,是你比昨天更了解自己的证明。
别删掉它们。审计它们。然后决定:是复活,还是体面告别。
利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!