ChatGPT

Article Wikipedia : https://fr.wikipedia.org/wiki/ChatGPT


Je rassemble ci-dessous quelques dates clés qui me servent de repères temporels, utiles pour retracer chronologiquement ma découverte de ces outils :

  • GPT-2 : février 2019
  • GPT-3.5 : novembre 2022
  • GPT-4 : mars 2023
  • GPT-4o : mai 2024

Papier de recheche arXiv de GTP-3.5, publié le 28 mai 2020 : https://arxiv.org/abs/2005.14165.


Journaux liées à cette note :

J'utilise les LLMs comme des amis experts et jamais comme des écrivains fantômes #llm, #generative-ai

Un ami m'a posé la question suivante :

J'aimerais ton avis sur l'utilisation des LLM au quotidien (hors code). Les utilises-tu ? En tires-tu quelque chose de positif ? Quelles en sont les limites ?

Je vais tenter de répondre à cette question dans cette note.


Danger des LLMs : le risque de prolétarisation

Mon père et surtout mon grand-père m'ont inculqué par tradition familiale la valeur du savoir-faire. Plus tard, Bernard Stiegler m'a donné les outils théoriques pour comprendre cet enseignement à travers le concept de processus de prolétarisation.

La prolétarisation est, d’une manière générale, ce qui consiste à priver un sujet (producteur, consommateur, concepteur) de ses savoirs (savoir-faire, savoir-vivre, savoir concevoir et théoriser).

source

Ici, j'utilise la définition de prolétaire suivante :

Personne qui ne possède plus ses savoirs, desquels elle a été dépossédée par l’utilisation d’une technique.

source

En analysant mon parcours, je réalise que ma quête d'autonomie technique et de compréhension — en somme, ma recherche d'émancipation — a systématiquement guidé mes choix, comme le fait d'avoir pris le chemin du logiciel libre en 1997.

Sensibilisé à ces questions, j'ai immédiatement perçu les risques dès que j'ai découvert la puissance des LLM mi 2023 .


J'utilise les LLMs comme des amis expert d'un domaine

Les LLMs sont pour moi des pharmakons : ils sont à la fois un potentiel remède et un poison. J'essaie de rester conscient de leurs toxicités.

J'ai donc décidé d'utiliser les IA générative de texte comme je le ferais avec un ami expert d'un domaine.

Concrètement, je continue d'écrire la première version de mes notes, mails, commentaires, messages de chat ou issues sans l'aide d'IA générative de texte.
C'est seulement dans un second temps que je consulte un LLM, comme je le ferais avec un ami expert : pour lui demander un commentaire, lui poser une question ou lui demander une relecture.

J'utilise les IA générative de texte par exemple pour :

  • vérifier si mon texte est explicite et compréhensible
  • obtenir des suggestions d'amélioration de ma rédaction

Tout comme avec un ami, je lui partage l'intégralité de mon texte pour donner le contexte, et ensuite je lui pose des questions ciblées sur une phrase ou un paragraphe spécifique. Cette méthode me permet de mieux cadrer ses réponses.

À ce sujet, voir mes notes suivantes :

Par respect pour mes interlocuteurs, je ne demande jamais à un LLM de rédiger un texte à ma place.

(source)

Lorsque je trouve pertinent un contenu produit par un LLM, je le partage en tant que citation en indiquant clairement la version du modèle qui l'a généré. Je le cite comme je citerai les propos d'un humain.

En résumé, je ne m'attribue jamais les propos générés par un LLM. Je n'utilise jamais un LLM comme un écrivain fantôme.


Seconde utilisation : exploration de sujets

J'utilise aussi les LLMs pour explorer des sujets.

Je dirais que cela me permet de faire l'expérience de ce que j'appellerais "de la sérendipité dirigée".

Par exemple, je lui expose une idée et comme à un ami, je lui demande si cela a du sens pour lui, qu'est-ce que cela lui évoque et très souvent, je découvre dans ses réponses des auteurs ou des concepts que je n'ai jamais entendus parler.

J'utilise beaucoup les LLMs pour obtenir un "overview" avec une orientation très spécifique, sur des sujets tech, politique, historique…

Je l'utilise aussi souvent pour comprendre l'origine des noms des projets, ce qui me permet de mieux m'en souvenir.

Voir aussi cette note que j'ai publiée en mai 2024 : Je constate que j'utilise de plus en plus ChatGPT à la place de DuckDuckGo.

Les limites ?

En matière d'exploration, je pense que les LLMs sont d'une qualité exceptionnelle pour cette tâche. Je n'ai jamais expérimenté quelque chose d'aussi puissant. Peut-être que j'obtiendrais de meilleurs résultats en posant directement des questions à des experts mondiaux dans les domaines concernés, mais la question ne se pose pas puisque je n'ai pas accès à ces personnes.

