Vibe Coding 一年实践后的冷思考 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录

独立开发者节点

愿每一位独立开发者都能保持初心,获得一个好的结果.

lmshl
V2EX    Vibe Coding

Vibe Coding 一年实践后的冷思考

  •  1
     
  •   lmshl
    mingyang91 19 天前 1956 次点击

    前言

    最近一年我在 Google/Anthropic/OpenAI 三家烧了超过 1 万美金的 token 账单。所以本文内容基于 opus4.6 、codex-5.3-xhigh 、gemini3-pro 等最强模型不限量使用所表现出来的编码能力进行评价。

    现象:Agent 的信任危机

    就好像保健品销售拿着他的《大数据量子 AI 生物磁场治疗仪》,忽悠我说这台原价 20 万、现在活动价 8 万 8 的仪器,可以彻底根治我的颈椎病腰椎病高血压糖尿病,还能逆转我的动脉血管粥样硬化、冠心病、阳痿早泄等等

    Agent 编程现在就是这么个状态。

    Agent 给我一堆 emoji 庆祝刚才生成的七八万行屎山通过了全部测试用例,告诉我可以替换生产环境了。你信吗?

    假设你是一位项目 leader ,你最靠谱的组员同事,交给他的开发任务 80% 可以在预期时间内高质量交付。这位同事拿头给你保证下周就可以上线,那么你大概率能信任他最迟下下周也搞定了。但是 agent 给你保证现在质量和完成度可以上线生产了,你信吗?

    此时此刻,无数知识星球、自媒体、AI 导师教父们正在到处收割韭菜的学费。大意基本上都是教你如何 prompt ( tool/skill 换汤不换药),然后让你多开 agent 并行干活。

    一个真实案例

    Agent 的盲目自信不仅会误导使用者,也会误导 agent 自己。

    我曾给 agent 这个任务:为当前 Kotlin 项目集成 GCP Transcoding 服务。我给了 agent 该产品的页面和文档作为参考,让它开始 plan 。Agent 做出了如下计划:

    1. 通读文档后,发现该服务仅提供了 Java SDK ,而当前项目使用的是 JVM 上的其他语言,并非原生支持
    2. 根据 RESTful 文档指示,结合文档定义字段,使用 ktor-client 进行手动接入
    3. 编写代码并执行测试

    你发现这份计划中存在的问题了吗?

    事实上,如果你曾经「古法手工编程」做过此类工作,你会发现手动实现 RESTful 远没有想象中那么简单。哪怕仅实现 Transcoding 服务的基础能力,也涉及到 5-10 个 endpoint 调用。每个 endpoint 的输入输出参数又有几十甚至上百个字段嵌套定义,agent 在应对这类长上下文任务时会频繁犯错。

    而如果 agent 选择对 Java SDK ( Google 也是从 protobuf 生成出来的)进行简单包装隔离,大概半天到一天就可以让这个功能稳定上线。

    若是让 agent 按照 RESTful 文档手动实现,agent 可能会陷入 debug 泥潭因为当 AI 幻觉导致写错了可选字段的字段名(大小写、驼峰、下划线),程序不会立即报错。你需要多久才能发现它实现错了?等上线生产后客户投诉吗?

    为什么我们无法信任 agent ? 经过一年的实践,我认为问题的根源在于:我们缺乏有效的验证手段。

    原因:验证手段的全面失效

    Code Review 失效

    常见观点:某种意义上来说 AI 并没有取代程序员,只不过是一个新的高级工具罢了。你作为生产代码的人,还是得弄明白要干啥,合入的代码就得弄明白。

    但我认为,这个在实际项目里很难做到。

    像我们之前内部 review 的时候,大部分时候 review 的是 code style ,作者讲一下设计思路,我们也就是大概一听就过了。以前这套方法是有效的:

    • 代码风格差的 PR ,设计思路也一团糟,性能也差,也没什么可扩展性
    • 代码风格好的 PR ,设计思路都挺清晰,性能考虑也周到,就算有性能瓶颈也容易改,最后扩展性也不错

    但是这个相关性在 agent 编码时代不存在,甚至相反。

    Agent 一分钟就能生成出来注释齐全、风格优秀的屎山代码。反正我肉眼看过去的时候,经常会被这第一层假象蒙蔽,放松警惕。主要是这个屎山有点难在 review 阶段发现,经常是上线后出了问题,回头细查的时候才发现是「巧克力味的屎」。

    你信我,opus 、codex-xhigh 这些你们舍不得用的模型,我开 thinking+max 模式站起来蹬,一样有这个问题。

    测试失效

    更不用说测试了。现在的 test cases 也是 AI vibe 出来的,agent 又当裁判又当运动员,它说什么就是什么。蒙我坑我也不是一次两次了。写了几千行 getter/setter 的 test case ,最后测试全绿告诉我可以上生产环境发布了。

    就像前面 GCP Transcoding 的例子,agent 写错了可选字段的字段名,测试照样能过,因为测试也是它自己写的,错的一致就是「对」的。

    与传统行业的对比

    说到这里,有人可能会问:其他行业被机械、智能赋能后,难道就没有这个问题吗?

    让我用 CNC 机床打个比方:

    CNC 机床精度比我高,但机床产出工件后,我们可以对工件进行客观的物理测量用卡尺量一下,公差是不是在 ±0.01mm 以内,一目了然。即便我没有手搓出这个精度的能力,但我依然有评价 CNC 机床和工件质量的能力。

    这就是传统制造业被机械赋能后的状态:机器精度高,质量统一且稳定,而人依然能评价机器的产出。

    那么软件开发行业被 Agent 变革后,理想状态应该是什么样的? Agent 交付的代码确实覆盖了需求,具备基本的安全防护,且更容易长期维护(哪怕仅考虑 agent 自己维护,不考虑对人类的可读性),性能更高,资源占用更少。

    但程序不仅需要完成眼下需求文档中的功能,还需要考虑到基本的安全防护。一个功能完成但安全漏洞百出的项目代码,同样是不合格的。

    而目前我们还无法评价 agent 是否达到了这个状态。单就「功能实现」这一基础要求,agent 还不能脱离人的引导和测试验证更别提安全性、可维护性、性能这些更高阶的指标了。

    而且程序不是物理工件,不能用物理手段去测量。你没法拿卡尺量一下这段代码的「质量公差」是多少。

    所以没法用衡量物理工件的标准去衡量程序,反而应该像衡量 CNC 机床本身一样而一次生产( all tests passed )远不能衡量机床质量,更不能衡量程序质量。

    CNC 机床加工塑料、铝合金小件精度高,不代表加工钛合金、不锈钢精度也能达标。后者更考验整体刚性,以及工件质量大了以后热胀冷缩对程序进刀补偿的要求。

    同理,vibe coding 出来的代码,本地点两下鼠标测试通过了,上线也是极大概率会直接炸掉。

    传统行业:机器精度高、质量稳定,人能评价。软件行业:Agent 产出快、覆盖广,但人还没法可靠地评价。这就是问题所在。

    方案:让编译器替你把关

    既然人工评价( Code Review )和自动测试都靠不住,我们需要另一种评价手段一种不依赖 agent 自己判断的、客观可验证的评价手段。

    我的观点和主流 AI 编码观点相反:

    Agent 编程时代,更需要强类型,更需要严格可验证的语言,而不是放任 agent 去写 python/js/go ,还有 anyscript 。

    为什么?

    AI 堆屎山这么快,别说生成个几万行了,就是生成超过 100 行我都已经懒得逐行去细读了。但是读类型签名、pre/post-condition 明显要快于通读逻辑代码。而这些东西只有 Rust/Scala/Haskell 甚至 formal method 能提供。

    我在 agent 编码前就一直用这种风格写自己的代码,主要是代码量大了以后,编译器检查比我肉眼检查更靠谱。现在 agent 编码流行起来了,我发现让 agent 遵循我的这个要求,更能控制产出代码质量当然也只能说一定程度上,起码比什么都不做好。

    回到 GCP Transcoding 的例子:如果 agent 用的是强类型语言,字段名写错了至少还能在编译期被类型系统拦住一部分。但 RESTful + 弱类型的组合,错了就是悄无声息地错,等你发现的时候已经晚了。

    实践效果

    y1s1 ,该夸的还是要夸。现在的最新最强模型,过编译问题不大了,除非你比我还执着于类型体操。

    放手让 agent 做工程还是拉垮的一批,但过编译已经问题不大了。Pure-FP Scala 、tagless final ,opus 4.5 和 codex-xhigh 遵循得挺不错了,过编译也是自动的。函数式类型体操的编译错误基本上都是几十上百行的类型天书,agent 读懂并修复这些编译错误,在我写这篇文章时已经不再是困难。

    局限性

    当然,这个方案也有局限。

    实际上现在的 formal method 工具链和生态还是很贫瘠,基本上只支持一门语言很有限很小的一个子集。有些工程上常用的语法/模式在 FM 那边都是 unsound ,或者尚未证明。更不用说动不动就陷入死循环/无解证明了稍不注意,z3 求解器要在比宇宙空间还大的可能性里搜索,到宇宙毁灭那一天都证明不出来。

    强类型能解决一部分问题,但不是全部。

    更深的困境:Plan 与 Execute

    即使有了强类型作为评价手段,还有一个更深层的问题:agent 对计划的理解和执行。

    GCP Transcoding 的例子其实已经暴露了这个问题:agent 选择手动实现 RESTful 而不是包装 Java SDK ,这不是代码写错了,而是路线选错了。编译器能告诉你代码有没有语法错误,但没法告诉你该不该走这条路。

    再举个更极端的例子:给 agent 一个复杂任务,研制一款火箭发动机。Plan 决定了做全流量分级燃烧循环,路线选择了共轴方案。

    Agent 不遵循的话: 可能就偏离到抽气循环也说不定。编译器能告诉你代码有没有语法错误,但没法告诉你这是不是你要的火箭发动机。

    Agent 遵循太好: 真的做出来共轴方案,那可能上线后会碰到更大的问题共轴以后动密封系统做不好,氧化剂和燃料随着涡轮轴互相泄漏,俩预燃室要炸一个。编译器能保证类型正确,但没法保证设计合理。

    现在的 plan/edit mode 切换也只是现阶段的权宜之计、无奈之举。这个问题比「评价手段缺失」更难解决,因为它涉及到对需求和设计的理解,而不仅仅是代码质量。

    初见即巅峰

    Agent 编程有一个显著的特点:初见即巅峰

    让 agent 开始一个全新的 CRUD 项目,或者一个 React 管理系统页面,agent 第一次的表现着实让所有人都大吃一惊干净利落,结构清晰,甚至还贴心地加上了注释和错误处理。

    但随着项目维护越来越久,那些「不可明说的」、没有被文档记录的、约定俗成的隐藏上下文越来越长。哪个字段其实已经废弃了但没删、哪个 API 有个历史遗留的 quirk 、哪个模块之间有个微妙的依赖关系这些东西,老员工心里都有数,但从来没人写下来。

    而 agent 无法处理无限长的上下文,只能通过压缩、总结来选择性遗忘细节。可能被丢弃的是几次失败尝试的经验,也可能被丢弃的是关键数据结构的偏移量、寄存器地址、枚举定义。

    每次新开一个 session 的时候,开发者不得不面对一个几乎全新的「员工」它似乎继承了压缩后的上下文( claude.md / agents.md ),但细节完全不知。你得重新跟它解释一遍:「不是,这个接口虽然文档上写的是这样,但实际上我们从来不传这个参数……」

    对于 CRUD 、Spring 、React 这类重复度高的任务,这似乎不是什么痛点反正每次都差不多,忘了就忘了。

    但对于嵌入式系统开发,任何被遗忘的细节都可能被 agent 天马行空的幻觉填充。寄存器地址错了?中断优先级配错了? DMA 通道冲突了?轻则系统崩溃,重则永久烧坏硬件。这不是「改个 bug 重新部署」能解决的问题。

    Agent 时代,CS 基础还要学吗?

    既然评价 agent 产出是核心问题,那开发者的基础知识就必然还是要学的。不然你拿什么去评价 agent 生成的代码、模块、架构设计质量到底如何?没有评价能力的开发者,和保健品店里待宰的老头老太没有区别。

    那么该如何学习呢?

    打开 LeetCode ,题目还没读完呢,Copilot 已经把答案补全出来了。点一下 Submit & Run ,前 1%。就这?

    我的意见是:既然有 AI 了,当然不能局限于过去的难度,得上强度,上到 AI 做不出来的程度

    放心,该学的不会落下。上了强度以后 AI 幻觉越来越多,该补的课全都得补上。期间 AI 还会给你帮不少倒忙但这恰恰是学习的机会。

    比如你要实现 Red-Black Tree 、B-Tree 、AVL Tree ,那就上点强度:给算法加上形式化验证,再把泛型支持也加上。放心,当下最强模型也写不出来。

    其实幻觉反而会帮助你学习因为幻觉里包含了常见的误解,你去验证和纠正幻觉的过程,本身就加深了学习效果。

    结语

    AI 框架、模型、工具、方法论层出不穷,日新月异。但说到底,这些都是在给模型做加法、打补丁。

    人类完成一个完整工作流的时候,不需要把自己拆解成多个「子 agent 」去协作因为人类是真的有记忆能力,且会学习的。做的时间越长,成长越多,越熟练。项目里那些隐藏的上下文、踩过的坑、约定俗成的规矩,都会沉淀成经验。

    而 agent 则相反。当前上下文越长,智力下降越明显。即便细节仍然在上下文内,agent 也开始频繁地忽略这些细节,自顾自地幻觉出一些「看起来合理」的东西来。

    核心问题始终没变:我们依然缺乏可靠的手段来评价 agent 的产出。强类型是目前我找到的最实用的部分解,但也只是部分解。

    一天不学,错过很多。一年不学,好像也没错过什么。

    框架工具更新迭代,爆款层出不穷,但其炒作因素远大于实际能力和价值。而 CS 基础知识才是久经时间考验的硬通货。与其追新框架新工具,不如把精力放在强化自己「评价 Agent 产出」的能力上这才是 agent 时代真正稀缺的东西。

    第 1 条附言    19 天前
    本文技术含量为 0 ,格局很小,纯粹从底层手艺人的视角写的。
    我本人的底线是,vibe 出来的代码起码比我古法手工编程质量更高,产出质量上不能是
    我 + agent < 我

    拿 agent 生产屎山代码我良心上过意不去
    18 条回复    2026-02-09 15:14:46 +08:00
    shoushen
        1
    shoushen  
       19 天前   1
    非常好的分享,AI 编程既是大势所趋,也存在能力边界,如何用好,需要更多的探索和实践经验!
    sillydaddy
        2
    sillydaddy  
       19 天前
    你说的这些都不是问题。

    AI 编程,最关键的区别,就在于它是可以低成本验证的。

    你提到的测试失效的问题,只要稍微想一下,它跟什么机床测量没有任何区别。软件最终是要验收结果的,它不考虑内部实现,就跟机床的验收一模一样!没有任何区别。

    想通了这点,你后面就这点的讨论就都不成立了。你说 AI 会自己编写 case ,放过自己编写的 bug ,难道你使用 2 个不同的 AI 去做,也会这样吗?
    我现在做一个项目(带有前后端),让 AI 去生成测试用例,它生成的测试用例很丰富,很详细。问题主要出在,它编码完成时,会「由于时间原因」跳过某些测试用例。(这是 AI 亲口告诉我的,由于时间原因,我想可能是迫于某些原因。)

    所以跳过测试是一个问题吗?我觉得不是。你如果让某个 Agent 实例,专门只测试 1 个测试用例,那应该完全不会有这个问题。有了测试用例,就不用担心 AI 的实现跑飞。

    然后有人会质疑,这些测试用例不会覆盖到所有情况。这里我觉得要拿你的矛来攻你的盾「如果一个工程代码,能将应用的核心用例和路径跑通,同时跑通一些极端用例,那么它出错的概率是比较小的,这就是功能的相关性。就像如果一个 AI 可以编写出最复杂的算法,就难以想象它无法编写简单的排序算法一样的道理。」
    newtype0092
        3
    newtype0092  
       19 天前   2
    我跟 OP 的感觉大差不差。

    简单的任务在不卡细节的情况下确实能快速给出一个原型,但越往后越难受。

    复杂的逻辑问题很容易绕圈子胡说八道,很像那种非常努力但实际没啥能力的队员,情绪价值给的很够但产出堪忧,只能安排一些打杂的体力活。

    有些时候提出的方案明显是错误的,虽然我能看出问题即时纠正,但是同理在生成其他我不那么专业的领域,不知道有多少这种错误被埋下,仅凭这点就很难让人信任。

    题外话
    越是在生成 AI 上踩坑,越觉得人脑太神奇了,虽然绝对的记忆力可能比不上 AI 的万分之一,但能把十几甚至几十年的常识、经历、情感、技能等海量内容组织成一个超高效率超低能耗的索引,在合适的场景里能迅速回想、识别、发散。。。从这方面看 AI 还差的很远很远。
    anguiao
        4
    anguiao  
       19 天前
    写得真的好,起码这种表达能力是我非常欠缺的
    lmshl
        5
    lmshl  
    OP
       19 天前
    @newtype0092 是的,AI 越发展我就越觉得人脑是真厉害。
    当前最强模型的智力我可以给 8-9 分,但智力正常的大学毕业生我觉得起码有 60 分,满分 100 分的话。
    herozzm
        6
    herozzm  
       19 天前
    我的实践结果是不适合 Agent (全面代理),只适合 edit (小手术)
    maolon
        7
    maolon  
       19 天前
    挺好的感想, 我最近也在做 agent 实践测试(也是烧两家最贵的模型), 目前连续不停的的跑了一周, 目标是交给他一篇论文, 在工程层面上做出效果远超过论文提供的 benchmark 的结果。
    结果是非常惊人的, 在 codex 和 cc 配合下他们确实逼近了我设定的一个目前不光论文没有实现,市面上开源的项目也都完全没有达到的 benchmark 值。
    这说明 agent 不是不能达成全自动代理也不是不能完成超长程复杂任务而是他一定要有正确设计的反馈 loop , 比如在我的场景下就是 benchmark - 反思组合, 在大多数开发场景下就是 TDD 和 SDD 的合理使用
    Midnight
        8
    Midnight  
       19 天前
    所以,我一直认为目前阶段虽然 AI 很强,但是只适合填空
    duuu
        9
    duuu  
       19 天前
    十分同意 OP 的看法,跟我得出来的结论相似。
    dji38838c
        10
    dji38838c  
       19 天前
    Vibe Coding 这个词是 2025 年 2 月被 Andrej Karpathy 发明的
    到现在还没有一年,你就已经实践了一年了,
    看来你才是发明人嘛
    lmshl
        11
    lmshl  
    OP
       19 天前   1
    @dji38838c 说得好
    lmshl
        12
    lmshl  
    OP
       19 天前
    @dji38838c 你的神说要有光,于是便有了光
    那么过去天上那个比地球大得多的核能灯泡向外辐射的是什么?一种电磁波?
    lmshl
        13
    lmshl  
    OP
       19 天前
    @dji38838c https://github.com/cline/cline/releases/tag/v1.0.4
    GitHub 上记录的第一个版本发布于 2024 年 7 月 28 日
    nightlight9
        14
    nightlight9  
       19 天前   1
    @lmshl #5

    你用 8-9 分的智力的东西帮你编程?逻辑不能自洽

    很明显你对 AI 的评分是不合理的,太自以为是了
    null05121
        15
    null05121  
       19 天前
    认真看完了,写的真不错。我说下我的启发和想法。

    AI 在 Coding 领域的能力的职责和人类是不完全重叠的,比如:人类拥有跨越超长时间的记忆能力和记忆容量,这就需要人类参与到 Coding 过程去管理上下文;有些上下文未被/不能显式记录导致 AI 缺少这个上下文,特别是那些需要主观参与的决策; AI 在信息的输入、语义理解、输出方面的速度远超人类,这也是 AI 能提高生产力的原因。
    所以 AI 并不是来完全代替程序员的,而是辅助程序员提高生产力的工具。反过来想,程序员也应该去培养一些不能被 AI 代替的技能,要是你会的技能 AI 都会,那就 GG 了。

    当然,这些观点都是基于现阶段的 AI 技术,说不定以后这个状态又会被打破。
    goodboy95
        16
    goodboy95  
       19 天前 via Android
    @dji38838c 有一说一,我 4o 出来那会就试图用它写安卓程序了(我只会写 java ,不会写安卓)
    kongkx
        17
    kongkx  
       17 天前 via iPhone
    写得不错,老哥能不能细说一下代码风格的控制啊。
    chitanda
        18
    chitanda  
       17 天前
    一次 vibe coding 有 3 个阶段,需求->编码->验证。
    新手:需求 1 ,编码 9 ,验证 0
    中手:需求 1 ,编码 6 ,验证 3
    熟手:需求 4 ,编码 1 ,验证 5
    老司机:和熟手一样,只是把验证拉到无限
    请注意,上面的数字代表人类花的时间,而不是 AI 花的时间

    需求阶段:你可以不用像古法编程那样完全理解需求,但至少要知道个大概,然后把需求扒下来做成文档,让 AI 去结合代码通读,这时候一般会超过 context ,agent 就来(/feature-dev:feature-dev 这个 skill 干这个很方便)。这个过程应该要持续几遍,特别是扒需求的时候很容易遗漏。然后生成一份 plan 文档

    编码阶段:最简单的阶段,甚至都不用开 agent ,写错也没关系,能编译就行,至于为什么往下看

    验证阶段:用需求阶段生成的文档验证 n 次,不同的 agent 人格从不同的角度去验证,编写者,阅读者,从不同端的角度沿着业务或者数据流转去检查,从后端的角度,从前端的角度,你能想到的各种角度。如果有 web 功能,那么就加上-- Chrome 去点,如果是纯服务的,部署后把账号密码给它,sshpass 上去观察。每一步都要留存文档。还有交叉验证。

    整个一生命周期,你会不断的完善 xxx.md ,xxxskills,只要你懒惰,你就会去完善这些东西

    新 context 没有记忆,这是坏事,也是好事,坏的是它没有记忆,你要不停的总结经验形成规则,试错 AI ,而不是试错代码。好的是 AI 只需要教一遍,你面对的其实不是 AI ,是你定下来规则和一整套交互的流程,一旦你达到某个程度,AI 只出很少 bug 了,恭喜你可以把时间花到摸鱼,或者更业务的工作,不过大多数人还是会花到研究 AI 上。

    验证阶段结束的标准就是,你对 AI 刚才写的东西已经烂熟于胸,不是古法代码在多少行干了什么那种,而是边界,流转,健壮,脆弱的部分在哪你全都知道。

    你问我 AI 编程为什么达不到预期,我会说你不是个总结者。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3222 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 1:27 PVG 19:27 LAX 03:27 JFK 06:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86