博客 / 詳情

返回

從懷疑到離不開:我第一個由 AI 深度參與完成的真實項目覆盤

首先説明,我不是專業的前端工程師。

但這次,我一個人完成了一個包含聊天窗口、WebSocket 實時推送、多語言翻譯、複雜 UI 狀態管理的前端項目。

説實話,如果沒有 AI,這個項目我大概率會延期,甚至放棄一些體驗上的細節。

這是我第一次,在一個真實、長期維護、並且已經上線使用的項目中,深度引入 AI 參與開發。 不是 Demo,不是練手,而是一個我必須為穩定性、性能和可維護性負責的系統。

一、前言

前端時間接了一個前端聊天+後端管理後台的項目,兩個項目都是我自己一個人完成。

説起來後端還好,但是前端html+css那套我最開始入行的時候學了一點,但是後面正式工作後主要還是圍繞後端語言來展開,前端的那套樣式語法就漸漸地放下了;

但這次是一個全新的機會,也是一個新的挑戰,需要自己寫前端。那如何快速寫前端項目,並快速交付呢?於是我想到了AI這個幫手,之前總拿它來排查問題,但是寫一個項目行不行呢? 我抱着懷疑的態度開始了這項“挑戰”,並最終“有驚無險”的落地完成,順利完成交付;

本篇文章,我想詳細的覆盤下這次經歷:如何與AI溝通? 如何合理利用AI完成代碼的實現?以及舉例一些聊天系統中實現的業務關鍵點!

在使用前,先想一下:

AI 到底能幫我們做到什麼?我們又該如何與 AI 協作,才能真的提高生產力,而不是製造技術債?

二、與AI對話

2.1 為什麼我會把 AI 真正引入一個“正經項目”?

先説結論: 不是因為“新技術”,而是因為“現實問題”。

我的真實情況

這個項目是一個 客服聊天系統,核心特點包括:

  • Laravel 後端處理接口數據
  • jQuery + Bootstrap 前端(我比較熟悉的是這套組合拳)
  • 多賬號、多好友
  • WebSocket 實時推送
  • 消息類型複雜(文本 / 圖片 / 視頻 / 語音)
  • SaaS 場景(多租户)

我面臨的真實問題是:

  • 後端我非常熟
  • 但前端交互複雜、狀態多、樣式細
  • 每一個“小交互”都很耗時間
  • 而項目又在持續迭代,不能停下來重構

👉 這時,AI 不再是“錦上添花”,而是降低邊際成本的工具


2.2 AI 開發入門:不要幻想“全自動”,要追求“人機協作”

2.2.1 AI 最適合做什麼?

在這次項目中,我給 AI 的定位非常清晰:

AI = 前端協作工程師

基於我當時的情況,我給它的定時是,輔助幫我寫前端代碼,包括但不限於以下:

  • UI 結構拆解
  • JS 事件邏輯補全
  • CSS 微調與重構
  • 複雜 DOM 操作的示例實現
  • 重複性、模式化代碼生成

結合我使用之後的感覺,我認為他可能不太適合

  • 定業務邊界
  • 定核心數據結構
  • 決定架構選型
  • 性能極限設計

這些必須由人來做。

2.2.2 心態非常重要:你不是“用 AI”,而是在“帶 AI”

如果你把 AI 當成:

  • “自動寫代碼工具”
  • “一句話生成系統”

那你一定會失望。

但如果你把 AI 當成:

  • 一個不抱怨的工程師
  • 一個願意反覆改的搭子
  • 一個可以隨時請教的助手

你會發現它非常好用


2.3 如何與 AI 溝通,才能真的把前端項目做出來?

這一節,是我整篇文章裏最想聊的部分。

2.3.1 關鍵原則一:給 AI “現有代碼”,而不是“空需求”

❌ 錯誤方式:

幫我寫一個聊天窗口

✅ 正確方式:

這是我現有的 HTML 結構 這是我的 JS 方法 這是我的業務規則 請在不破壞現有結構的前提下,實現功能 X

AI 的代碼質量,嚴重依賴上下文完整度

PS:如果你是從0開始讓AI幫你完成項目,那最好在同一個人聊天窗口下,如果切換了聊天窗口,那可能會導致以前的消息可能無法產生關聯;如果要優化,最好貼上之前的代碼!


