AI 吐代码,工程师吐槽
今天致敬我老乡唐香玉 —— 这篇是纯骂人,毫无意义!
AI 拉屎山,工程师通马桶
AI 吐千行单位的 .vue,Vue 官方开发扩展把 VS Code 搞崩了……
去他爹的 Vue 单文件组件,TSX 语法糖干翻你!
import { Vue, Component, toNative } from 'vue-facing-decorator';
import { observer } from 'mobx-vue-helper';
import counterStore from './models/Counter';
@Component
@observer
class MyMobX extends Vue {
render() {
return (
<button onClick={() => counterStore.increment()}>
Count: {counterStore.count}
</button>
);
}
}
export default toNative(MyMobX);import { observer } from 'mobx-vue-helper';
import counterStore from './models/Counter';
export const MyMobX = observer(() => (
<button onClick={() => counterStore.increment()}>
Count: {counterStore.count}
</button>
));AI 打死写不出 Nuxt.js 服务端渲染自定义 Markdown
不但 AI 反复写都是客户端渲染代码,以下官方文档的方法在 .vue 文件中不是报错就是静默失败……
去他爹的 Nuxt.js 官方文档、issue,类组件上大分~
import { Suspense } from 'vue';
import * as runtime from 'vue/jsx-runtime';
import { Component, Setup, toNative, Vue } from 'vue-facing-decorator';
import { evaluate } from '@mdx-js/mdx';
import { Link } from '../components/Link';
const evaluateMDX = (link: string) =>
defineAsyncComponent(async () => {
const { data, error } = await useFetch<string>(link);
if (error.value) throw new URIError(error.value?.message);
const { default: MDXContent } = await evaluate(data.value!, runtime);
// @ts-expect-error Upstream Type compatibility issue
return () => <MDXContent components={{ a: Link }} />;
});
@Component
class MdxDemoPage extends Vue {
@Setup(() => evaluateMDX('https://cdn.jsdelivr.net/gh/idea2app/Nuxt-MobX-Shadcn-ts/README.md'))
MDXContent?: ReturnType<typeof evaluateMDX>;
render() {
const { MDXContent } = this;
return (
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '20px' }}>
<Suspense>{MDXContent ? <MDXContent /> : <p>Loading MDX content...</p>}</Suspense>
</div>
);
}
}
export default toNative(MdxDemoPage);Vite 不支持 ES 装饰器 stage-3 候选发布标准?Parcel 来救场~
AI 能 solo?工程师擦屁股
甲方:现在 AI 代码编辑器都能 solo 了,你们有十倍效率提升了吧……
敏捷笑话永不过时:老板认为一个女人十月怀胎,用了敏捷,十个女人一月怀胎就生了!
甲方:3 天 solo 出所有前端页面,我要给客户演示……
(合同中的开发)计划赶不上(甲方的)变化……
萧山鸡排哥:做完你的做你的,做完你的做你的……
台北王世坚:本来应该从从容容、游刃有余~
台北王世坚:到现在是匆匆忙忙、连滚带爬!
AI:你一次性让我写一套页面赶工期,我就开始编……
前端页面的数量和细节复杂性让 AI 的识图遵从性很差
类人的疲态表现说明:这不是技术问题,是阶级问题!
后端识图抽字段的遵从性反而很高
当前 AI 的能与不能
- 天马行空做个新项目 —— 表现惊艳
- 既定框架下赶工期 —— 表现拉垮
- 知无不言、言无不尽的提示词 —— 尚能思考
立党哥是我嘴替!
AI 时代更需要甲方做“禁欲系”男友
克制一下拍脑袋既要又要还要也要都要全要的欲望……
我:真正容易让 solo 的不是“主流库”,而是让人和 AI 都能低代码
甲方觉得“主流”的 Shadcn UI 只会助长 AI 在我的 Git 历史记录里堆屎山
ThoughtWorks 中国 CTO:复杂需求必需图灵完备,而掌握它的只有程序员
水歌推论:好工具是服务高频用户的。
基于 MVC 和装饰性语法的数据表定义
@Entity()
export class User extends Base {
@IsString()
@Column()
name: string;
@IsEnum(Gender)
@IsOptional()
@Column({ type: 'simple-enum', enum: Gender, nullable: true })
gender?: Gender;
@IsUrl()
@IsOptional()
@Column({ nullable: true })
avatar?: string;
@IsEmail()
@IsOptional()
@Column({ nullable: true })
email?: string;
@IsMobilePhone()
@IsOptional()
@Column({ nullable: true })
mobilePhone?: string;
@IsStrongPassword()
@IsOptional()
@Column({ nullable: true, select: false })
password?: string;
@IsEnum(Role, { each: true })
@IsOptional()
@Column('simple-json')
roles: Role[];
@IsJWT()
@IsOptional()
token?: string;
}基于 service 封装增删查改
@JsonController('/template')
export class TemplateController {
service = new UserServiceWithLog<Template>(Template, ['name', 'description']);
@Post()
@Authorized()
@HttpCode(201)
@ResponseSchema(Template)
createOne(@Body() data: Template, @CurrentUser() createdBy: User) {
return this.service.createOne(data, createdBy);
}
@Get('/:id')
@OnNull(404)
@ResponseSchema(Template)
getOne(@Param('id') id: number) {
return this.service.getOne(id);
}
@Put('/:id')
@Authorized()
@ResponseSchema(Template)
updateOne(@Param('id') id: number, @Body() data: Template, @CurrentUser() updatedBy: User) {
return this.service.editOne(id, data, updatedBy);
}
@Get()
@Authorized()
@ResponseSchema(TemplateListChunk)
getList(@QueryParams() filter: TemplateFilter) {
return this.service.getList(filter);
}
}基于 MVVM 和 RESTful API 封装接口调用
import { buildURLData } from 'web-utility';
import { Filter, ListModel } from 'mobx-restful';
import { components } from '@octokit/openapi-types';
import { client } from './client';
export type Organization = components['schemas']['organization-full'];
export type Repository = components['schemas']['minimal-repository'];
export class RepositoryModel<
D extends Repository = Repository,
F extends Filter<D> = Filter<D>
> extends ListModel<D, F> {
client = client;
baseURI = 'orgs/idea2app/repos';
async loadPage(page: number, per_page: number) {
const { body } = await this.client.get<D[]>(
`${this.baseURI}?${buildURLData({ page, per_page })}`
);
const [_, organization] = this.baseURI.split('/');
const {
body: { public_repos }
} = await this.client.get<Organization>(`orgs/${organization}`);
return { pageData: body, totalCount: public_repos };
}
}
export default new RepositoryModel();import { text2color } from 'idea-react';
import { computed } from 'mobx';
import { GitRepository } from 'mobx-github';
import { observer } from 'mobx-react';
import { Column, RestTable } from 'mobx-restful-table';
import { Component } from 'react';
import { Badge, Container } from 'react-bootstrap';
import { repositoryStore } from '../model/service';
import { i18n, t } from '../model/Translation';
@observer
export class PaginationPage extends Component {
@computed
get columns(): Column<GitRepository>[] {
return [
{
key: 'full_name',
renderHead: t('repository_name'),
renderBody: ({ html_url, full_name }) => (
<a target="_blank" href={html_url} rel="noreferrer">
{full_name}
</a>
)
},
{ key: 'homepage', type: 'url', renderHead: t('home_page') },
{ key: 'language', renderHead: t('programming_language') },
{
key: 'topics',
renderHead: t('topic'),
renderBody: ({ topics }) => (
<>
{topics?.map(topic => (
<Badge
key={topic}
as="a"
className="me-2 text-decoration-none"
bg={text2color(topic, ['light'])}
target="_blank"
href={`https://github.com/topics/${topic}`}
>
{topic}
</Badge>
))}
</>
)
},
{
key: 'stargazers_count',
type: 'number',
renderHead: t('star_count')
}
];
}
render() {
return (
<Container style={{ height: '91vh' }}>
<RestTable
className="h-100 text-center"
columns={this.columns}
store={repositoryStore}
translator={i18n}
striped
hover
editable
deletable
onCheck={console.log}
/>
</Container>
);
}
}AI 新时代?工程师操碎心
以下是 2023 年初 GPT 3 发布不久后,我与某 AI 大厂中国区高管的一次聊天
AI 时代警言第一弹《雪国列车》
AI 时代警言第二弹《机械公敌》
AI 时代警言第三弹《西部世界》
AI 时代警言第四弹《终结者》
AI 时代警言第五弹《黑客帝国》
高管重复:这是第四次工业革命!他们被淘汰也没有办法~
像西部世界里未觉醒的机器人,对现实世界的照片总机械地重复:我没看出有什么问题……
人工智能的反面 —— 能治工人
我回味过来前面说的十倍效率 —— 甲方的潜台词其实是说:我可要十倍地砍工期和预算啦!
我:我月初的重感冒,在没休息好的情况下,又加重到“类新冠”症状了……
甲方 2:你每天用 20% 的精力写 AI 提示词也能赶上演示节点!
我:我就是让 AI 反反复复改联调细节代码写不好,最后还得我来擦屁股!
多少倍的效率提升我是没见着,但前些天几档的高烧我是上去了…… 下面我们先来做个小学算术题:
- 重感冒期间日均有记录的静息心率 100 ~ 120 次每分钟(实际感受上不封顶)
- 健康时静息心率平均 75 次每分钟
- 按近日很常出现的 120 次为例,心动过速 45 次每分钟
- 按医学统计,人静息心率每升高 10 ~ 15 次,体温升高 1℃
- 按 15 次 1 度保守估算,45 ÷ 15 = 3℃
- 以新冠疫情期间频繁测体温的均值 36.5℃ 为正常体温,则 36.5 + 3 = 39.5℃
- 若以 10 为单位,高烧已到 41℃(我小时候被同一体温烧昏厥过,抢救及时才没烧成脑残)
应开发提问智能 —— 能治问题
AI: step by step, please! No Mission Impossible!
我希望 AI agent 能增加质疑人类变态需求的特性,敢于提出问题,毕竟完成不可能任务的阿汤哥只有一个,还是在电影里……
我:不要解决不了问题,就解决提出问题的人!
关于前面那位女高管:
- 小八卦:我在和她同在的一个行业协会同为理事,今年我被当成提出问题的人解决了……
- 好消息:她今年被 AI 大厂裁了~
- 坏消息:她加入了一家具身智能创业公司……
时代发展、技术无罪,但要警惕 AI 幕后人的伦理
谢谢大家,我是 idea2app 的水歌!
左边是我的个人飞书,右边是我们开源社区的飞书群,欢迎扫码交流~