「AI書法」的原理

AI書法不使用圖像生成 AI,而是用語言模型來書寫書法。

一般的圖像生成 AI 直接輸出完成的圖像。然而書法是一門重視過程的藝術:筆落在何處、按下多重、如何運行又如何收住。圖像生成 AI 沒有這一過程,因此無法表現書法的本質。
而語言模型雖然無法輸出圖像,卻能把運筆的過程生成為資料。也就是說,藉助語言模型,可以模擬「書寫」這一行為本身,有可能做出更接近書法本質的表現。

語言模型 × 書法引擎

語言模型會收到以下資訊作為輸入。

語言模型根據這兩項資訊,把實際的運筆輸出為資料。把這些資料變成實際圖像的,是書法引擎 sho.js。sho.js 是重現毛筆特性的原創程式,透過重現毛筆與紙張的物理規律來完成書法作品。

  1. 系統提示詞引擎規格與書法心得
    題目文字(例)用楷書寫「春風」
  2. 語言模型構思運筆
  3. 運筆資料{"p":[[377,327,0.06,null,0.8],[418,352,1],…
  4. 書法引擎sho.js
  5. 作品

模型的個性

sho.js 只負責毛筆與紙張的物理重現。如何運筆、寫成什麼字形、如何佈局整張紙面等表現上的判斷,全部交給語言模型的能力。因此作品中會鮮明地表現出各個模型的特徵。比較作品,可以觀察到各模型在對書法的理解深度、筆順正誤、技術高低、字形習慣等方面的個性差異。

sho.js 的規格

下面結合可實際運作的示例,說明運筆資料的形式、各數值的含義,以及 sho.js 如何把資料變成線條。同樣的內容也寫在交給語言模型的系統提示詞中。(系統提示詞全文見這裡,為日文)

資料格式

資料為 JSON Lines 格式,即每行一個 JSON 物件。sho.js 由上到下依序處理這些資料。

{"t":"brush","size":58}
{"c":"永"}
{"p":[[377,327,0.06,null,0.8],[418,352,1],[434,376,2.0,null,0.3,0.12],[430,372,0.06,null,0.4]]}
{"p":[[311,528,0.1,null,0.5],[317,534,1.1,null,0.4], …]}
…
{"comment":"把右捺的收尾稍微拉長了一些。"}
行含義
{"t":"brush","size":58}宣告所用的毛筆。size 是筆壓為 1 時的線寬。 也可以指定 ink_tone(墨的濃淡)和 ink_load(墨量)。 書寫表情符號時可以更換一次毛筆。
{"c":"永"}宣告接下來要寫的字。此時毛筆會沾墨(沾墨)。若不沾墨,寫作 {"c":"永","no_dip":true}。
{"p":[[x,y,…],…]}一筆的資料。是點的序列,毛筆依序經過這些點。
{"dip":0.6}沾墨的量。
{"comment":"…"}寫完作品後的感想。

紙張為直長的半紙,寬 1000 × 高 1376。左上角為 (0, 0),右下角為 (1000, 1376)。

「筆畫」資料的表示

筆畫由點的序列表示,每個點寫作 [x, y, 筆壓, 角度, 速度, 停頓]。不寫或寫 null 即可省略該值。 加入 "k" 則該點成為轉角。

值範圍含義省略時
x, y紙張座標筆尖的位置(不可省略)
筆壓0〜2毛筆壓入紙面的深度。1 時線寬等於筆的粗細,2 時為兩倍。接近 0 時只有筆尖接觸,線條尖細由前後的點插值(全部省略則為 1)
角度度從筆尖指向筆腹的方向保持前一個點的角度(最初為 42)
速度0.05〜6運筆的速度。1 為每秒「筆的粗細 × 20」由前後的點插值(全部省略則為 1)
停頓秒毛筆在該點停留的時間。越長,墨越濃,輪廓越圓潤鼓脹0
"k"—該點不平滑連接,而是成為轉角(轉折)平滑
一條橫畫。筆尖落下後立即按住(露鋒),行筆速度恆定,收尾時放慢速度按住、停頓,再稍微回筆後提起(頓)。紅點是資料點(筆尖的位置),淺藍色的形狀是該點處的筆頭。筆頭從筆尖沿角度方向伸出,長度為筆壓 × 粗細。用「點」「筆」切換顯示,用「書寫」重播運筆過程。

書法引擎用平滑曲線(centripetal Catmull-Rom)連接各點,筆壓、角度、速度也在點與點之間插值。

筆:筆尖與筆腹

毛筆是數百根毛的束(粗細 60 的筆約 300 根,筆越粗越多),形如水滴,筆尖細、筆腹粗。點所在的位置是筆尖, 線條從筆尖沿角度的方向展開,寬度為筆壓 × 筆的粗細。 壓得越深,筆腹越多地落在紙上,線越粗;提起時則收縮回筆尖,線條變細變尖。

只改變筆壓的 3 條線(由上到下為 0.4、1、1.8)。同一支筆,壓入的深度不同,線寬也隨之改變。

角度是筆的傾斜。預設的 42 時,筆腹落在筆尖的右下方(側鋒),粗的部分偏向點的右下方。 當角度與前進方向一致時,筆尖走在線條的中心(中鋒),筆沿筆軸前進,線條較細。 當筆橫切筆軸前進時,線條最粗。

筆壓 1.2,只改變角度的 3 條線(由上到下為 42、0、90)。向右行進的線,角度 0 沿行進方向,所以細;90 橫切,所以粗。

墨:濃淡與墨量

墨由濃淡和墨量兩個值決定,都在毛筆宣告中指定。省略時兩者均為 1,即沾滿濃墨的筆。 這兩個值彼此獨立,組合使用。

墨的濃淡 ink_tone(0〜1)決定顏色的深淺和暈染的難易。1 是濃墨的黑色,調低則變成淡墨的灰色。 淡墨含水多,會向線外暈開,外緣留下一圈略深的水痕。暈染在書寫較慢處更寬,飛白處不會出現。

濃淡 1
濃淡 0.5
濃淡 0.2

墨量 ink_load(0.2〜1.5)是毛筆沾的墨量。不改變顏色,只決定是否容易出現飛白。

墨量 1
墨量 0.4

墨:飛白與停頓

每一根毛都含有墨,隨著在紙上行進而逐漸失去墨。有墨時線條連貫,墨用盡之處則沿著紙的紋理斷開, 形成條狀的飛白。墨量越少、運筆越快、同一個字中越靠後的筆畫,越容易出現飛白。 墨以字為單位({"c":…} 這一行)重新沾取。紙上的墨有雲一般的濃淡不均,飛白並不均勻,而是斑駁地出現。

只改變速度的 3 條線(由上到下為 0.5、2、5)。越快,飛白越呈條狀。

在筆停住之處(停頓),墨會積聚變濃,輪廓圓潤地暈開。停得越久,暈得越大。 墨越淡,暈得越快。

淡墨(濃淡 0.5)的線條,只改變中間一點的停頓的 3 條線(由上到下為 0 秒、0.15 秒、1.2 秒)。停得越久,墨積得越圓。

轉角:轉折

在 "k" 點處,曲線不平滑連接,而是形成轉角。從橫折向豎的地方,在轉角前放慢速度, 在轉角處按住並停頓,改變方向後稍微放鬆筆壓再恢復,轉角處就會留下「肩」。

從橫折向豎的一筆。在轉角點加入 "k",在轉角處留下「肩」。

書法的筆法

sho.js 中沒有針對「鉤」或「撇捺」等筆法的固定處理。與人類的運筆一樣,露鋒、藏鋒、頓、鉤、撇捺、垂露、懸針,都只透過各點的位置與筆壓、角度、速度、停頓的組合來表現。例如撇,是一邊順時針旋轉筆的角度一邊向下行,在左下方先沉下,然後提高速度、放鬆筆壓,向左流出。下面是系統提示詞中示例的「永」字(永字八法)。

「永」。側、勒、努、趯、策、掠、啄、磔八種筆法,全部只用點的資訊寫成。

對語言模型的要求

僅僅排列座標、描出字的形狀,寫不出好的書法。語言模型需要在每一筆都留意以下幾點,並設計整幅作品。

亂數由筆的位置決定,所以同樣的資料一定會寫出同樣的書法。作品之間的差異,全部來自語言模型所寫數值的差異。

GitHub

籌備中

參考文獻

Published: 2026-11-02 12:00 JST
AI書法大賽籌備委員會(@enpitsu)
「AI書法」的原理|AI書法大賽