2.3.2 關鍵原則二:需求要“具象”,不要“抽象”

比如我會這樣描述 UI:

聊天窗口頂部: 左側是頭像 + 暱稱 右側是三個點按鈕 點擊後,從“聊天窗口右側”滑出信息面板 而不是整個頁面

你會發現:我描述的是“畫面”,不是“功能名詞”。

2.3.3 關鍵原則三:有問題就“精準反饋”,不要一句否定

我在項目中經常這樣和 AI 互動:

  • “三個點按鈕沒有靠右”
  • “事件綁定不到,因為是動態元素”
  • “滑出層相對於 body 了,不是 chat-panel”

這種反饋,會讓 AI 快速修正,而不是推倒重來

2.3.4 一個我踩過的坑:AI 會“自信地寫錯”

AI不是萬能的,它也有可能出錯,你的描述詞不清晰,代碼未提供完整,就可能導致:

  • CSS 看起來對,但層級錯了
  • JS 邏輯跑得通,但狀態沒覆蓋
  • WebSocket 示例是 Demo 級,不是生產級

所以我後來形成了一個習慣:AI負責“給方案”,我負責“兜底校驗”!

三、項目功能關鍵點拆解示例

3.1 關鍵功能點一:前後端聊天消息推送

3.1.1 後端整體設計思路

我採用的是:

  • Workerman / GatewayWorker
  • 後端消息統一入庫
  • 再推送 WebSocket 給前端

核心原則是:

消息以“後端為準”,前端只是展示層

我設計的流程是,後端採用腳本監聽第三方消息服務,監聽到有消息之後推送到job,job中處理消息,代碼如下:

<?php
​
namespace App\Jobs;
​
use App\Repositories\YkAccountFriendChatRecordRepository;
use App\Repositories\YkAccountFriendRepository;
use App\Repositories\YkAccountRepository;
use App\Services\GatewayService;
use App\Services\InstagramMessageService;
use App\Services\TranslateService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
​
/**
 * 處理mqtt消息
 */
class ProcessIncomingMqttMessage implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
​
    protected $payload;
​
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(array $payload)
    {
        $this->payload = $payload;
    }
​
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            if (!$this->payload['PK']) {
                throw new \Exception('缺少PK!');
            }
            $accountKey = $this->payload['PK'];
            $account = app(YkAccountRepository::class)->firstWhere(['account_key' => $accountKey, 'status' => YkAccountRepository::STATUS_ENABLE]);
            if (empty($account)) {
                throw new \Exception("account_key:{$accountKey}對應的account數據不存在");
            }
​
            if (!is_array($this->payload['Payload']) || !count($this->payload['Payload'])) {
                throw new \Exception('payload數據異常!');
            }
            foreach ($this->payload['Payload'] as $value) {
                /**
                 * UserId 發送方id
                 * RealTimeOp 類型
                 * Text 文本類型是內容字段
                 * Media 媒體類型時字段
                 */
                if (empty($value['UserId'])) {
                    Log::info('payload中沒有UserId:'  . json_encode($value));
                    continue;
                }
​
                $friend = app(YkAccountFriendRepository::class)->firstWhere(['pks' => $value['UserId'], 'account_id' => $account['id']]);
                if (empty($friend)) {
                    Log::info("pks:{$value['UserId']}在好友表中不存在!");
                    continue;
                }
​
                $contentType = InstagramMessageService::transContentType($value);
                if (empty($contentType)) {
                    Log::warning('ProcessIncomingMqttMessage - handle 未知的消息類型' . json_encode($value));
                    continue;
                }
​
                $sendTime = transMicrosecondTimestamp($value['TimeStampUnix']);
​
                $data = [
                    'customer_id'       => $account['belong_customer_id'],
                    'account_id'        => $account['id'],
                    'friend_id'         => $friend['id'],
                    'content'           => $value['Text'] ?? null,
                    'content_type'      => $contentType,
                    'attachment'        => InstagramMessageService::getAttachment($contentType, $value),
                    'item_id'           => $value['ItemId'],
                    'send_time'         => transMicrosecondTimestamp($value['TimeStampUnix']),
                    'send_status'       => YkAccountFriendChatRecordRepository::STATUS_SUCCESS
                ];
                
                // 如果是文本類型 獲取翻譯之後的數據
                if ($contentType == YkAccountFriendChatRecordRepository::CONTENT_TYPE_TEXT) {
                    $transContent = TranslateService::getChatMessageTranslate($account['belong_customer_id'], $value['Text']);
                    if ($transContent && ($transContent != $value['Text'])) {
                        $data['is_translate'] = YkAccountFriendChatRecordRepository::CONTENT_TRANSLATE;
                        $data['content_translate'] = $transContent;
                    }
                }
​
                DB::beginTransaction();
                try {
                    $record = app(YkAccountFriendChatRecordRepository::class)->updateOrCreate(['item_id' => $data['item_id']], $data);
                    app(YkAccountFriendRepository::class)->updateLastChatTime($friend['id'], $sendTime);
                    app(YkAccountRepository::class)->updateLastChatTime($account['id'], $sendTime);
                    DB::commit();
                } catch (\Exception $e) {
                    DB::rollBack();
                    Log::info('ProcessIncomingMqttMessage handle 落庫失敗,異常原因:' . $e->getMessage());
                    continue;
                }
                $data['message_id'] = $record->id;
​
                GatewayService::pushMessageToClient($data, $friend);
                // 自動回覆消息
                dispatch(new SendAutoReplyMessageJob($record->id))->onConnection('redis')->onQueue('SendAutoReplyMessageSqs');
            }
        } catch (\Throwable $e) {
            Log::error('ProcessIncomingMqttMessage fail line:' . $e->getLine() . ' 報錯信息:' . $e->getMessage(), ['payload' => $this->payload]);
        }
    }
}

