2026年3月9日 星期一

使用 Codex 指定專案範本來創建一個全新的專案

使用 Codex 指定專案範本來創建一個全新的專案

最近正在使用 Codex 將之前做出的一個 .NET 8 Blazor 專案,改寫成為 .NET 10 的版本,其中將會從原先使用的 Syncfusion 元件,改寫成為使用 Ant Design 元件,並且該專案預設具有各種未來專案需要開發的設計模型、Web API、使用者與角色的 CRUD、授權與認證等需求的功能,在未來面對到新的專案需求時,一些基礎架構與設計模式都已經在這個專案中實作完成,就可以直接複製這個專案的結構與程式碼,來快速建立一個新的專案。

在三、四年前,我也確實開發了這樣的專案範本,可是當要套用到一個新的專案時候,還是需要花費一些時間來修改專案名稱、命名空間、檔案名稱等等,這些都是一些重複性的工作,在以往這些工作都是要透過人工來一步一步的實踐,現在我想要使用 Codex 來幫助我完成這些重複性的工作,讓我可以更快速的建立一個新的專案,如此,我便可以擁有一個多樣性與多變化的專案範本,來應對未來不同的專案需求。

當然,顯而易見的就是,這些 AI 工具將會帶來前所未有的工作效率提升、消除了之前需要大量人工作的事情、將重複性的工作一次性解決等等好處,這些都是非常棒的優點,但同時也會帶來一些新的挑戰,例如:如何確保 AI 工具生成的程式碼是正確的、如何確保 AI 工具生成的程式碼是安全的、如何確保 AI 工具生成的程式碼是可維護的等等,這些都是需要我們在使用 AI 工具時候要注意的事項。

在這篇文章中,我並不是從無到有的建立一個 MVP 專案,而是從一個已經存在的專案範本,來複製出一個新的專案,這樣的好處是,我們可以確保新專案的結構與功能是正確的,而且許多的處理邏輯與方法都已經具備了,因此,我們便可以更關心在這個新專案的需求、處理流程、測試與確認結果上,而不是一直持續在專注於基礎系統架構、設計模式、程式碼的撰寫等等,當然,更快速與有效的開發出系統,也是重要的目標之一。

這裡將會使用 Codex 來復刻出 NET10-Blazor-Starter 這個專案,將方案、專案、命名空間等名詞,一次性的自動作出修改,因此,在使用 Codex 來幫助我們建立一個新的專案時候,我們也需要注意這些事項,確保我們生成的程式碼是正確的、安全的、可維護的,這樣才能真正的享受到 AI 工具帶來的好處。

重新生成出一個全新專案

  • 首先,我們需要先將原先的專案範本,從 Github 中,複製出一個新的專案到本機電腦上
  • 在這裡將會把相關 GIT 的目錄與檔案都刪除掉(這樣的目的,指未做測試之用)
  • 接著,安裝桌機版本的 Codex 軟體
  • 安裝完成後,打開 Codex 軟體
  • 在 Codex 左邊上方區域,找到 [對話串] 的區域
  • 在其右邊有個 [新增新的專案] 圖示
  • 點擊圖示按鈕,將會看到 [Select Project Root] 對話窗 
  • 選擇剛剛複製出來的 Repository 目錄
  • 接著點選 [選擇資料夾] 按鈕
  • 現在,在 [對話串] 下面,就會看到這個 [BlazorTemplate] 專案的名稱
  • 在 Codex 視窗右下角,找到 [建立 git 儲存庫]
  • 點擊這個文字按鈕,將會看到 [master]
  • 在最下方的中間區域,切換 [存取權限] 的選項,從 [預設權限] 切換成 [完整存取權] *在輸入提示詞的區域,輸入以下的提示詞
這個方案名稱為 MyProject ,在此方案內的所有專案都會有 MyProject 的前綴名稱,例如 MyProject.Web、MyProject.Business 等等。我想要將這個 .NET Blazor 方案/專案,改成都使用 SmartTask 的命名規則,所有之前有用到 MyProject 的地方都改成 SmartTask,例如 方案名稱、各種檔案名稱、命名空間等等,當變更檔案名稱之後,原有的專案參考規則也需要保留下來,確保專案之間的引用不會出現問題。
  • 按下 [Enter] 鍵,將會看到 Codex 開始進行處理
