· 7 min read

Un assistant de conception qui fonctionne sur votre appareil — aucun compte, aucun serveur

L'assistant AI de PinePaper transforme une invite en une scène réelle en utilisant un modèle de langue qui fonctionne entièrement dans votre navigateur. Voici l'architecture — appels d'outils limités, deux fournisseurs, et un compte rendu honnête de ce qu'un modèle minuscule peut et ne peut pas faire.

La prémisse

La plupart des outils de conception AI envoient votre invite à un serveur, lancent un grand modèle et renvoient le code. Cela nécessite un compte, un réseau aller-retour, et confiance que votre travail en cours transite l'infrastructure de quelqu'un d'autre.

Nous voulions savoir jusqu'où va l'autre extrême : un assistant de conception où le modèle fonctionne sur votre propre machine. Pas de compte. Pas de téléchargement. L'invite ne quitte jamais le navigateur. Ceci est maintenant en direct dans l'éditeur de PinePaper comme un onglet expérimental AI / Code → Assistant, et ce post est un compte honnête de la façon dont il fonctionne et où il tombe à court.

Pourquoi ne pas simplement demander le code au modèle ?

L'approche évidente est de demander au modèle on-device d'écrire JavaScript contre PinePaper et de l'exécuter. On a essayé. Ça échoue mal.

Les petits modèles — ceux qui s'adaptent à un ordinateur portable — n'ont ** aucune connaissance du API d'une application spécifique.** Demandez à un modèle 0.5-2B d'appeler PinePaper.create() et il improvise : une clé que la méthode ne lit pas (un fill de style SVG où le API attend color), une méthode qu'il a imaginée, argumente dans la mauvaise forme. La sortie *semble un code et fait silencieusement la mauvaise chose.

Donc nous ne demandons pas de code. Nous demandons une liste d'appels d'outils restreints:

[
  { "name": "pinepaper_set_background_color", "arguments": { "color": "#0F0F1A" } },
  { "name": "pinepaper_create_item", "arguments": { "itemType": "star", "x": 400, "y": 300, "radius": 90, "color": "#E74C3C", "animationType": "pulse" } }
]

Le même vocabulaire PinePaper MCP server expose à des agents externes — mais émis par un modèle fonctionnant localement, et exécuté sur la toile à travers un petit répartiteur.

Rendre la sortie invalide impossible

Le mouvement clé est ** décodage forcé.** Au lieu d'espérer que le modèle produit une forme valide, nous restreignons quels jetons il est même autorisé à émettre:

  • Sur Chrome intégré Prompt API (Gemini Nano), nous passons un schéma JSON comme une contrainte de réponse. Le modèle ne peut produire que des objets que le schéma permet — avec additionalProperties: false, tout argument que le schéma ne définit pas est littéralement non représentatif.
  • Sur WebLLM (un modèle ouvert fonctionnant sur WebGPU), nous joindre une grammaire EBNF via XGrammar. La grammaire dicte la structure; le modèle ne remplit que les valeurs.

Les deux produisent la même forme d'appel d'outils. Un petit passe de réparation récupère ensuite les quasi-mâches d'un modèle minuscule fait encore — un name largué, arguments sans leur enveloppe — en inférant l'outil de la forme de l'argument. Le résultat est que "tirer un pentagone vert" devient un vrai appel create_item au lieu d'une erreur.

Deux fournisseurs, un contrat