GatewayService類的pushMessageToClient方法代碼如下:

public static function pushMessageToClient($data, $friend)
{
    $gatewayHost = config('services.gateway.host', '127.0.0.1');
    $gatewayPort = config('services.gateway.port', '1238');
​
    Gateway::$registerAddress = sprintf('%s:%s', $gatewayHost, $gatewayPort);
​
    $sendData = [
        'account_id'    => $data['account_id'],
        'friend_id'     => $data['friend_id'],
        'friend_name'   => $friend['username'],
        'friend_avatar' => $friend['avatar'],
        'send_time'     => format_time($data['send_time']),
        'timestamp'     => format_time(null),
        'content'       => $data['content'],
        'attachment'    => $data['attachment'],
        'content_type'  => $data['content_type'],
        'message_id'    => $data['message_id'],
        'is_me'         => $data['is_me'] ?? false,
        'is_auto_reply' => $data['is_auto_reply'] ?? false,
    ];
​
    if (!$sendData['is_me']) {
        // 不管客服有沒有在線 先標記賬號和好友 有未讀數據(從前端去處理已讀)
        app(YkAccountFriendRepository::class)->update(['is_have_un_read_msg' => YkAccountFriendRepository::HAVE_UN_READ_MSG], $friend['id']);
        app(YkAccountRepository::class)->update(['is_have_un_read_msg' => YkAccountFriendRepository::HAVE_UN_READ_MSG], $data['account_id']);
    }
​
    // 判斷當前客服是否在線
    if (Gateway::isUidOnline($data['customer_id'])) {
        Log::info('推送到客户端信息', ['customer_id' => $data['customer_id'], 'data' => json_encode([
            'type' => 'new_message',
            'data' => $sendData
        ])]);
        // 發送消息給客服
        Gateway::sendToUid($data['customer_id'], json_encode([
            'type' => 'new_message',
            'data' => $sendData
        ]));
    } else {
        Log::info("客服id:{$data['customer_id']},未在線~", ['send_data' => $sendData]);
    }
}

這個方法多個地方都可以調用,比如:

  • 接收到消息推送到前端
  • 前端發送消息,後端推送到第三方成功,發送到前端回顯
  • 自動回覆消息成功,發送到前端回顯
  • ...

3.1.2 後端推送的數據結構

{
    "account_id": 123456,
    "friend_id": 789012,
    "friend_name": "張三",
    "friend_avatar": "https://example.com/avatar.jpg",
    "send_time": "2023-10-15 14:30:25",
    "timestamp": "2023-10-15 16:45:10",
    "content": "你好,最近怎麼樣?",
    "attachment": "image_001.jpg",
    "content_type": "text",
    "message_id": "msg_20231015143025_123456",
    "is_me": false,
    "is_auto_reply": false
}