Pour l'aide à la rédaction, il me semble que c'est nettement plus efficace que ce qu'un ami serait en mesure de proposer. Même si ce n'est pas parfait, je ne pense pas qu'un LLMs soit en mesure de deviner précisément, par lui-même, ce que j'ai l'intention d'exprimer. Il n'y a pas de magie : il faut que mes idées soient suffisamment claires dans mon cerveau pour être formulées de façon explicite. En ce qui concerne ces tâches, je constate d'importantes différences entre les modèles. Actuellement, Claude Sonnet 4 reste mon préféré pour la rédaction En revanche, j'obtiens de moins bons résultats avec les modèles chain-of-thought, ce qui est sans doute visible dans les LLM Benchmark.

Par contre, dès que je m'éloigne des questions générales pour aborder la résolution de problèmes précis, j'obtiens pour le moment des résultats très faibles. Je remarque quotidiennement des erreurs dans le domaine tech, comme :

  • des paramètres inexistants
  • des parties de code qui ne s'exécutent pas
  • ...

Comment a évolué mon utilisation des LLMs depuis 2023 ?

J'ai publié sur https://data.sklein.xyz mes statistiques d'utilisation des LLMs de janvier 2023 à mai 2025.
Ces statistiques ne sont plus représentatives à partir de juin 2025, parce que j'ai commencé à utiliser fortement Open WebUI couplé à OpenRouter et aussi LMArena. J'aimerais prendre le temps d'intégrer les statistiques de ces plateformes prochainement.

Comme on peut le voir sur https://data.sklein.xyz, mon usage de ChatGPT a réellement démarré en avril 2024, pour évoluer vers une consommation mensuelle d'environ 300 threads.

Je suis surpris d'avoir si peu utilisé ChatGPT entre avril 2023 et janvier 2024 🤔. Je l'utilisais peut-être en mode non connecté et dans ce cas, j'ai perdu toute trace de ces interactions.

Voir aussi ma note : Estimation de l'empreinte carbone de mon usage des IA génératives de textes.


Combien je dépense en inférence LLM par mois ?

De mars à septembre 2024, 22 € par mois pour ChatGPT.
De mars à mai 2025, 22 € par mois pour Claude.ia.

Depuis juin 2025, je pense que je consomme moins de 10 € par mois, depuis que je suis passé à OpenRouter. Plus d'informations à ce sujet dans : Quelle est mon utilisation d'OpenRouter.ia ?


J'aurais encore beaucoup à dire sur le sujet des LLMs, mais j'ai décidé de m'arrêter là pour cette note.

Pour aller plus loin sur ce sujet, sous un angle très technique, je conseille cette série d'articles sur LinuxFr :

Et toutes mes notes associées au tag : #llm

Quelle est mon utilisation d'OpenRouter.ia ? #llm, #Jutilise

Alexandre m'a posé la question suivante :

Pourquoi utilises-tu openrouter.ai ? Quel est son intérêt principal pour toi ?

Je vais tenter de répondre à cette question dans cette note.

(Un screencast est disponible en fin de note)


Historique de mon utilisation des IA génératives payantes

Pour commencer, je pense qu’il est utile de revenir sur l’histoire de mon usage des IA génératives de texte payantes, afin de mieux comprendre ce qui m’a amené à utiliser openrouter.ai.

En juin 2023, j'ai expérimenté l'API ChatGPT dans ce POC poc-api-gpt-generate-demo-datas et je me rappelle avoir brûlé mes 10 € de crédit très rapidement.

Cette expérience m'a mené à la conclusion que pour utiliser des LLM dans le futur, je devrais passer par du self-hosting.
C'est pour cela que je me suis fortement intéressé à Llama.cpp en 2024, comme l'illustrent ces notes :

J'ai souscrit à ChatGPT Plus pour environ 22 € par mois de mars à septembre 2024.

Je pensais que cette offre était probablement bien plus économique que l'utilisation directe de l'API ChatGPT. Avec du recul, je pense que ce n'était pas le cas.


Après avoir lu plusieurs articles sur Anthropic — notamment la section Historique de l'article Wikipédia — et constaté les retours positifs sur Claude Sonnet (voir la note 2025-01-12_1509), j’ai décidé de tester Claude.ia pendant un certain temps.

Le 3 mars 2025, je me suis abonné à l'offre Claude Pro à 21,60 € par mois.

Durant cette même période, j'ai utilisé avante.nvim connecté à Claude Sonnet via le provider Copilot, voir note : J'ai réussi à configurer Avante.nvim connecté à Claude Sonnet via le provider Copilot.

En revanche, comme je l’indique ici , je n’ai jamais réussi à trouver, dans l’interface web de GitHub, mes statistiques d’utilisation ni les quotas associés à Copilot. J’avais en permanence la crainte de découvrir un jour une facture salée.

Au mois d'avril 2025, j'ai commencé à utiliser Scaleway Generative APIs connecté à Open WebUI : voir note 2025-04-25_1833.


Pour résumer, ma situation en mai 2025 était la suivante


En mai 2025, j'ai commencé sans conviction à m'intéresser à OpenRouter

J'ai réellement pris le temps de tester OpenRouter le 30 mai 2025. J'avais déjà croisé ce projet plusieurs fois auparavant, probablement dans la documentation de Aider, llm (cli) et sans doute sur le Subreddit LocalLLaMa.

