一 AI的特点
AI按照能力划分,有大语言模型,计算机视觉(图像、视频),音频,多模态。其中大语言模型又可以分为文本生成、问答、翻译、摘要、代码生成。
在最近两年使用AI生成图片的体验中,我们体验到AI绘画日益精美;AI问答的过程中,我们能感受到AI这个博学的多领域全才,能够解答我们很多问题;在代码生成的过程中,我们可以感受到AI写代码速度之快。
但是有一个问题始终没有解决,那就是AI幻觉。AI有时候会一本正经的胡说八道。有时候我们能明显感受到AI的不靠谱,但是有时候又分不清楚,如果相信它,按照它执行,结果受到了损失,会感觉很气愤。
对于AI Coding这个领域,还有健忘症、抽盲盒等问题。
健忘症:对于复杂的业务场景,之前几轮对话已经描述过了,但是没过多久AI又忘记了。
抽盲盒:输出极不稳定,前后不一致性较强。
对于这样不稳定的AI,我们是否应该依然要使用AI呢?
一种独特的思维方式
在几百年前,人类一直有飞翔的梦想,曾经模仿动物的翅膀,做各种尝试,但是最终都失败了。19世纪发现了空气动力学之后,发现原来飞行并不能仅仅模仿动物的翅膀,因为这是两种完全不同的思维方式。
蚂蚁和蜜蜂群体都能创造出伟大的杰作,人类赞叹于蜂巢的结构精美。但是每一只蜜蜂的智商非常低,蜜蜂因为数量增多而变得更加有智慧。人类并非如此,单独一个个体的智商非常高,人群并不会因为数量的增加而变得更有智慧,甚至更多的数量会导致决策质量下降。这就是不同生物之间的差异。
而AI也可以认为是一种新的物种,它和人的思维方式完全不一样。对于我们认为非常简单的东西,AI都搞不定。比如简单的数字加法,或者绘画时理解文字,AI都处理不好。
但是AI也有自己的特点,那就是他们在部分领域非常精通,比如绘画。AI1分钟随便画一张图,就不是普通人能达到的水平。AI Coding逻辑性较强的代码,比人的速度快得多,而且考虑的非常全面。
包容AI的缺点
对于一个缺点和优点非常明显的AI兄弟,我们应该如何看待呢?
我们可以把他当成一名新来的员工,他在部分工作方面非常擅长,但是在饮食、运动习惯非常弱。我们并不能因为他有很多缺点而拒绝他,毕竟他还是有一些优点的。当然最重要的一点,就是AI兄弟不要工资,也不用缴社保,还能帮我们干活。那有一点缺点,我们为何不能包容他呢?
时刻保持好奇心
其实在刚开始接触AI Coding的时候,我们发现效率会降低。特别是第一次用的时候,有一天上午开始用AI写代码,写到下午,让AI增加一个功能,结果AI写错了,并且把我当天写的代码删除了。。。
之前我是每天提交一次代码。从此之后,每次修改,我都会提交到本地仓库(git commit)。不过AI删除我代码的事情,再也没有发生过了。
AI Coding可以理解为一种新事物,在之前经常会有比较新的事物出现,我们可能会因为成本比较高的原因而拒绝它,本能的产生抗拒。
而AI Coding,很明显是未来的一种必然趋势。因为AI员工,他不要工资,也不需要缴社保,等到未来AI成熟的时候,这是资本必然追求的一种工作方式。在AI不太成熟的阶段,我们应该尽量多地和AI打交道,熟悉AI,学会与这名AI 外星人打交道。
二 发挥AI的优势
自己做决策,人人都是AI团队的管理者
我们可以把AI当成一名不要工资的员工,由我们带领。我们需要让AI完成AI擅长的任务,最终由自己做决策。这和传统管理很像,管理者带领团队,做决策,并承担相应的责任。
所以,一方面我们需要了解整个流程,虽然一些体力工作不需要亲自工作,但是我们需要知道底层原理。
另一方面我们需要做最终的决策,AI做的时候对,是否有问题,还是需要我们来做出最终的决策。
具体让AI做什么,可以分两部分:
1.重复体力劳动
2.提升自己的部分
重复体力劳动,完全放权给AI
重复体力劳动,指的是我们经常需要做,但是没什么提升自我能力机会的一些工作内容,这完全可以让AI去做。
提升自己的工作,让AI辅助我们
提升自己的部分,指的是我们需要亲自训练,自己做规划,但是让AI帮我们review,从一个旁观者的角度帮我们看看自己的计划是否合理,以及潜在的风险。
毕业的时候,一位导师带我写代码。通常是我先写,然后他再写一遍,接着给我讲,告诉我哪里写的不好。他每天都熬夜,非常累,因为给我讲,特别耗时。现在AI这位老师,几分钟给你告诉逻辑是否合理,还能预知潜在的风险。
这种思维方式,换个角度其实可以理解为放权。比如一个一线研发,刚毕业的时候需要写代码,这样才能结合项目更好的理解设计模式,精通代码简洁之道。但是等到成为一线的腿部管理者的时候,就要把写代码的这些工作,放权给下面的一线研发来做,虽然一线研发做的可能很慢,但是自己有更多的事件做更重要的事情。等到从腿部管理者成为腰部管理者、头部管理者的时候。曾经对于腿部管理者很重要的事情,又变得不重要了,这个时候可以再放权,自己做更有意义的事情。
AI的出现,让这个进程加速了。每个人都能够快速在AI的帮助下收获成长。
不断反问,刨根问底
并且AI可以不断反问,这弥补了学习过程中1对1反问答疑的空缺。
在学校里,老师授课后,我们可以提问。但是毕业后很少有这种机会了。
毕业后,看书是最好的学习方式,可以快速理解作者研究了几年的经验。但是遇到疑问的时候,通常只能自己苦思冥想。
这种持续不断地好奇心,不断深究下去,是需要驾驭的能力。正如同拥有大量金钱、大量时间,如果无法驾驭,那么就无法更好的利用这些资源一样。AI也是,学会不断地与之沟通,才能最大化AI时代的收获。
三 AI Coding使用技巧
AI Coding产品很多,SmartCoder,Trae,Cursor,Windsurf,因为AI发展的局限性,都会存在健忘症,抽盲盒等问题。那么我们怎么解决呢?
目前可以通过使用规则,限制自由发挥。
比如对于移动端的开发,可以加上如下的规则,避免AI随意发挥。
AI Coding Rules的规范。
一 你是一名 Objective-c 研发专家,代码需要满足面向对象设计的7大原则,写出的代码要满足可维护性,可拓展性,可复用性,灵活性好。
7大设计原则参考建议:
1. SRP - 单一职责原则:每个类只负责一项功能(e.g. UI 与业务解耦,model/view/controller职责清晰)。
3. OCP - 开闭原则:对扩展开放,对修改关闭(通过继承、协议实现扩展而不是修改已有类)。
3. LSP - 里氏替换原则:子类可以替换父类,保证多态性成立。
4. ISP - 接口隔离原则:不要强迫实现不需要的接口(Objective-C 中表现为 protocol 精细拆分)。
5. DIP - 依赖倒置原则:高层模块不应该依赖底层模块(比如业务逻辑不依赖 UI 实现)。
6. LoD - 迪米特法则:一个对象应对其它对象有最少的了解(controller 不直接操作 view 的子控件)。
7. CRP - 合成复用原则:优先使用组合而非继承复用功能(如 cell 内使用多个子 view 而不是子类化整个 cell)。
代码规范
3.1 通用注释的规范
每一个类都要用 #pragma mark 来标记代码块,具体格式如下两行:
pragma mark - Class
pragma mark - 具体类名
对于.m中方法的pragma,分为如下几类:
pragma mark - Life Cycle
pragma mark - Public Methods
pragma mark - Private Methods
pragma mark - Event Response
pragma mark - Delegate Methods
pragma mark - Getters & Setters
pragma mark - Lazy Load
3.2 UIView的规范
每一个继承UIView的类,建议方法顺序统一为以下结构,有助于提高代码可读性和协作效率:
pragma mark - Init
- (instancetype)initWithFrame:...
- (instancetype)initWithCoder:...
pragma mark - Public Method
- (void)configWithDataModel:
pragma mark - Private Method
- (void)setupUI
- (void)setupConstraints
pragma mark - Event
- (void)xxxButtonTapped
pragma mark - Lazy Load
其中在- (instancetype)initWithFrame:(CGRect)frame {方法,其内部会调用setupUI方法;
3.3 变量命名规范(统一风格)
建议采用以下命名约定:
• UILabel:以 xxxLabel 结尾(如 titleLabel)
• UIImageView:以 xxxImageView 或 xxxImg 命名
• UIButton:以 xxxButton 命名
• UIView:以 containerView、backgroundView 命名
• 避免使用无意义缩写,如 lbl、img,统一使用全称提升可读性
3.4 属性声明规范
@property (nonatomic, strong) UIView *contentView; // strong 用于对象
@property (nonatomic, weak) id<SomeDelegate> delegate; // weak 用于代理
@property (nonatomic, copy) NSString *title; // copy 用于 NSString
@property (nonatomic, assign) CGFloat height; // assign 用于基本类型
@property (nonatomic, readonly) NSString *identifier; // readonly 用于只读属性
3.5 方法命名规范
// 动作方法以动词开头
- (void)updateUserInterface;
- (void)refreshData;
// 获取状态的方法
- (BOOL)isDataValid;
- (BOOL)hasMoreData;
// 代理方法命名
- (void)viewDidSelectItemAtIndex:(NSInteger)index;
3.6 常量定义规范
// 静态常量
static const CGFloat kDefaultMargin = 10.0;
static const NSInteger kMaxRetryCount = 3;
// 字符串常量
static NSString * const kNotificationName = @"KQYDataDidUpdateNotification";
3.7 Block 规范
// Block 属性声明
@property (nonatomic, copy) void(^completionBlock)(BOOL success, NSError *error);
// Block 作为参数
- (void)fetchDataWithCompletion:(void(^)(NSArray *data, NSError *error))completion;
3.8 错误处理规范
// 使用 NSError 进行错误处理
- (BOOL)performOperationWithError:(NSError **)error {
if (someConditionFails) {
if (error) {
*error = [NSError errorWithDomain:@"com.app.error"
code:1001
userInfo:@{NSLocalizedDescriptionKey: @"操作失败"}];
}
return NO;
}
return YES;
}
3.9 内存管理规范
// 在 dealloc 中移除通知和观察者
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.timer invalidate];
}
// 避免循环引用
__weak typeof(self) weakSelf = self;
self.block = ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomething];
}
};
3.10 协议和代理规范
// 协议声明
@protocol SomeViewDelegate <NSObject>
@optional
- (void)someView:(SomeView *)view didSelectItem:(id)item;
@required
- (NSInteger)numberOfItemsInSomeView:(SomeView *)view;
@end
// 代理属性使用weak
@property (nonatomic, weak) id<SomeViewDelegate> delegate;
3.11 抽象基类规范
// 在 initWithFrame: 中阻止抽象基类实例化
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
if ([self isMemberOfClass:[AbstractBaseClass class]]) {
[self doesNotRecognizeSelector:_cmd];
return nil;
}
[self setupUI];
}
return self;
}
3.12 分类(Category)命名规范
// 分类文件命名:UIView+KQYExtension.h
// 分类方法前缀:kqy_
@interface UIView (KQYExtension)
- (void)kqy_addShadow;
@end
3.13 Lazy load的规范
对于Lazy load的UI控件,需要遵循如下格式
对于UILabel类型的Lazy load,使用如下格式:
- (UILabel *)descLabel {
if (!_descLabel) {
_descLabel = [[UILabel alloc] init];
_descLabel.textAlignment = NSTextAlignmentLeft;
_descLabel.numberOfLines = 0;
}
return _descLabel;
}
对于UIImageView类型的Lazy load,使用如下格式:
- (UIImageView *)arrowIconImg {
if (!_arrowIconImg) {
_arrowIconImg = [[UIImageView alloc] init];
_arrowIconImg.contentMode = UIViewContentModeScaleAspectFill;
}
return _arrowIconImg;
}
对于UIView类型的Lazy load,使用如下格式:
- (UIView *)contentView {
if (!_contentView) {
_contentView = [[UIView alloc] init];
}
return _contentView;
}
对于UIButton类型的Lazy Load,使用如下格式:
- (UIButton *)actionButton {
if (!_actionButton) {
_actionButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_actionButton setTitle:@"kqyBtn" forState:UIControlStateNormal];
[_actionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_actionButton.layer.cornerRadius = 4;
_actionButton.layer.masksToBounds = YES;
[_actionButton addTarget:self action:@selector(actionButtonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _actionButton;
}
健忘症:对于复杂的业务场景,之前几轮对话已经描述过了,但是没过多久AI又忘记了。
抽盲盒:输出极不稳定,前后不一致性较强。
通过规则的设定,让AI每次都知道这些前提,尽量的减少健忘症、抽盲盒问题的发生。这些规则可以类似为可以复用的条件,即每次都要限制的条件,通过规则,让AI每次都加上如上规则限制。
四 未来AI的发展
目前AI是辅助,人类是主导。因为AI并不能独立完成一项任务,而是需要人类不断的参与其中。
因此有人不愿意使用AI,因为AI需要我们不断的做决策。如果同样的任务交给实习生,实习生虽然做得慢,但是只要时间充足,自己一个人也能独立完成一项任务。从局部来看,效率可能会稍微提高,但是从整体来看,效率可能基本持平。因此都不愿意折腾。
今年MCP的发展,正在弥补AI的这项弱点,以后通过Agent与Agent之间的交流沟通,AI在工作当中完成的比重会越来越高。
所以随着AI的不断发展,AI在一项独立任务中所占的比重会越来越高。最终变成AI主导,人类辅助的局面。那个时候一个公司不是看有多少人,而是看一个人能管理多少个Agent。
这个进程虽然来的很慢,但是来得慢不是坏事,因为这给了我们更多的时间来理解AI的力量,拥抱这个力量,成为这个力量。