3.1.3 前端接收消息

綁定並監聽websocket

// 綁定 WebSocket
function connectWebSocket() {
    if (!CUSTOMER_ID) {
        console.error('未設置客服ID,無法連接WebSocket');
        return;
    }
    // 清除之前的重連定時器
    if (reconnectTimer) {
        clearTimeout(reconnectTimer);
        reconnectTimer = null;
    }
​
    ws = new WebSocket(window.WEBSECKET_HOST); // 改成你的服務地址
​
    ws.onopen = function () {
        console.log('WebSocket 已連接');
        lastPongTime = Date.now(); // 連接建立時重置時間
        reconnectAttempts = 0; // 重置計數器
​
        // 綁定客服登錄用户ID
        ws.send(JSON.stringify({
            type: 'bind',
            uid: CUSTOMER_ID
        }));
        // 啓動心跳檢測
        startHeartbeatCheck();
    };
​
    ws.onmessage = function (event) {
        console.log('收到消息:', event.data);
        let msg = {};
        try {
            msg = JSON.parse(event.data);
        } catch (e) {
            console.warn('收到非法消息', event.data);
            return;
        }
​
        if (msg.type === 'ping') {
            // 服務器心跳包,更新最後活躍時間並回復pong
            lastPongTime = Date.now();
            // 服務器心跳包,回覆pong
            ws.send(JSON.stringify({type: 'pong'}));
            return;
        }
​
        if (msg.type === 'new_message') {
            console.log('收到new_message消息:', msg.data);
            handleIncomingMessage(msg.data);
        }
​
        if (msg.type === 'account_online_status') {
            const data = msg.data;
            console.log('收到account_online_status消息:', msg.data);
            updateAccountOnlineStatus(data);
        }
​
        if (msg.type === 'send_message_status') {
            console.log('收到send_message_status消息:', msg.data);
            const data = msg.data;
            // updateFriendOnlineStatus(data);
​
            updateMessageSendStatus(data)
        }
    };
​
    ws.onclose = function () {
        reconnectAttempts++;
​
        // 漸進式重連:前3次快速重連,後續採用退避策略
        const delay = reconnectAttempts <= 3 ?
            BASE_DELAY :
            Math.min(BASE_DELAY * Math.pow(1.5, reconnectAttempts - 3), MAX_DELAY);
​
        console.warn(`[第${reconnectAttempts}次重連] ${delay}ms後嘗試...`);
        setTimeout(connectWebSocket, delay);
    };
​
    ws.onerror = function (e) {
        console.error('WebSocket 發生錯誤');
        console.error('WS錯誤代碼:', e.code);
        console.error('WS錯誤原因:', e.reason);
        ws.close();
    };
}
​
/**
 * 新消息處理
 * @param msg
 */
function handleIncomingMessage(msg) {
    console.log('handleIncomingMessage', msg);
    const currentAccountId = state.currentAccountId;
    const currentFriendId = state.currentFriendId;
​
    if (msg.account_id === currentAccountId) {
        if (msg.friend_id === currentFriendId) {
            // 當前聊天窗口好友,追加消息
            appendMessage({
                me: msg.is_me || false,
                auto_reply: msg.is_auto_reply || false,
                name: msg.friend_name,
                avatar: msg.friend_avatar,
                timestamp: msg.timestamp,
                send_time: msg.send_time,
                content: msg.content,
                attachment: msg.attachment,
                id: msg.message_id,
                type: getContentType(msg.content_type)
            });
            // 如果當前消息是當前聊天好友的,標記好友狀態為已讀
            setFriendUnReadStatus(msg.friend_id, 0);
            translateVisibleMessages($('select[name="input_target_lang"]').val(), 'left');
        } else {
            // 當前賬號的其他好友,標紅點
            markFriendUnreadDot(msg.friend_id, msg.account_id);
        }
    } else {
        // 非當前賬號,賬號頭像標紅點
        markAccountUnreadDot(msg.account_id);
    }
}

這個這段邏輯主要包括:

  • 當前聊天窗口實時追加消息
  • 非當前好友 → 好友紅點
  • 非當前賬號 → 賬號紅點

這裏之所以要在前端判斷account\_id /friend\_id,而不是後端分多鐘類型推是因為:

  • 降低後端推送負責度,而且我覺得在前端判斷會更好
  • 保證前端狀態一致性
  • 方便後續擴展更多UI狀態