Avant de prendre réellement le temps de le tester, en ligne de commande et avec Open WebUI, je n'avais pas réellement compris son intérêt.

Je ne comprenais pas l'intérêt de payer 5% de frais supplémentaires à openrouter.ai pour accéder aux modèles payants d'OpenAI ou Anthropic 🤔 !

Au même moment, je m'interrogeais sur les limites de quotas de tokens de l'offre Claude Pro.

For Individual Power Users: Claude Pro Plan

  • All Free plan features.
  • Approximately 5 times more usage than the Free plan.
  • ...

source

J'étais très surpris de constater que la documentation de l'offre Claude Pro , contrairement à celle de l'API, ne précisait aucun chiffre concernant les limites de consommation de tokens.

Même constat du côté de ChatGPT :

ChatGPT Plus

  • Toutes les fonctionnalités de l’offre gratuite
  • Limites étendues sur l’envoi de messages, le chargement de fichiers, l’analyse de données et la génération d’images
  • ...

source

Je me souviens d'avoir effectué diverses recherches sur Reddit à ce sujet, mais sans succès.

J'ai interrogé Claude.ia et il m'a répondu ceci :

L'offre Claude Pro vous donne accès à environ 3 millions de tokens par mois. Ce quota est remis à zéro chaque mois et vous permet d'utiliser Claude de manière plus intensive qu'avec le plan gratuit.

Aucune précision n'est donnée concernant une éventuelle répartition des tokens d'input et d'output, pas plus que sur le modèle LLM qui est sélectionné.

J'ai fait ces petits calculs de coûts sur llm-prices :

  • En prenant l'hypothèse de 1 million de tokens en entrée et 2 millions en sortie :

J'en ai déduit que le prix des abonnements n'est peut-être pas aussi économique que je le pensais initialement.

Après cela, j'ai calculé le coût de plusieurs de mes discussions sur Claude.ia. J'ai été surpris de voir que les prix étaient bien inférieurs à ce que je pensais : seulement 0,003 € pour une petite question, et environ 0,08 € pour générer un texte de 5000 mots.

J'ai alors pris la décision de tester openrouter.ai avec 10 € de crédit. Je me suis dit : "Au pire, si openrouter.ai est inutile, je perdrai seulement 0,5 €".
Je pensais que je n'avais pas à me poser de questions tant qu'openrouter.ai ne me coûtait qu'un ou deux euros par mois.

Suite à cette décision, j'ai commencé à utiliser openrouter.ai avec Open WebUI en utilisant ce playground : open-webui-deployment-playground.

Ensuite, je me suis lancé dans « Projet 30 - "Setup une instance personnelle d'Open WebUI connectée à OpenRouter" » pour héberger cela un peu plus proprement.

Et dernièrement, j'ai connecté avante.nvim à OpenRouter : Switch from Copilot to OpenRouter with Gemini 2.0 Flash for Avante.nvim.


Après plus d'un mois d'utilisation, voici ce que OpenRouter m'apporte

Entre le 30 mai et le 15 juillet 2025, j'ai consommé $14,94 de crédit. Ce qui est moindre que l'abonnement de 22 € par mois de Claude Pro.

D'après mes calculs basés sur https://data.sklein.xyz, en utilisant OpenRouter j'aurais dépensé :

  • mars 2025 : $3.07
  • avril 2025 : $2,76
  • mai 2025 : $2,32

Ici aussi, ces montants sont bien moindres que les 22 € de l'abonnement Claude Pro.

En utilisant OpenRouter, j'ai accès facilement à plus de 400 instances de models, dont la plupart des modèles propriétaires, comme ceux de OpenAI, Claude, Gemini, Mistral AI

Je n'ai plus à me poser la question de prendre un abonnement chez un provider ou un autre.
Je dépose simplement des crédits sur openrouter.ai et après, je suis libre d'utiliser ce que je veux.

openrouter.ai me donne l'opportunité de tester différents modèles avec plus de liberté.

J'ai aussi accès à énormément de modèles gratuitement, à condition d'accepter que ces providers exploitent mes prompts pour de l'entrainement. Plus de détail ici : Privacy, Logging, and Data Collection.

Tout ceci est configurable dans l'interface web de OpenRouter :

Je peux générer autant de clés d'API que je le désire. Et ce que j'apprécie particulièrement, c'est la possibilité de paramétrer des quotas de crédits spécifiques pour chaque clé ❤️.

OpenRouter me donne bien entendu accès aux fonctionnalités avancées des modèles, par exemple Structured Outputs with LLM, ou "tools" :

J'ai aussi accès à un dashboard d'activité, je peux suivre avec précision mes consommations :

Je peux aussi utiliser OpenRouter dans mes applications, avec llm (cli), avante.nvim… Je n'ai plus à me poser de question.

Et voici un petit screencast de présentation de openrouter.ai :

Estimation de l'empreinte carbone de mon usage des IA génératives de textes #écologie, #llm, #generative-ai