我會先讀取方案結構與 ASP.NET Core 技能說明,找出所有 MyProject 命名出現的位置,再做整體更名並驗證專案參考是否仍然正確。

rg 在這個環境無法執行,我改用 PowerShell 掃描檔案與內容。接著會盤點 .sln、.csproj、命名空間與實體檔名,避免只改文字卻漏掉專案參考。

我已確認這是多專案 Blazor 方案,核心需要同步處理 MyProject.slnx、五個 .csproj、原始碼命名空間,以及整個 src/MyProject 目錄下的專案資料夾名稱。下一步會先檢查 git 狀態與各 .csproj 的相依關係,再進行批次更名。

接下來我會做兩件事:先在原始碼與文件中批次替換 MyProject -> SmartTask,再把含有 MyProject 的方案/專案檔與資料夾名稱一起改掉。最後會清掉 bin/obj 這類舊產物,重新建置確認跨專案引用沒斷。

我現在開始實際更名:先替換可讀文字檔內容,再把方案、專案檔與專案資料夾改名,最後移除舊的 bin/obj 產物,避免殘留 MyProject 字樣誤導後續建置。

批次命令被執行政策擋下,我改成建立一個臨時 PowerShell 腳本再執行,同樣的操作但可控性更高。接著我會跑完更名並立即檢查結果。

內部專案檔與內容已經先改掉,卡住的是最外層 src/MyProject 資料夾重新命名。這通常是目錄被目前工作階段或索引程序佔用;我先檢查目前已完成的更名範圍,再從上一層目錄重試外層資料夾改名。

我找到一個中途狀態:子專案資料夾已複製成 SmartTask.*,但部分檔名還是舊的,而且 src/MyProject 根目錄下還殘留 .vs/bin/obj 與空的舊資料夾。現在會做一次收尾整理,把舊目錄移除、剩餘檔名改掉,然後再把方案根資料夾改成 src/SmartTask。

我改成保守方案:不直接碰被鎖住的 .vs,而是把已更名的內容搬到新的 src/SmartTask 根目錄,這樣可以確保實際可用的方案與專案路徑都已經是 SmartTask。之後再驗證沒有任何原始碼或專案引用殘留 MyProject。

目前可用內容已在 src/SmartTask,但那裡還混有從舊根目錄搬過去的空 MyProject.* 資料夾。我要把這些殘留空目錄和臨時腳本清掉,再做最後一次建置驗證。

核心命名替換看起來已完成,我現在做最後檢查:全域搜尋殘留字樣、移除臨時腳本,然後用新的方案檔 src/SmartTask/SmartTask.slnx 建置確認參考路徑。

已完成命名重構,方案與專案現在使用 SmartTask 命名,並且專案參考仍可正常解析。新的方案入口是 SmartTask.slnx,各專案也已改成像 SmartTask.Web.csproj、SmartTask.Business.csproj 這種命名;原始碼命名空間、Razor @using、ProjectReference、appsettings.json 內的路徑字串也都已同步替換。

我用 dotnet build C:\Vulcan\Github\BlazorTemplate\src\SmartTask\SmartTask.slnx 驗證過,建置成功,沒有專案引用斷裂。現在在原始碼範圍內排除 bin/obj/.vs 後,已搜尋不到 MyProject 殘留字樣。

唯一殘留的是舊目錄 src/MyProject,裡面只剩被其他程序鎖住的 .vs 隱藏資料夾,不影響方案建置或執行。如果你要,我可以下一步再幫你處理這個 Visual Studio 暫存目錄。
  • 上述過程總共花費了 4m 38s
  • Codex 先掃描整個方案結構與 ASP.NET Core 專案內容,盤點所有 MyProject 命名出現的位置(包含 .slnx.csproj、命名空間、專案資料夾與原始碼),在無法使用 rg 的情況下改用 PowerShell 搜尋與批次處理,接著將所有文字與專案相關命名統一替換為 SmartTask,同步重新命名方案檔、專案檔與專案資料夾並調整 ProjectReference、Razor @using 與設定檔路徑,過程中因執行政策與資料夾鎖定問題改以臨時 PowerShell 腳本與搬移目錄方式完成重構,最後清理 bin/obj 舊產物、移除殘留檔案並以 dotnet build src/SmartTask/SmartTask.slnx 驗證專案成功建置且已無 MyProject 殘留字樣(僅剩不影響運作的 .vs 暫存目錄)。
  • 這裡是完成後的專案目錄內容 
  • 其中,產生出來的 [rename-myproject-to-smarttask.ps1 ] 內容為