Sur l'appareil AI n'est pas une chose — cela dépend du navigateur:

  • Browser AI — Chrome intégré Gemini Nano (window.LanguageModel). Le modèle est livré avec le navigateur; il n'y a rien à télécharger de nous. C'est le chemin le plus fiable sur les appareils aujourd'hui, car la contrainte JSON-schéma est bon marché et bien supportée.
  • PinePaper AIWebLLM exécutant un modèle Qwen2.5 dans un navigateur WebGPU. Il télécharge un modèle une fois (caché par la suite), puis fonctionne hors ligne.
  • Langues — les instructions non anglaises sont traduites d'abord en anglais sur l'appareil (par l'intermédiaire du traducteur intégré du navigateur), car les petits modèles axés sur le code sont centrés sur l'anglais. La scène générée est la même quel que soit le langage rapide.

L'utilisateur choisit le moteur; tout en aval — la contrainte, l'exécuteur, la toile — est identique.

Édition, pas seulement générer

Un générateur à une prise n'est pas un assistant. Pour soutenir « faire rouger l'étoile », le modèle doit savoir ce qui est déjà sur la toile. Ainsi, chaque tour nous lui fournissons un instantané compact des éléments actuels — leurs ids, types et couleurs — exactement comme un chat côté serveur le ferait. "Rendre l'étoile rouge" puis se résout à un véritable appel modify_item contre l'identifiant de l'article. (Et parce qu'un petit modèle fait parfois référence à "the circle" quand il signifie l'étoile, l'exécuteur résout des références floues contre la toile en direct.)

Le journal de conversation est conservé ** sur votre appareil** dans le stockage local. Rien à ce sujet n'est envoyé nulle part — à moins que vous optiez explicitement pour partager des invites échouées, ce qui nous aide à améliorer les invites et la grammaire.

Quand le petit modèle ne suffit pas — escalader

Voici la partie honnête : un modèle 0,5–2B est le niveau le plus faible. Le décodage contraint garantit structure valide, mais le modèle doit toujours choisir le bon outil et les valeurs sensées, et il ne le fera pas toujours. Demandez un pentagone et un modèle sous-déterminé vous donne un hexagone; demandez deux fois pour "rouge" et il pourrait exécuter un générateur à la place.

Ainsi, l'architecture traite l'appareil comme le premier niveau, pas le seul. Après quelques tentatives infructueuses, l'assistante propose de réaliser toute la conversation au modèle Cloud** — même intention, même toile, un modèle beaucoup plus capable — et vous continuez exactement là où vous avez quitté. Faible fidélité, libre et privée, avec un chemin à un clic vers la haute fidélité lorsque vous en avez besoin.

Ce que nous avons appris

  • Constraints battent appel. Un système à base d'invite aide; une grammaire / schéma qui rend la sortie invalide impossible aide beaucoup plus. Le plus grand saut de fiabilité vient du décodage limité, pas d'un meilleur prompt.
  • La taille du modèle domine encore. Passer d'un 0.5B à un modèle 1.5B a nettement amélioré la fréquence à laquelle l'assistant choisit le bon outil. Il n'y a pas de prompt qui transforme un modèle minuscule en un modèle intelligent.
  • La grammaire complète peut être trop grande. Notre première grammaire encodée chaque opération possible – y compris une trappe d'évacuation de longueur limitée pour code de dessin arbitraire. Il était si grand que le décodage forcé a bloqué la page. Une grammaire compacte couvrant les opérations communes est la bonne par défaut; la surface entière est opt-in.
  • ** Exécuter le fil principal.** Un modèle faisant une inférence sur le fil d'interface utilisateur gèle la page. WebLLM fonctionne dans un Web Worker de sorte que l'éditeur reste réactif pendant qu'un modèle se charge et génère.

Suivant

Ceci est expérimental et s'améliore. Sur la feuille de route:

  • Couverture de l'outil Wider dans la trajectoire contrainte — plus des opérations de PinePaper expressible sans l'écoutille d'échappement libre.
  • Modèles de largeur sur l'appareil à mesure que les catalogues de modèles WebGPU grandissent, trading taille de téléchargement pour la fiabilité.
  • Une boucle d'évaluation plus serrée — en utilisant des rapports d'échecs choisis pour mesurer ce qui incite à faire glisser les modèles sur les appareils et à durcir la grammaire contre eux.
  • Un appareil plus lisse → Débranchement nuageux, donc l'escalade a l'impression de monter le cadran de qualité plutôt que de changer d'outils.

Le throughline: le même vocabulaire d'outil déclaratif conduit un modèle de chaque côté de la limite du navigateur. Un agent externe appelle ces outils sur MCP ; un modèle sur appareil appelle localement les mêmes formes. Un contrat, des agents où qu'ils courent.

Essayez-le dans l'éditeur — ouvrir AI / Code → Assistant. Il est gratuit, fonctionne sur votre appareil, et n'a pas besoin de compte.

Ready to create?

Start making animated GIFs, videos, and graphics — free, no signup.

Open PinePaper Editor