Je pense avoir entendu : « Une requête ChatGPT consomme l'équivalent de 10 recherches conventionnelles Google ! ».

Problème : je ne retrouve plus la source et cette comparaison me paraît manquer de rigueur. Par exemple, elle ne prend pas en compte le volume de tokens traités en entrée et en sortie.

Aujourd'hui, j'ai cherché à en savoir plus sur ce sujet et à vérifier cette déclaration.

J'ai d'abord cherché des informations sur l'émission de CO2 d'une recherche conventionnelle Google et j'ai trouvé ceci :

In 2009, The Guardian published an article about the carbon cost of Google search. Google had posted a rebuttal to the claim that every search emits 7 g of CO2 on their blog. What they claimed was that, in 2009, the energy cost was 0.0003 kWh per search, or 1 kJ. That corresponded to 0.2 g CO2, and I think that was indeed a closer estimate.

source

Si ma déclaration précédente est valide et qu'une recherche conventionnelle Google génère 0,2 g de CO2, alors une requête sur une IA générative de texte devrait sans doute produire environ 2g de CO2.

Attention, ces chiffres datent de 2009 : Google a probablement gagné en efficacité énergétique, mais a probablement aussi complexifié son algorithme.

En attendant de trouver des données plus récentes, j'ai choisi de partir de cette estimation pour cette note.


Ensuite, je me suis lancé dans des recherches sur l'estimation de la consommation CO2 des IA génératives de texte. J'ai effectué des recherches sur arXiv et je suis tombé sur cet article "How Hungry is AI? Benchmarking Energy, Water, and Carbon Footprint of LLM Inference" qui date de mai 2025.

J'y ai trouvé ces graphes d'émission de CO2 par modèle en fonction du nombre de tokens en entrée et en sortie :

Pour Claude Sonnet 3.7 que j'ai fréquemment utilisé, je lis ceci :

  • 100 in => 100 out : 0.4g
  • 1k in => 1k out : 1g
  • 10k in => 10k out : 2g

J'en conclus que l'ordre de grandeur de la déclaration que j'ai entendu semble réaliste.


En mai 2025, mes 299 threads ont consommé 19 129 tokens en entrée, soit 63 tokens par thread en moyenne. Mon usage d'IA générative de texte ce mois-là aurait généré approximativement 299 x 0,4g = 119g de CO2.

Pour mettre cela en perspective, j'ai estimé les émissions d'un trajet aller-retour Paris - Crest-Voland (Savoie) avec ma voiture :

Résultat : 1240km x 140g = 173 kg de CO2 pour mes déplacements hivernaux en Savoie. Un seul voyage correspond à 121 ans de mon utilisation mensuelle actuelle d'IA générative de texte.

Une extension browser pour exporter ses threads Claude.ia et ChatGPT #iteration, #backup, #browser-extension

Actuellement, et à ma connaissance, les APIs de Claude.ia et ChatGPT ne proposent pas de fonctionnalité d'export de l'historique des conversations de leur interface web de chat.

J'imagine deux approches pour réaliser cet export malgré tout : développer un script qui réalise une forme de Web Scraping ou intégrer cette fonctionnalité directement dans une extension navigateur plutôt que dans un script autonome. L'extension browser présente l'avantage de simplifier la gestion de l'authentification.

Après 30 minutes de recherche sur GitHub, du style "export chatgpt", j'ai trouvé claude-chatgpt-backup-extension. Cette extension permet l'export d'une ou plusieurs conversations Claude.ia et une conversation à la fois ChatGPT.

Je l'ai testée, elle fonctionne correctement 🙂.

Je viens de proposer cette Pull Request pour ajouter le support de l'export ChatGPT en mode bulk : Add bulk export feature for ChatGPT conversations.

Cette extension pourrait me servir de base de travail pour l'idée de projet "Aggregator - Backup Numeric Conversation System".

Voici les prochaines issues d'amélioration que j'imagine pour un fork de cette extension :

  • Affichage conditionnel des boutons d'export Claude.ia uniquement quand l'utilisateur est connecté sur https://claude.ai/ (même principe pour ChatGPT).
  • Afficher une barre de progression lors des bulk exportations.
  • Proposer une option d'export au format YAML, sous une forme plus facile à lire pour les humains, avec moins d'informations techniques que le format JSON natif proposé actuellement.
  • Tenter un refactoring pour simplifier la base de code actuelle.
  • Développer une option permettant l'export vers des services Object Storage qui implémentent l'API S3.
  • Créer un mock serveur API REST et permettre l'export des données vers ce serveur.

Aggregator - Backup Numeric Conversation System #backup, #idée

Ce matin, j'ai eu l' #idée et l’envie de créer une appli d'archivage et de centralisation de toutes mes conversations numériques.

L'objectif ? Rassembler en un seul endroit, dans une interface web minimaliste, toutes mes discussions provenant de :

Le support des threads serait utile pour Mattermost et les mails. J'aimerais pouvoir sauvegarder tous ces messages au format brut original et en Markdown. Une fonction pour partager un message ou un thread serait aussi sympa.