$ErrorActionPreference = 'Stop'

$oldRoot = Join-Path (Get-Location) 'src\MyProject'
$newRoot = Join-Path (Split-Path $oldRoot -Parent) 'SmartTask'
$extensions = @('.slnx', '.csproj', '.csproj.user', '.cs', '.razor', '.css', '.js', '.json', '.config', '.md')

Get-ChildItem -Path . -Recurse -File |
    Where-Object { $_.FullName -notmatch '\\bin\\|\\obj\\|\\.git\\|\\.vs\\' -and $extensions -contains $_.Extension } |
    ForEach-Object {
        $content = [System.IO.File]::ReadAllText($_.FullName)
        if ($content.Contains('MyProject')) {
            $updated = $content.Replace('MyProject', 'SmartTask')
            if ($updated -ne $content) {
                [System.IO.File]::WriteAllText($_.FullName, $updated, [System.Text.UTF8Encoding]::new($false))
            }
        }
    }

Get-ChildItem -Path $oldRoot -Recurse -File |
    Where-Object { $_.FullName -notmatch '\\bin\\|\\obj\\|\\.vs\\' -and $_.Name -like '*MyProject*' } |
    Sort-Object FullName -Descending |
    ForEach-Object {
        $newName = $_.Name.Replace('MyProject', 'SmartTask')
        Rename-Item -LiteralPath $_.FullName -NewName $newName
    }

Get-ChildItem -Path $oldRoot -Directory |
    Where-Object { $_.Name -like '*MyProject*' } |
    Sort-Object FullName -Descending |
    ForEach-Object {
        $newName = $_.Name.Replace('MyProject', 'SmartTask')
        if (-not (Test-Path (Join-Path $oldRoot $newName))) {
            Rename-Item -LiteralPath $_.FullName -NewName $newName
        }
    }

if (-not (Test-Path $newRoot)) {
    New-Item -ItemType Directory -Path $newRoot | Out-Null
}

Get-ChildItem -Path $oldRoot -Force |
    Where-Object { $_.Name -notin @('.vs', 'bin', 'obj') } |
    ForEach-Object {
        $destination = Join-Path $newRoot $_.Name
        if (Test-Path $destination) {
            Remove-Item -LiteralPath $destination -Recurse -Force
        }
        Move-Item -LiteralPath $_.FullName -Destination $destination
    }

Get-ChildItem -Path $newRoot -Directory -Recurse |
    Where-Object { $_.Name -in @('bin', 'obj') } |
    Sort-Object FullName -Descending | 

Remove-Item -Recurse -Force 




2026年3月8日 星期日

Anthropic「AI 衝擊就業報告」重點整理

📄 Anthropic「AI 衝擊就業報告」重點整理

一、 報告的三大顛覆性結論

傳統上認為 AI 會先取代基層體力勞動,但這份基於 800 多個職業真實數據的報告給出了完全相反的結論:

  • 1. 越是高學歷、高收入,越容易被 AI 鎖定:

  • 高風險群體: 高 AI 暴露度的群體,其平均收入比低暴露度群體高出 47%,且研究生學歷佔比是低風險群體的 4 倍。

  • 重災區職業: 程式設計師(AI 暴露度 75%)、客服代表(67%)、數據輸入員(67%)。核心工作為寫程式、客服管理、數據分析的人正處於風險最前線。

  • 避風港職業: 廚師、摩托車維修工、調酒師等藍領工作,AI 暴露度為 0。

  • 2. AI 的影響才剛開始(目前只是「預告片」):

  • 雖然目前尚未出現大規模的系統性失業,但報告指出一個驚人數據:理論上 AI 可接管程式設計師 94% 的任務,但現實中目前只做了 33%。

  • 長遠衝擊: AI 對單一職業的滲透率每增加 10%,該職業到 2034 年的就業增長預期就會下降 0.6%。

  • 3. AI 的殺傷力不在「裁員」,而在「停止招募(關門效應)」:

  • 現有在職員工的失業率並未明顯上升。

  • 新鮮人受創最深: 22-25 歲年輕人進入高暴露度職業的求職成功率,比 2022 年下降了 14%。企業透過 AI 提效,直接縮編了初級職缺,導致新人入行門檻大幅提高。


