ponytail爆火背后:为什么AI Agent写的代码总是太啰嗦?

ponytail爆火背后:为什么AI Agent写的代码总是太啰嗦?

一个Skill让Claude Code少写54%的代码,GitHub 53K星。开发者苦AI冗余代码久矣。

一个现象

如果你用过AI写代码,应该见过这种输出:

def get_user(user_id: int) -> User | None:
    """
    Retrieve a user from the database by their unique identifier.
    
    Args:
        user_id: The unique identifier of the user to retrieve.
        
    Returns:
        The User object if found, None otherwise.
        
    Raises:
        DatabaseError: If there is an error connecting to the database.
    """
    try:
        session = SessionLocal()
        user = session.query(User).filter(User.id == user_id).first()
        session.close()
        return user
    except Exception as e:
        logger.error(f"Failed to retrieve user {user_id}: {e}")
        raise DatabaseError(f"Database error: {e}")

有经验的开发者一眼就能看出问题:这段代码做了太多不该做的事。

AI生成了什么:

  • docstring写了4行

  • 异常处理覆盖了数据库错误

  • 手动管理session生命周期

  • 日志记录

  • 自定义异常包装

实际要什么:

  • 一个简单的查询函数

  • 项目里其他地方怎么写的,这里就怎么写

多余代码是AI的安全策略——它宁可多写,也不敢漏写。但这就是AI代码和人类代码之间的核心矛盾。

ponytail的技术思路

ponytail是一个Skill文件,安装到Claude Code后自动生效。它的核心是改变AI生成代码时的判断标准。

安装方式:

npm install @dietrichgebert/ponytail

或者手动安装Skill:

curl -o ~/.claude/skills/ponytail.md https://raw.githubusercontent.com/DietrichGebert/ponytail/main/ponytail.md

核心规则

ponytail的规则文件只有不到200行,核心规则可以概括为几条:

不写不需要的代码: 不添加当前任务不需要的依赖、工具函数、配置项。一个函数里不需要的import不写。

不写防御性代码: 如果参数类型已经通过TypeScript或Pydantic校验,函数内部不需要再重复校验。如果数据库层已经处理了异常,上层不需要再包一层try-except。

优先用现有的: 项目里有现成的工具函数、装饰器、中间件,优先复用而不是自己写。检查现有代码的模式,保持一致。

减少注释: 函数名和参数类型能表达清楚逻辑时,不写docstring。不写显而易见的注释。

效果数据

根据ponytail作者在12个任务上的测试(Haiku 4.5,n=4):

指标普通Agent加ponytail变化
代码量基准-54%减少一半以上
token消耗基准-20%节省费用
执行时间基准-27%速度提升
安全性基准不变不影响安全
功能正确性基准不变功能不受影响

极端情况下(生成日期选择器这类简单组件),代码量减少达到94%。

为什么普通Agent会写多余代码

理解ponytail的效果,需要先理解AI生成冗余代码的原因。

原因1:安全策略

LLM的训练数据中,带完整异常处理、日志记录、参数校验的代码被认为是“好代码”。模型被训练成倾向于多写而不是少写,因为多写的风险低于少写。

从LLM的角度看:生成一段完整但冗余的代码,用户最多说“啰嗦”;生成一段缺少异常处理的代码,用户会说“有Bug”。

原因2:没有项目上下文

Agent不知道当前项目中其他代码是怎么写的。没有参照系,它只能按通用的“最佳实践”来写,而通用的最佳实践往往是冗余的。

同一个项目里,所有CRUD函数都用了同一个装饰器处理异常,但Agent不知道这个约定,所以每个函数都自己写try-catch。

原因3:指令模糊

用户说“写一个用户查询接口”,Agent的理解是“实现一个完整的查询功能”,而不是“按项目现有模式写一个查询接口”。

解决思路:不是少写,是写对的

ponytail的做法不是简单粗暴地让AI“少写代码”,而是改变AI的判断标准。

思路1:用项目模式替代通用模式

普通Agent的生成逻辑:

看到“写一个查询函数”
→ 调用通用模板(try-catch + 日志 + docstring)
→ 输出冗余代码

ponytail的生成逻辑:

看到“写一个查询函数”
→ 检查项目里其他查询函数怎么写
→ 发现项目里用了装饰器处理异常
→ 按项目模式生成
→ 输出精简代码

思路2:优先级排序

ponytail的prompt里给Agent设定了代码生成的优先级:

  1. 功能正确 — 代码必须能工作

  2. 一致性 — 和项目现有代码风格一致

  3. 必要性 — 每行代码都有理由存在

  4. 可读性 — 代码本身表达意图,注释是补充

很多Agent把“可读性”放在“必要性”前面,导致docstring和注释比逻辑代码还多。

思路3:明确什么是不需要的

普通Agent需要被告知“要做什么”,ponytail额外告诉Agent“不做什么”:

  • 不需要手动管理session(项目已有中间件处理)

  • 不需要重复写类型校验(Pydantic已经处理)

  • 不需要写显而易见的注释(get_user_by_id不需要注释说是查询用户的)

  • 不需要处理当前任务范围外的异常

实际效果对比

安装ponytail前后的同一个需求

需求:“给用户模型加一个update_last_login方法”

安装前:

def update_last_login(self, user_id: int) -> User:
    """
    Update the last login timestamp for a user.
    
    Args:
        user_id: The ID of the user whose login time to update.
        
    Returns:
        The updated User object.
        
    Raises:
        ValueError: If user_id is invalid.
        DatabaseError: If the database operation fails.
    """
    if not isinstance(user_id, int) or user_id <= 0:
        raise ValueError("Invalid user_id")
    
    try:
        user = self.session.query(User).filter(User.id == user_id).first()
        if not user:
            raise ValueError(f"User {user_id} not found")
        
        user.last_login = datetime.utcnow()
        self.session.commit()
        self.session.refresh(user)
        return user
    except SQLAlchemyError as e:
        self.session.rollback()
        raise DatabaseError(f"Failed to update login: {e}")

安装后:

def update_last_login(self, user_id: int) -> User:
    user = self.session.get(User, user_id)
    user.last_login = datetime.utcnow()
    self.session.commit()
    return user

差异:前者65行,后者7行。功能等价。

成本变化

假设一个项目每天生成100个函数:

指标安装前安装后节省
每个函数平均token35016054%
每日token消耗35K16K19K
月token消耗1.05M0.48M0.57M
月费用(按$5/M计算)$5.25$2.40$2.85

对于大规模使用AI编程的团队,这个节省是实际的成本优化。

局限

ponytail对简单到中等复杂度的代码效果最好。对于复杂业务逻辑、安全敏感代码、需要详细注释给新人看的项目,过度精简可能会降低可读性。

另外,ponytail的效果依赖项目本身的代码质量。如果项目现有代码风格不统一或质量不高,Agent按“项目现有模式”生成的结果也可能不好。

总结

  • ponytail(⭐53K)让Agent代码量平均减少54%,token消耗减少20%,执行时间减少27%

  • AI生成冗余代码的原因是安全策略、缺乏项目上下文、指令模糊

  • 不是简单让AI少写代码,而是让AI按项目现有模式写代码

  • 对中等复杂度代码效果最好,复杂场景需要权衡精简和可读性

  • 安装只需一行命令,可以按项目决定是否启用


2026年6月 | Vincent #ponytail #Agent #AI编程 #代码精简 #ClaudeCode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值