Pour la persistance des données, je pense utiliser ElasticSearch avec son moteur vectoriel. Un LLM pourrait assigner automatiquement des tags à chaque conversation. J'aimerais que l'interface web soit minimaliste, orientée vitesse et exploration.

Pour la postérité, toutes ces données devraient être exportées en continu dans un Object Storage, sous un format YAML facilement compréhensible.

Je me demande si ce type d’application existe en Open source ou closed-source 🤔.

Journal du vendredi 25 avril 2025 à 18:33 #projet, #Inference, #intentions

Au mois de janvier, j'ai écrit :

Voici mes prochaines #intentions d'amélioration de ma workstation :

source

Le hasard de la vie fait que je commence une mission professionnelle pour la DINUM en lien avec Open WebUI : Ablert Conversation.

Au mois de décembre, j'ai déjà installé et testé rapidement Open WebUI connecté à Scaleway Generative APIs, mais je n'ai pas pris le temps de le faire avec rigueur.

Dans les prochains jours, je souhaite réaliser les projets suivants :

Journal du mardi 25 février 2025 à 22:12 #llm, #Inference, #selfhosting, #OnMePoseLaQuestion, #ollama

Un ami me demande :

Je vais bientôt acheter un nouveau portable PC. Je veux utiliser l'IA en local pour analyser des documents privés, concevoir des articles (il faut qu'elle puisse surfer), mais que les données restent locales. Il me faut donc un PC Copilot avec un NPU ?

Réponse courte : je pense qu'un NPU ne te sera d'aucune utilité pour exécuter un LLM de qualité sur ton laptop 😔.


Quand mon ami parle d'une « IA en local », je suppose qu'il souhaite exécuter un agent conversationnel qui exploite un LLM, du type ChatGPT, Claude.ia, LLaMa, DeepSeek, etc.

Sa motivation première est la confidentialité.

Cela fait depuis juin 2023 que je souhaite moi aussi self host un LLM, avant tout pour éviter le vendor locking, maitriser son coût et éviter la "la merdification des choses".

En juin 2024, je pensais moi aussi que les NPU étaient une solution technique pour self hosted un LLM. Mais depuis, j'ai compris que j'étais dans l'erreur.

Je trouve que ce commentaire résume aussi bien la fonction des NPU :

Also, people often mistake the reason for an NPU is "speed". That's not correct. The whole point of the NPU is rather to focus on low power consumption.

...

I have a sneaking suspicion that the real real reason for an NPU is marketing. "Oh look, NVDA is worth $3.3T - let's make sure we stick some AI stuff in our products too."

source