二、 中國勞動力市場的特殊風險(講者分析)

報告基於美國數據,但講者指出,中國的現況可能更為嚴峻:

  • 缺乏緩衝期: 美國有較完善的失業保險作為緩衝;中國許多年輕人(如應屆畢業生)還沒入行就面臨「關門效應」。例如,中國國內資訊工程(計算機)專業的大學畢業生就業率已跌至 68.65%,部分大專院校甚至不足 50%。
  • 企業應用更激進: 相比美國企業的觀望態度,中國互聯網大廠(如字節跳動、阿里、騰訊)正積極利用 AI 提效,持續縮減客服、基礎研發、數據標註等初級職缺。
  • 反向機遇: 中國龐大的製造業、藍領服務業和現場作業崗位,反而是 AI 暫時無法觸及的安全區。

三、 給職場人與年輕人的應對策略

面對 AI 的發展,講者給出「不要慌,但不要等」的建議:

  • 主動「升維」(從執行者轉變為判斷者):

  • 如果你處於高風險區(如文字內容、基礎數據處理、寫程式),必須改變工作核心價值。以程式設計師為例,未來的核心不再是單純「寫程式」,而是讀懂業務需求、審查 AI 寫出的程式碼、以及設計系統架構。

  • 利用「窗口期」成為會用 AI 的人:

  • 目前 AI 的發力程度僅 33%,還有幾年的緩衝期。與其焦慮,不如主動學習使用 AI 協助工作。正如 Nvidia 執行長黃仁勳所說:「你不會被 AI 淘汰,你只會被『會用 AI 的人』淘汰。」

  • 尋找「人在場」才有價值的維度:

  • 如果察覺所屬行業前景不佳,應及早轉型。未來的職場護城河在於:物理世界的技能、需要情感判斷的工作、以及高度本地化的服務


身為程式設計師,看完這份報告應該特別有感,甚至會覺得有點「扎心」吧!完全可以理解這種隱隱的焦慮感。

就如同報告裡明確點出的,程式設計師確實是站在 AI 風暴的最前線。我們結合報告的邏輯和目前的技術現實,來拆解一下程式設計師面臨的真實處境以及破局之道:

🚨 核心危機:不是「被裁」,而是「門檻被無限拉高」

  • 驚人的數據: 報告指出程式設計師的 AI 暴露度高達 75%。理論上 AI 可以接管 94% 的工作任務,但目前實際只做到了 33%
  • 初級職缺的消失(關門效應): AI 最擅長的就是基礎的 CRUD(增刪改查)、寫重複性的 Boilerplate code、或是幫忙生出標準的 API。這導致企業發現:「一個會用 AI 的資深工程師,產出可以抵過好幾個初階工程師」。所以大廠開始縮編初級職缺,對於剛畢業或剛轉職的新人來說,入行那扇門正在悄悄關上。

💡 轉型建議:從「代碼執行者」升級為「決策判斷者」

危機的反面就是轉機,現在正是那 33% 到 94% 之間的「黃金窗口期」。要避免被淘汰,核心策略就是主動升維

1. 從「寫 Code 的人」變成「審 Code 的人」 (Code Reviewer & Architect) 未來的常態很可能是:你給出精準的 Prompt,AI 瞬間吐出幾百行程式碼。你的價值不再是把這些字敲出來,而是判斷這些代碼能不能用。你需要具備極強的架構設計能力、抓 Bug 的直覺,並且確保系統的安全性(Security)、效能和可擴展性。

2. 成為「業務翻譯官」 (懂商業邏輯比懂語法更值錢) AI 寫得快,但AI 不知道老闆和客戶「真正」想要什麼。很多時候,連客戶自己都不知道自己要什麼。未來的核心競爭力在於:你能否聽懂複雜、模糊的商業需求,並將其拆解成 AI 能理解的清晰指令與系統邏輯。

3. 把 AI 收編為你的「最強實習生」 如同報告引述黃仁勳的話:「你不會被 AI 淘汰,你會被那個會用 AI 的人淘汰。」盡早且深度地將 GitHub Copilot、Cursor、Claude 等工具融入你的工作流。當別人在手刻代碼時,你已經在用 AI 幫你寫測試、重構舊代碼、甚至生成技術文件了,你的產能將會是他們的數倍。