3.2 關鍵功能點二:中英文切換與“批量翻譯”的實現思路

這是一個讓我非常滿意、也非常適合 AI 協作的功能。

3.2.1 我的需求不是“翻譯一條消息”

而是:

  • 聊天窗口已有歷史消息
  • 切換語言後
  • 原文不變
  • 原文下方顯示譯文
  • 支持再次切換目標語言

3.2.2 前端結構設計(AI 協助)

<div class="chat-message-bubble">
    <div class="original-text">Hello</div>
    <div class="translated-text text-muted small">你好</div>
</div>

AI 在這裏給了我一個很重要的建議:

翻譯內容不要覆蓋原文,而是“附加”

如果一開始就讓 AI 覆蓋原文,後期做多語言切換、撤銷翻譯、重新翻譯,都會非常痛苦。這讓體驗和可維護性都好很多。

3.2.3 切換語言時的 JS 邏輯

// Tab 切換事件
$("#collapseTranslate").on('change', '.translate-select', function () {
    let name = $(this).attr('name');
    let value;
    if (name === 'chat_message_auto_translate' || name === 'input_auto_translate') {
        const isChecked = $(this).is(':checked');
        value = isChecked ? 1 : 0;
    } else {
        value = $(this).val();
    }
​
    if (name === 'input_target_lang') {
        translateVisibleMessages(value);
    }
​
    if (name === 'chat_message_target_lang') {
        translateVisibleMessages(value, 'left');
    }
​
    $.post('/chat/change_translate_config', {
        name: name,
        value: value
    }, function (res) {
        if (res.code !== 0) {
            layer.msg(res.msg)
        }
    });
});
​
/**
 * 聊天框內容翻譯
 * @param targetLang
 * @param trans_message_type
 */
function translateVisibleMessages(targetLang = 'en', trans_message_type = 'right') {
    const messagesToTranslate = [];
    const selector = '.chat-message-wrapper.chat-message-' + trans_message_type;
    console.log('selector', selector); // 輸出拼接的選擇器
    console.log('匹配到元素數量:', $(selector).length);
    $(selector).each(function () {
        const $wrapper = $(this);
        const messageId = $wrapper.data('id');
​
        const $bubble = $wrapper.find('.chat-message-bubble');
        const content = $wrapper.find('.chat-message-bubble .original-text').text().trim();
        const cacheKey = `${messageId}_${targetLang}`;
​
        if (!messageId || !content) return;
​
        // 若已緩存則直接渲染
        if (translationCache[cacheKey]) {
            applyTranslatedMessage(messageId, translationCache[cacheKey]);
        } else {
            // 顯示 loading 佔位
            insertLoadingPlaceholder($bubble);
​
            // 準備發送的內容
            messagesToTranslate.push({ message_id: messageId, content });
        }
    });
​
    console.log('messagesToTranslate', messagesToTranslate);
    if (messagesToTranslate.length === 0) return;
​
    $.ajax({
        url: '/chat/translate/batch',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            messages: messagesToTranslate,
            target_lang: targetLang
        }),
        success: function (res) {
            if (res.code === 0 && Array.isArray(res.data)) {
                res.data.forEach(item => {
                    const cacheKey = `${item.message_id}_${targetLang}`;
                    translationCache[cacheKey] = item.translate;
                    applyTranslatedMessage(item.message_id, item.translate);
                });
            }
        }
    });
}
​
/**
 * 翻譯內容顯示
 * @param messageId
 * @param translation
 */
function applyTranslatedMessage(messageId, translation) {
    const $wrapper = $(`.chat-message-wrapper[data-id="${messageId}"]`);
    const $bubble = $wrapper.find('.chat-message-bubble');
​
    const $translated = $bubble.find('.translated-text');
    if ($translated.length) {
        $translated.text(translation);
    } else {
        $bubble.append(`
            <div class="divider"></div>
            <div class="translated-text text-muted small">${translation}</div>
        `);
    }
}

這段代碼是 AI 在我給出 DOM 結構後幫我補全的。


3.3 關鍵功能點三:複雜 UI 交互(微信式體驗)如何落地?

比如:

  • 消息氣泡寬度
  • 時間顯示位置
  • 自己 / 對方對齊方式
  • 動態按鈕事件綁定