D'après ce que j'ai compris, voici ce que les NPU exécutent en local (ce qui inclut également la technologie Microsoft nommée Copilot) :

  • L'accélération des modèles d'IA pour la reconnaissance vocale, la transcription en temps réel, et la traduction.
  • Traitement plus rapide des images et vidéos pour des effets en direct (ex. flou d'arrière-plan, suppression du bruit audio).
  • Réduction de la consommation électrique en exécutant certaines tâches IA en local, sans solliciter massivement le CPU/GPU.

Je pense que les fonctionnalités MS Windows Copilot qui utilisent des LLM sont exécutées sur des serveurs mutualisés avec de gros GPU.

Si j'ai bien compris, pour faire tourner efficacement un LLM en local, il est essentiel de disposer d'une grande quantité de RAM avec une bande passante élevée.

Par exemple :

  • Une carte NVIDIA RTX 5090 avec 32Go de RAM (2700 €)
  • Une carte NVIDIA RTX 3090 avec 24Go de RAM d'accasion (1000 €)
  • Une Puce Apple M4 Max avec CPU 16 cœurs, GPU 40 cœurs et Neural Engine 16 cœurs 128 Go de mémoire unifiée (plus de 5000 €)
  • Une Puce Apple M4 Pro avec CPU 12 cœurs, GPU 16 cœurs, Neural Engine 16 cœurs 64 Go de mémoire unifiée (2400 €)

Je ne suis pas disposé à investir une telle somme dans du matériel que je ne parviendrai probablement jamais à rentabiliser. À la place, il me semble plus raisonnable d'opter pour des Managed Inference Service tels que Replicate.com ou Scaleway Managed Inference.

Voici les tarifs de Scaleway Generative APIs :

Il y a quelques semaines, j'ai connecté Open WebUI à l'API de Scaleway Managed Inference avec succès. Je pense que je vais utiliser cette solution sur le long terme.

Si je devais garantir une confidentialité absolue dans un cadre professionnel, je déploierais Ollama sur un serveur dédié équipé d'un GPU :

Journal du jeudi 30 janvier 2025 à 12:02 ##JaiDécouvert, #DevOps, #linux, #aide-mémoire, #aide

Note de type #aide-mémoire : contrairement à ~/.zprofile, .zshenv est chargé même lors de l'exécution d'une session ssh en mode non interactif, par exemple :

$ ssh user@host 'echo "Hello, world!"'

Je me suis intéressé à ce sujet parce que mes scripts exécutés par ssh dans le cadre du projet /poc-capacitor/ n'avaient pas accès aux outils mis à disposition par Homebrew et Mise.

J'ai creusé le sujet et j'ai découvert que .zprofile était chargé seulement dans les cas suivants :

  • « login shell »
  • « interactive shell »

Un login shell est un shell qui est lancé lors d'une connexion utilisateur. C'est le type de shell qui exécute des fichiers de configuration spécifiques pour préparer l'environnement utilisateur. Un login shell se comporte comme si tu te connectais physiquement à une machine ou à un serveur.

Un shell interactif est un shell dans lequel tu peux entrer des commandes de manière active, et il attend des entrées de ta part. Un shell interactif est conçu pour interagir avec l'utilisateur et permet de saisir des commandes, d'exécuter des programmes, de lancer des scripts, etc.

ChatGPT

Suite à cela, dans ce commit "Move zsh config from .zprofile to .zshenv", j'ai déplacé la configuration de Homebrew et Mise de ~/.zprofile vers .zshenv.

Cela donne ceci une fois configuré :

$ cat .zshenv
eval "$(/opt/homebrew/bin/brew shellenv)"
eval "$(mise activate zsh)"

Mais, attention, « As /etc/zshenv is run for all instances of zsh ». Je pense que ce n'est pas forcément une bonne idée d'appliquer cette configuration sur une workstation, parce que cela peut "ralentir" légèrement le système en lançant inutilement ces commandes.

ChatGPT me conseille cette configuration pour éviter cela :

# Ne charge Brew et Mise que si on est dans un shell interactif ou SSH
if [[ -t 1 || -n "$SSH_CONNECTION" ]]; then
  eval "$(/opt/homebrew/bin/brew shellenv)"
  eval "$(mise activate zsh)"
fi

Journal du dimanche 12 janvier 2025 à 00:14 #desktop, #intentions, #CodeAssistant, #neovim, #JeMeDemande

Voici mes prochaines #intentions d'amélioration de ma workstation :

Journal du jeudi 09 janvier 2025 à 13:13 #iteration, #devlog, #capacitor, #POC

Nouvelle #iteration sur le Projet 17 - Créer un POC de création d'une app smartphone avec Capacitor.

Je viens de push le commit feat(android): implemented webview and configured deeplinks. J'ai passé en tout, 11 heures sur cette itération.

Je souhaite, dans cette note de type DevLog, présenter les difficultés et les erreurs rencontrées dans cette itération.


Étape 1 : mise en place d'un dummy website totalement statique

The Capacitor application in this POC displays the content of a demonstration website, with the HTML content located in the ./dummy-website/ folder.
This website is served by an HTTP Nginx server, launched using docker-compose.yml.

source

Pour faire très simple, j'ai choisi de créer un faux site totalement statique, qui sera affiché dans une webview de l'application smartphone.

Ce site contient juste 2 pages HTML ; celui-ci est exposé par un serveur HTTP nginx, lancé via un docker-compose.yml.


Étape 2 : Expose dummy website on Internet

En première étape, j'ai dû mettre en place une méthode pour facilement exposer sur Internet un dummy website lancé localement :

Expose dummy website on Internet

Why?
The Android and iOS emulators do not have direct and easy access to the HTTP service (dummy website) exposed on http://localhost:8080.

To overcome this issue, I use "cloudflared tunnel". You can also use other solutions, such as sish or ngrok Developer Preview. For more information, you can refer to the following note (in French): 2025-01-06_2105

source

Comme expliqué ci-dessus, cette contrainte est nécessaire afin de permettre à l'émulateur Android et à l'émulateur iOS (lancé sur une instance Scaleway Apple Silicon) aussi bien que sur mon smartphone physique personnel, d'accéder aux dummy website avec un support https.

Ceci était d'autant plus nécessaire, pour remplir les contraintes de configuration de la fonctionnalité Deep Linking with Universal and App Links.

C'est pour cela que j'ai dernièrement publié les notes suivantes : 2024-12-28_1621, 2024-12-28_1710, 2024-12-31_1853 et Alternatives managées à ngrok Developer Preview.

Pour simplifier la configuration de ce projet (poc-capacitor), j'ai décidé d'utiliser "cloudflared tunnel" en mode non connecté.

J'ai installé cloudflared avec Mise (voir la configuration ici).

Pour rendre plus pratique le lancement et l'arrêt du tunnel cloudflare, j'ai implémenté deux scripts :

Voici ce que cela donne à l'usage :

$ ./scripts/start-cloudflare-http-tunnel.sh
Starting the tunnel...
…wait… …wait… …wait…
Tunnel started successfully: https://moral-clause-interesting-broadway.trycloudflare.com

To stop the tunnel, you can execute:

$ ./scripts/stop-cloudflare-http-tunnel.sh
Stopping the tunnel (PID: 673143)...
Tunnel stopped successfully.

source


Étape 3 : configuration de la webview Capacitor

En réalité, par erreur, j'ai configuré la webview Capacitor après l'implémentation de la partie App links.

Au départ, je pensais qu'un simple window.location.href = process.env.START_URL; était suffisant pour afficher le site web dans l'application. En réalité, cette commande a pour effet d'ouvrir la page HTML dans le browser par défaut du smartphone. Je ne m'en étais pas tout de suite rendu compte.

Dans Capacitor, pour créer une webview dans une application, il est nécessaire l'utiliser la fonction InAppBrowser.openInWebView(... du package @capacitor/inappbrowser.

Voici l'implémentation dans le fichier /src/js/online-webview.js :

window.Capacitor.Plugins.InAppBrowser.openInWebView({
	url: startUrl,
	options: {
		// See https://github.com/ionic-team/capacitor-os-inappbrowser/blob/e5bee40e9b942da0d4dad872892f5e7007d87e75/src/defaults.ts#L33
		// Constant values are in https://github.com/ionic-team/capacitor-os-inappbrowser/blob/e5bee40e9b942da0d4dad872892f5e7007d87e75/src/definitions.ts
		showToolbar: false,
		showURL: false,

		clearCache: true,
		clearSessionCache: true,
		mediaPlaybackRequiresUserAction: false,

		// closeButtonText: 'Close',
		// toolbarPosition: 'TOP', // ToolbarPosition.TOP

		// showNavigationButtons: true,
		// leftToRight: false,
		customWebViewUserAgent: 'capacitor webview',

		android: {
			showTitle: false,
			hideToolbarOnScroll: false,
			viewStyle: 'BOTTOM_SHEET', // AndroidViewStyle.BOTTOM_SHEET

			startAnimation: 'FADE_IN', // AndroidAnimation.FADE_IN
			exitAnimation: 'FADE_OUT', // AndroidAnimation.FADE_OUT
			allowZoom: false
		},
		iOS: {
			closeButtonText: 'DONE',           // DismissStyle.DONE
			viewStyle: 'FULL_SCREEN',          // iOSViewStyle.FULL_SCREEN
			animationEffect: 'COVER_VERTICAL', // iOSAnimation.COVER_VERTICAL
			enableBarsCollapsing: true,
			enableReadersMode: false
		}
	}
});

source

Les paramètres dans options permettent de configurer la webview. J'ai choisi de désactiver un maximum de fonctionnalités.

En implémentant cette partie, j'ai rencontré trois difficultés :

  • Avec la version 1.0.2 du packages, j'ai rencontré ce bug "Bug- Android App crashing after adding this plugin, j'ai perdu presque 1 heure avant de le découvrir, pour fixer cela, j'ai choisi le QuickWin d'installer la version 1.0.1.
  • J'ai mis un peu de temps pour trouver les paramètres passés dans options
  • J'ai trouvé allowZoom: false pour supprimer l'affichage des boutons de zoom dans la webview

Étape 4 : setup de la partie App Links

Après avoir lu la page "Deep Linking with Universal and App Links", c'était la partie que je trouvais la plus difficile, mais en pratique, ce n'est pas très compliqué.

J'ai passé 5h30 sur cette partie, mais j'ai fait plusieurs erreurs.

Cette configuration se passe en 3 étapes.

Génération du fichier .well-known/assetlinks.json

La première consiste à générer le fichier le fichier dummy-website/.well-known/assetlinks.json qui est exposé par le serveur HTTP du dummy website.

Cette opération est documentée dans la partie "Create Site Association File".

Son contenu ressemble à ceci :

[
  {
    "relation": [
        "delegate_permission/common.handle_all_urls"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "$PACKAGE_NAME",
      "sha256_cert_fingerprints": ["$SHA256_FINGERPRINT"]
    }
  }
]

Il a une fonction de sécurité, il permet d'éviter de créer des applications malveillantes qui s'ouvriraient automatiquement sur des URLs sans lien avec l'application.

Il permet de dire « l'URL de ce site web peut automatiquement ouvrir l'application $PACKAGE_NAME » qui est signée avec la clé publique $SHA256_FINGERPRINT.

J'ai implémenté le script /scripts/generate-dev-assetlinks.sh qui permet automatiquement de générer ce fichier.

Lorsque j'ai travaillé sur cette partie, j'ai fait l'erreur de générer un certificat (voir le script /scripts/generate-dev-assetlinks.sh). Or, ce n'est pas la bonne méthode en mode développement.
Par défaut, Android met à disposition un certificat de développement dans ${HOME}/.android/debug.keystore.

La commande suivante me permet d'extraire la clé publique :

SHA256_FINGERPRINT=$(keytool -list -v \
  -keystore "${HOME}/.android/debug.keystore" \
  -alias "androiddebugkey" \ # password par défaut
  -storepass "android" 2>/dev/null | grep "SHA256:" | awk '{print $2}')

source

Configuration de AndroidManifest.xml

Comme indiqué ici, voici les lignes que j'ai ajoutées dans /android/app/src/main/AndroidManifest.xml.tmpl :

<intent-filter android:autoVerify="true">
   <action android:name="android.intent.action.VIEW" />
   <category android:name="android.intent.category.DEFAULT" />
   <category android:name="android.intent.category.BROWSABLE" />
   <data android:scheme="https" />
   <data android:host="{{ .Env.ALLOW_NAVIGATION }}" />
</intent-filter>

source

Petite digression sur mon usage des templates dans ce projet.

J'utilise gomplate pour générer des fichiers dynamiquement à partir de 4 templates (.tmpl) et des variables d'environnement configurées entre autres dans .envrc.

La génération des fichiers se trouve ici :

gomplate -f capacitor.config.json.tmpl -o capacitor.config.json
gomplate -f android/app/build.gradle.tmpl -o android/app/build.gradle
gomplate -f android/app/src/main/AndroidManifest.xml.tmpl -o android/app/src/main/AndroidManifest.xml
gomplate -f android/app/src/main/strings.xml.tmpl -o android/app/src/main/res/values/strings.xml

source

Les principaux éléments dynamiques sont :

export APP_NAME=myapp
export PACKAGE_NAME="xyz.sklein.myapp"
export START_URL=$(cat .cloudflared_tunnel_url)
export ALLOW_NAVIGATION=$(echo "$START_URL" | sed -E 's#https://([^/]+).*#\1#')

START_URL contient l'URL publique générée par cloudflared tunnel qui change à chaque lancement du tunnel.

Support deep links via l'interception de l'événement appUrlOpen

Troisième étape de la configuration de App links.

let timeoutId = setTimeout(() => {
	openInWebView(process.env.START_URL);
}, 200);

window.Capacitor.Plugins.App.addListener('appUrlOpen', (event) => {
	clearTimeout(timeoutId);
	openInWebView(event.url);
});

source

Cela permet d'implémenter la fonction deep links. Exemple : si l'utilisateur du smartphone clique sur l'URL https://dummysite/deep/ alors l'application va directement s'ouvrir sur la page /deep/ du dummy website.

Commandes utiles

La commande suivante permet de demander à l'OS Android de lancer une nouvelle "vérification" du fichier dummy-website/.well-known/assetlinks.json :

$ adb shell pm verify-app-links --re-verify ${PACKAGE_NAME}

source

Note : le fichier .cloudflared_tunnel_url contient l'URL du tunnel cloudflare qui expose le dummy website.

La commande suivante permet d'afficher la configuration actuelle App Link d'une application :

$ adb shell pm get-app-links ${PACKAGE_NAME}
  xyz.sklein.myapp:
    ID: 100ba7e3-b978-49ac-926c-8e6ec6810f5c
    Signatures: [AF:AE:25:7F:ED:98:49:A3:E0:23:B3:BE:92:08:84:A5:82:D1:80:AA:E0:A4:A3:D3:A0:E2:18:D6:70:05:67:ED]
    Domain verification state:
      association-pending-belt-acute.trycloudflare.com: verified

source

La commande suivante permet de tester le lancement de l'application à partir d'une URL passée en paramètre :

$ adb shell am start -W -a android.intent.action.VIEW -d "$(cat .cloudflared_tunnel_url)"
Starting: Intent { act=android.intent.action.VIEW dat=https://sc-lo-welsh-injury.trycloudflare.com/... }
Status: ok
LaunchState: COLD
Activity: xyz.sklein.myapp/.MainActivity
TotalTime: 1258
WaitTime: 1266
Complete

source

Cela fonctionne aussi avec une sous-page, par exemple : "$(cat .cloudflared_tunnel_url)/deep/?query=foobar".

Dans l'émulateur, Chrome ne lance pas les App Link !

Je pense que ce piège m'a fait perdre 2 h (sur les 5 h passées sur cette implémentation) !

Si j'ouvre l'URL du dummy website dans Chrome, l'application n'est pas lancée.

Mais, si j'ouvre l'URL dans l'application qui se nomme "Google", celle accessible via la barre de recherche en bas ce ce screenshot, l'App Link est bien pris en compte.

Problème : je testais mon application seulement dans Chrome. Et la fonctionnalité App Links ne fonctionnait pas. C'est seulement quand j'ai installé l'application sur mon smartphone physique personnel que j'ai constaté que App Links fonctionnait sous "Firefox Android".

J'ai constaté aussi que sur mon smartphone, Chrome n'ouvrait aucune application sur les URLs youtube.com, reddit.com, github.com

D'après ce que je pense avoir compris, la liste des applications qui peuvent ouvrir les App Links est listée dans la section "Settings => Apps => Default apps" :

J'ai fait des expériences sur 3 différents smartphones Android d'amis et à ce jour, je n'ai pas encore compris comment cela fonctionne. J'ai l'impression que c'est lié au browser par défaut configuré, mais j'ai trouvé des exceptions.

En tout cas, ce piège m'a fait perdre beaucoup de temps !


Note finale

Pour le moment, je n'ai pas eu besoin de configurer @capacitor/app-launcher, mais je pense que cela sera utile pour permettre à l'application d'ouvrir d'autres applications à partir d'une URL.

J'ai scripté pratiquement toutes les actions de ce projet.

ChatGPT m'a bien servi tout au long de cette implémentation.