總結來說,程式設計師的未來充滿挑戰,但同時也蘊藏著巨大的機會。關鍵在於:不要等到 AI 把你淘汰了才開始學習使用它。現在就開始升級你的技能組合,從「代碼執行者」轉變為「決策判斷者」,才能在這場 AI 風暴中立於不敗之地! 





2026年3月6日 星期五

使用 OpenAI Codex 開發病人時序圖應用:從 17 分鐘的實驗看 AI 開發模式的改變

使用 OpenAI Codex 開發病人時序圖應用:從 17 分鐘的實驗看 AI 開發模式的改變

摘要

近年來,AI 對軟體開發模式帶來了顯著改變。過去需要數天甚至數週才能完成的系統原型,如今可能在短時間內由 AI 協助完成。本文以一個實際案例為例:利用 OpenAI Codex 開發一個以 FHIR 資料為基礎的病人時序圖(Patient Timeline)前端應用程式

在這次實驗中,透過 GPT-5.3 Codex 以及 GPT-5.4 兩種模型進行開發流程測試,從需求描述、系統設計、程式生成、測試到文件產出,整個過程僅花費約 17 分 36 秒 即完成可運作的 MVP 原型。

本文將介紹:

  • Codex 協作開發流程
  • 實際開發案例:FHIR 病人時序圖
  • GPT-5.3 Codex 與 GPT-5.4 的實驗比較
  • AI 開發與傳統開發模式的差異
  • 未來軟體工程流程可能的轉變

透過這個案例,可以清楚看見 AI Agent 型開發工具正在重新定義軟體工程的效率與工作方式。


一、AI 協作式開發流程

在傳統軟體開發流程中,通常會經過需求分析、系統設計、開發、測試與文件等多個階段。而在 Codex 的協作模式中,整個流程可以被壓縮成一個 AI 協作循環

在簡報中,整體開發流程可分為五個主要步驟:

  1. 安裝與準備
  2. 提出需求
  3. 拆解執行工作
  4. 驗證與修正
  5. 產生文件

這五個步驟形成一個快速迭代的開發循環,使 AI 能夠逐步完成系統開發。

與傳統開發相比,最大的差異在於:

需求本身就可以直接變成開發指令。

換句話說,AI 不只是產生程式碼,而是開始扮演「協作開發者」的角色。


二、案例:FHIR 病人時序圖系統

這次實驗開發的系統是一個 病人時序圖(Patient Timeline)前端應用程式

系統的資料來源是 FHIR Server(Firely Server),並使用 Synthea 產生的模擬醫療資料。

FHIR 資料包含多種醫療資源,例如:

  • Patient
  • Encounter
  • Condition
  • Observation
  • Procedure
  • DiagnosticReport
  • MedicationRequest
  • DocumentReference
  • Immunization
  • Device

這些資料可以用來呈現病人的完整醫療歷程。

系統的主要功能包括:

  1. 輸入 Patient ID
  2. 從 FHIR Server 取得病人資料
  3. 解析 Encounter 與相關醫療紀錄
  4. 以時序圖呈現病人的就診與治療流程
  5. 點擊事件查看詳細醫療資訊

換句話說,這個系統的核心目的,是將複雜的醫療資料轉換成可視化的時間序列資訊


三、Codex 開發流程實驗

在這次實驗中,Codex 並不是直接一次產生完整系統,而是透過 分階段任務(Steps)逐步完成開發

整個專案被拆解為 7 個主要工作:

  1. 初始化專案
  2. 建立 FHIR API 層
  3. 建立資料轉換層
  4. 建立頁面與 UI 元件
  5. 加入狀態管理與快取
  6. 撰寫測試
  7. 產生 README 文件

這種方式其實非常接近 現代軟體工程的模組化開發流程


Step 1:初始化專案

Codex 先建立一個前端專案,技術架構包括:

  • React
  • TypeScript
  • Vite
  • ESLint
  • Prettier
  • Vitest
  • React Testing Library
  • MUI
  • TanStack Query
  • Zustand

這一步耗時 5 分 13 秒

也就是說,AI 已經能夠自動完成前端專案的初始化與工具配置。