3.3.1 動態元素事件綁定問題

我一開始寫的是:

$('#toggle-friend-info').on('click', ...)

AI 很快指出問題:

這是動態生成的 DOM,需要事件委託

修正後:

$(document).on('click', '#toggle-friend-info', function () {
    $('#friend-info-panel').toggleClass('show');
});

這是一個非常典型的“AI 幫你查漏補缺”場景


3.3.2 滑出面板相對聊天窗口,而不是頁面

AI 在我反饋問題後,幫我調整為:

.chat-panel {
    position: relative;
    overflow: hidden;
}
.friend-info-panel {
    position: absolute;
    right: -260px;
    transition: right .3s;
}
.friend-info-panel.show {
    right: 0;
}

3.3.3 發送消息、接收消息左右分隔

.chat-message-wrapper {
    display: flex;
    align-items: flex-start;
    margin-bottom: 12px;
    width: 100%;
}
​
.chat-message-left {
    flex-direction: row;
}
​
.chat-message-right {
    flex-direction: row-reverse;
}
​
.message-block {
    display: inline-flex;
    flex-direction: column;
    max-width: 75%;   /* 讓消息區最大佔75%寬 */
    word-wrap: break-word;
}
​
/* 自己發的消息(右側) */
.chat-message-right .message-block {
    display: flex;
    flex-direction: column;
    align-items: flex-end; /* 時間右對齊 */
}
​
/* 對方的消息(左側) */
.chat-message-left .message-block {
    display: flex;
    flex-direction: column;
    align-items: flex-start; /* 時間左對齊 */
}
​
.chat-message-bubble {
    max-width: 95%;
    padding: 10px 14px;
    border-radius: 16px;
    word-wrap: break-word;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    line-height: 1.5;
}

以上這些,基本上都是AI幫我完成調優的。


除了以上幾個功能點之外,我還實現了

  1. 退出登錄聊天窗記憶功能:退出登錄,記錄上次聊天的對象,再次登錄後自動打開最後一次聊天對象所在的分組、tab、聊天窗口、聊天記錄
  2. 多語言切換:通過配置切換當前要展示的語言
  3. 快捷回覆:添加(文本、圖片、視頻、語音)、刪除、快捷發送
  4. 自動回覆:接收到消息自動回覆
  5. 翻譯配置:支持發送出去的消息和接收到的消息,可以分別配置源語言、翻譯為目標語言。比如發出去的是中文,實際對方接收到的是英文;接收到的是英文、韓文,聊天窗顯示中文
  6. 未讀分組、tab、好友紅點標記等

太多了,具體細節就不一一介紹了,光聊天一個窗口交互就複雜的一批(感覺要錢要少了,orz...

四、效果展示

登錄

image-20251223114030780.png

聊天首頁

image-20251223114119055.png

翻譯配置

image-20251223114155843.png

自動回覆配置

image-20251223114232951.png

五、總結

5.1 AI寫代碼的優缺點

基於我這次和AI對話的實戰來看,優點是非常明顯的

  • 前端效率提升巨大
  • UI 微調不再痛苦
  • 可以快速試錯
  • 非前端工程師也能做出“像樣界面”

但是缺點也很明顯

  • 不會主動考慮性能極限
  • 容易“寫得能用,但不夠優雅”
  • 架構必須你來定
  • 需要你具備基本判斷能力

5.2 其他

AI的使用遠不限於此,如果你願意學習如何使用:

  • 描述需求
  • 提供上下文
  • 精準反饋
  • 與 AI 協作

你會發現:一個人,可以完成過去一個小團隊才能完成的事情。

六、寫到最後

對我來説,AI 並不是讓我“變成前端工程師”,而是讓我在有限時間內,把一個本來可能妥協的項目,做到自己滿意為止

從某些方面來説,AI讓我變的更高效,從之前排查問題靠百度、靠在社區提問,到現在有問題問AI,AI的準確率還不錯;從之前靠自己經驗寫出一段邏輯代碼,到現在請AI幫我優化,大大提高了我代碼的質量;AI是個好東西,咱們程序員還是要擅於利用它,這樣才有更多的時間“摸魚"(提高自己)啊

你有沒有用 AI 真正寫過項目呢?歡迎評論聊聊。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.