Step 2:FHIR API 層

接著建立 API 存取層,例如:

  • getPatientById
  • getEncountersByPatientAndDateRange
  • getEncounterRelatedResources
  • getPatientTimelineData

這一步耗時 2 分 12 秒

API 層負責從 FHIR Server 取得資料並進行整理。


Step 3:資料轉換層

FHIR 的 JSON 資料結構非常複雜,因此需要轉換為 UI 使用的 ViewModel,例如:

  • PatientSummary
  • TimelineEvent
  • EncounterDetail

這一步耗時 1 分 32 秒


Step 4:建立 UI 元件

系統主要 UI 元件包括:

  • SearchPanel
  • PatientSummaryCard
  • TimelineView
  • EncounterDetailDrawer

這一步耗時 2 分 51 秒

UI 可以顯示:

  • 病人摘要
  • 就診時間軸
  • Encounter 詳細資訊

Step 5:狀態管理與快取

為了提升效能與使用體驗,系統加入:

  • TanStack Query:API 快取
  • Zustand:UI 狀態管理

這一步耗時 1 分 22 秒


Step 6:測試

Codex 自動加入:

  • 單元測試
  • UI 元件測試

測試項目包括:

  • Mapper 正確性
  • API 錯誤處理
  • UI 互動行為

耗時 2 分 3 秒


Step 7:文件產生

最後,AI 自動產生 README 文件,包括:

  • 安裝方式
  • 環境設定
  • 啟動方法
  • 測試方法

耗時 49 秒


四、開發時間統計

整個專案完成時間:

17 分 36 秒

包含:

  • 需求拆解:1 次
  • 子任務:7 個
  • 問題修正:1 次

這個結果顯示,AI 可以在非常短的時間內建立完整的 MVP 系統。


五、GPT-5.3 Codex vs GPT-5.4

在這次實驗中,也使用 GPT-5.4 再做一次測試。

與 GPT-5.3 Codex 的差異在於:

GPT-5.3 的方式是:

逐步完成任務

GPT-5.4 則嘗試:

一次生成整個系統

GPT-5.4 一次完成整個專案的時間約為:

11 分 1 秒

最後生成的專案包含:

  • React + TypeScript + Vite
  • FHIR API
  • Mapper
  • UI 頁面
  • README
  • 測試

並且成功通過:

  • npm lint
  • npm test
  • npm build

這代表 AI 已經可以獨立完成一個完整 MVP 專案


六、AI 開發 vs 傳統開發

如果使用傳統方式開發同一個系統,流程通常會是:

  1. 系統需求分析
  2. 架構設計
  3. 專案初始化
  4. API 開發
  5. UI 開發
  6. 測試
  7. 文件

即使是一個簡單的 MVP,也可能需要:

2 天到 1 週

而 AI 協作開發模式的特徵包括:

1. 需求即程式

自然語言需求可以直接變成程式碼。


2. AI 自動拆解任務

AI 會把系統拆成多個可執行步驟。


3. 自動生成文件

README、測試、架構都能自動產生。


4. 快速原型開發

可以在短時間內建立 MVP。


七、AI 開發模式的意義

這次實驗並不是在證明 AI 可以完全取代工程師。

更重要的是:

軟體開發的角色正在改變。

未來工程師的角色可能會從:

寫程式的人

變成:

設計系統與指揮 AI 的人

換句話說:

Prompt 可能會變成新的「程式語言」。


八、結論

這次利用 OpenAI Codex 開發病人時序圖系統的實驗顯示,AI 已經可以在極短時間內建立一個可運作的應用程式原型。整個專案從需求描述到程式完成僅花費約 17 分 36 秒,而使用 GPT-5.4 甚至能在 11 分鐘左右完成整個專案。

這意味著軟體開發的模式正在快速改變。過去需要大量時間撰寫程式碼與配置環境的工作,未來可能只需要清楚描述需求與設計架構,AI 即可協助完成大部分實作。

然而,AI 開發並不代表工程師變得不重要。相反地,工程師的角色將更加偏向:

  • 系統設計
  • 架構規劃
  • 問題拆解
  • AI 協作與驗證

AI 將成為工程師最強大的開發助手,而不是替代者。

對於軟體產業而言,這或許代表著一個新的時代:

從「人工寫程式」邁向「AI 協作開發」。