Que fait opendraft ?
Transforme une simple ligne de sujet en un article académique finalisé, avec une base bibliographique réelle.
Porté depuis OpenDraft (github.com/federicodeponte/opendraft, MIT), qui exécute ceci comme un moteur hébergé. Ici, le moteur c'est vous : dix-huit étapes, chacune étant une instruction dans agents/, plus cinq scripts qui effectuent les parties qu'un modèle de langage ne doit pas faire à la main.
Vous êtes le modèle. Pas de clé, pas de service, pas de compte. Les seuls appels réseau sont Crossref, OpenAlex et DataCite, tous des points d'accès ouverts.
La commande unique
Écrire un article sur <sujet>
Tout ce qui suit découle de cela. Ne demandez pas à l'utilisateur d'exécuter les étapes lui-même ; exécutez-les.
Demandez quatre choses d'abord
Avant l'étape 5, si l'utilisateur ne l'a pas déjà dit, demandez :
- Lieu de publication cible, ou "aucun, académique général".
- Limite totale de mots.
- Style de citation, l'un des six dans
references/citation-styles.md. - Type de document, l'un des types dans
references/paper-types.md.
Ce sont quatre questions dans un seul message, pas une interview, et ce sont les seules questions que le pipeline pose. Tout le reste, il le décide.
Demandez parce que le coût d'une supposition se paye à la fin et ne peut y être réglé. Un lieu de publication avec un résumé de 150 mots maximum est appliqué à l'étape 6 ou nulle part : au moment où l'étape 17 écrit le résumé, le budget de mots de chaque section rédigée est déjà erroné. Un style de citation choisi au début plutôt qu'à l'étape 6 signifie que l'ensemble du brouillon a été écrit avec une mauvaise densité de marqueurs.
Si l'utilisateur refuse de répondre, ou dit "vous choisissez", procédez avec les valeurs par défaut dans references/paper-types.md, inscrivez-les dans le bloc de format du lieu de publication à l'étape 6, et dites en une ligne les valeurs par défaut que vous avez utilisées. Ne procédez jamais sur une hypothèse non énoncée que vous ne lui avez pas montrée.
Quatre choses que les scripts possèdent, et vous pas
Un modèle de langage est bon pour le jugement et mauvais pour la comptabilité. La séparation est délibérée, et la transgresser est ce qui casse la sortie. Chacune est appliquée par un script qui termine avec un code non nul, donc aucune n'est une question d'opinion à la porte.
N'écrivez jamais de marqueur de citation rendu à la main. Pas [3], pas (Smith, 2020). Lors de la rédaction, écrivez {cite_<doi>} en ligne exactement au point de l'affirmation. scripts/citations.py compile les transforme en marqueurs et construit la bibliographie par consultation d'un dictionnaire. C'est déterministe, donc la correspondance entre le texte et la bibliographie est mécanique plutôt que mémorisée.
N'inventez jamais une source pour une affirmation que vous ne pouvez pas étayer. Si une affirmation est réelle et que vous ne trouvez pas de source, écrivez {cite_MISSING: courte description de l'affirmation} et continuez. compile refuse de la rendre, la nomme et termine avec un code non nul, et integrity.py la compte comme critique, donc elle ne peut survivre jusqu'à l'article finalisé. C'est le but : ce n'est pas un moyen de publier une affirmation non sourcée, c'est un moyen d'être honnête lors de la rédaction au lieu de supprimer silencieusement l'affirmation ou de l'attacher à un DOI inventé. Éliminez chacune avant la porte en trouvant une source réelle avec sources.py find, ou en supprimant intentionnellement l'affirmation.
Ne fusionnez jamais les sections dans le brouillon à la main. scripts/assemble.py le fait, dans l'ordre numérique, et refuse d'assembler quoi que ce soit qui n'est pas une section numérotée dans l'article. Une fusion manuelle qui omet une section est l'échec que personne ne remarque jusqu'à ce qu'un lecteur le fasse.
Ne décidez jamais à l'œil si l'article est cohérent en interne. scripts/integrity.py le vérifie et termine avec un code non nul. Exécutez-le et lisez le code de sortie.
Configuration
mkdir -p research sections review
Pas de clé API, pas de compte, pas d'étape d'installation : les scripts utilisent uniquement la bibliothèque standard Python. Une variable d'environnement optionnelle existe, et c'est la seule que quoi que ce soit ici lit. Définissez OPENDRAFT_CONTACT_EMAIL avec votre propre adresse et sources.py l'ajoute à son User-Agent, ce qui déplace les requêtes Crossref vers le pool poli et ses meilleures limites de taux. Laissez-la non définie et chaque étape fonctionne toujours ; aucune adresse n'est intégrée, car une valeur par défaut distribuée mettrait tous les installateurs dans une seule identité et acheminerait leurs problèmes de limite de taux vers la boîte de réception d'un inconnu.
Le pipeline écrit dans des chemins fixes, et chaque étape lit ce que les étapes précédentes ont écrit. Les chemins sont le contrat entre les étapes :
research/sources.md research/sources.json research/summaries.md
research/gaps.md research/citations.json research/citation-notes.md
outline.md outline_formatted.md
sections/*.md full_draft.md final.md
review/thread.md review/narrator.md review/skeptic.md
review/verifier.md review/referee.md review/voice.md
review/entropy.md review/polish.md
Quatre règles concernant ces chemins, et chacune a déjà été enfreinte :
sections/contient les sections de l'article et rien d'autre. Chaque fichier qui s'y trouve est assemblé dans l'article finalisé parscripts/assemble.py. Un rapport d'étape placé là se retrouve à l'intérieur de la thèse de quelqu'un. Les rapports vont dansreview/.research/sources.jsonest une entrée machine,research/sources.mdest une lecture humaine. L'étape 1 écrit les deux.citations.py buildlit le fichier JSON.- Rien d'écrit à la main ne va jamais dans
research/citations.json. Il est construit parcitations.py buildet n'est jamais modifié que par une ré-exécution debuild. Les jugements qu'aucun script ne peut prendre, les sources sans DOI, les entrées nécessitant une révision, les mentions qui n'ont pas pu être transformées en espace réservé, vont dansresearch/citation-notes.md, qui est du texte et n'est jamais lu par un script. Une base de données éditée à la main est ainsi qu'un indicateurverifiedest basculé pour passer la porte, ce qui est ainsi qu'un DOI non résolu atteint la bibliographie en ayant l'air vérifié. - Après l'étape 9.5,
full_draft.mdest le seul brouillon. Rien en aval ne litsections/*.mdà nouveau, donc modifier un fichier de section après l'assemblage ne change rien et perd silencieusement la modification.
Le pipeline
Exécutez dans l'ordre. Chaque étape sauf une est un fichier dans agents/ : lisez ce fichier, faites ce qu'il dit, écrivez la sortie qu'il nomme, puis passez à la suite. L'exception est l'étape 9.5, qui est un script que vous exécutez. Ne sautez pas une étape parce que le sujet semble facile.
| # | Étape | Fichier agent ou script | Écrit |
|---|---|---|---|
| 1 | Trouver des sources | agents/01-scout.md | research/sources.md, research/sources.json |
| 2 | Les lire et les résumer | agents/02-scribe.md | research/summaries.md |
| 3 | Trouver l'angle qui vaut la peine d'être écrit | agents/03-signal.md | research/gaps.md |
| 4 | Construire la base de données de citations | agents/04-citation-manager.md | research/citations.json, research/citation-notes.md |
| 5 | Esquisser l'argumentation | agents/05-architect.md | outline.md |
| 6 | Appliquer le format du lieu de publication et les budgets de mots | agents/06-formatter.md | outline_formatted.md |
| 7 | Rédiger chaque section | agents/07-crafter.md | sections/*.md, ajoute à research/gaps.md |
| 8 | Vérifier la cohérence entre les sections | agents/08-thread.md | corrections dans sections/*.md, review/thread.md |
| 9 | Unifier la voix | agents/09-narrator.md | corrections dans sections/*.md, review/narrator.md |
| 9.5 | Assembler les sections en un seul brouillon | scripts/assemble.py | full_draft.md |
| 10 | Attaquer l'argumentation | agents/10-skeptic.md | review/skeptic.md, puis corrections |
| 11 | Vérifier les affirmations par rapport aux sources | agents/11-verifier.md | review/verifier.md, puis corrections |
| 12 | Simuler l'évaluation par les pairs | agents/12-referee.md | review/referee.md, puis corrections |
| 13 | Correspondre à la voix de l'auteur (optionnel) | agents/13-voice.md | corrections dans full_draft.md, review/voice.md |
| 14 | Varier le rythme de la prose | agents/14-entropy.md | corrections dans full_draft.md, review/entropy.md |
| 15 | Grammaire et polissage final | agents/15-polish.md | full_draft.md, review/polish.md |
| 16 | Ajouter l'appareil critique (optionnel) | agents/16-enhancer.md | full_draft.md |
| 17 | Écrire le résumé | agents/17-abstract.md | préfixé à full_draft.md |
| 18 | Écrire le titre | agents/18-titlemaker.md | préfixé à full_draft.md |
L'étape 7 s'exécute une fois par section, pas une fois par article. Les étapes 10 à 12 produisent des listes de problèmes ; une liste de problèmes que personne n'applique est une opération nulle, donc appliquez les corrections et ré-exécutez l'étape jusqu'à ce qu'aucun problème critique ne subsiste.
L'étape 12 a un nombre, pas un sentiment. Arrêtez lorsqu'une nouvelle exécution signale zéro problème critique et une moyenne globale d'au moins 3,0 sur 5, sans dimension unique en dessous de 3 à moins que vous n'enregistriez la raison dans review/referee.md. "Assez bon pour envoyer" n'est pas une condition d'arrêt, car un modèle à qui on demande de juger son propre brouillon le trouvera toujours assez bon au troisième passage.
L'étape 13 est la seule étape avec une entrée que le pipeline ne produit jamais. Elle fait correspondre le brouillon à la prose de l'auteur, et elle lit cette prose à partir d'un répertoire samples/ dans le répertoire de travail : deux ou trois articles antérieurs, chapitres ou billets longs, au format .md ou .txt. Rien ne crée ce répertoire et rien ne vous le demande, donc une exécution qui n'en crée jamais saute proprement l'étape 13, ce qui est le résultat normal plutôt qu'un échec. Placez vos propres écrits là avant l'exécution si vous voulez que l'article semble écrit par vous.
L'étape 9.5 est numérotée comme une demi-étape car c'est un script plutôt qu'une instruction d'agent, et parce que les dix-huit étapes d'agent conservent les numéros qu'elles avaient déjà. Elle n'est pas optionnelle. Les étapes 1 à 9 travaillent sur sections/*.md ; les étapes 10 à 18 travaillent sur full_draft.md ; rien ne produit ce fichier sauf cette commande :
python3 scripts/assemble.py sections -o full_draft.md
Elle fusionne les fichiers de section dans l'ordre numérique, refuse d'inclure tout fichier qui n'est pas une section numérotée, et termine avec un code non nul en cas d'écart de numérotation, de numéro en double ou de répertoire vide. --check rapporte ce qu'elle ferait sans écrire.
Elle ignore également tout fichier numéroté dont le nom contient report, review, notes, checklist ou log, ce qui est le mécanisme qui empêche un rapport d'étape obsolète de se retrouver dans une thèse. C'est une heuristique basée sur le nom de fichier, donc elle a un angle mort : une section réelle intitulée "Revue de la littérature" serait ignorée, et vous ne la verriez que comme une ligne "Ignorée" sur stdout plutôt que comme une erreur. Nommez cette section travaux-connexes ou litterature à la place. Lisez les lignes ignorées ; une section qui disparaît ici disparaît silencieusement.
Ré-exécuter après que full_draft.md existe nécessite --force, et --force jette toutes les modifications que les étapes 10 et suivantes ont apportées au brouillon, donc réassemblez seulement lorsque vous avez l'intention de redémarrer à partir des sections.
Échelle
Adaptez le pipeline à ce qui a été demandé. Les étapes sont les mêmes ; la profondeur ne l'est pas.
- Un texte court, 1 500 à 3 000 mots. Étapes 1 à 7, puis 9.5, 10, 11, 15. Dix à quinze sources.
- Un article complet, la valeur par défaut. Les dix-huit, plus 9.5. Vingt-cinq à cinquante sources, ou cinquante et plus lorsque l'article est une revue de la littérature, dont le propre plancher prévaut partout où il est plus élevé (
references/paper-types.md). - Un chapitre de thèse ou une longue revue. Les dix-huit, plus 9.5, sources dans la cinquantaine ou plus, et étape 7 une fois par sous-section plutôt que par section.
L'étape 9.5 est dans chacune de ces listes. Il n'y a aucune échelle à laquelle un article s'assemble tout seul.
Les deux fichiers de référence
references/paper-types.mdcontient le squelette de la section, le budget de mots et le nombre de sources pour chaque type de document. Lisez-le à l'étape 5.references/citation-styles.mdmontre le résultat compilé réel des six styles, marqueur dans le texte et entrée de référence, afin que vous puissiez en choisir un pour le lieu de publication et savoir à quoi il ressemblera. Lisez-le à l'étape 6, et à nouveau avant la porte si une citation se rend d'une manière que vous n'aviez pas prévue. Il indique également ce que le compilateur ne gère pas : pas de numéros de volume, de numéro ou de page, pas d'abréviation de revue. Si un superviseur exige ces éléments, c'est l'endroit qui le dit honnêtement plutôt que l'endroit où vous l'apprenez après coup.
Aucun des deux fichiers n'est une lecture optionnelle déguisée en référence. Un style choisi sans lire le second est un style choisi de mémoire, et le compilateur n'implémente pas votre mémoire de l'APA.
Les scripts
python3 scripts/sources.py find "<requête>" --n 15 # Crossref plus OpenAlex
python3 scripts/sources.py find "<requête>" --json # lisible par machine
python3 scripts/sources.py verify <doi> <doi> ... # Crossref plus DataCite
python3 scripts/citations.py build research/sources.json -o research/citations.json
python3 scripts/citations.py verify -d research/citations.json
python3 scripts/citations.py compile full_draft.md -d research/citations.json --style apa -o final.md
python3 scripts/citations.py bibtex -d research/citations.json -o refs.bib
python3 scripts/assemble.py sections -o full_draft.md
python3 scripts/assemble.py sections -o full_draft.md --check
python3 scripts/integrity.py final.md -d research/citations.json --target 8000
python3 scripts/integrity.py final.md -c research/summaries.md # vérification de nombre consultative
python3 scripts/export.py final.md --format docx -o final.docx
Tous terminent avec un code non nul en cas d'échec. Ce code de sortie est le signal ; lisez-le plutôt que de survoler la sortie.
sources.py find termine avec le code 1 lorsqu'aucune API n'a pu être contactée du tout, ce qui est différent de les contacter et de n'obtenir aucun résultat. agents/01-scout.md est l'autorité sur la façon de lire ce code de sortie et sur le plancher de sources en dessous duquel l'étape 1 s'arrête plutôt que de continuer ; lisez-le là plutôt que de vous fier à un résultat vide.
citations.py build prend le tableau JSON que l'étape 1 a écrit dans research/sources.json, pas le markdown dans research/sources.md. Lui fournir le fichier markdown est une erreur, et il le dira.
Recherchez également deux ou trois sous-requêtes plus étroites si le premier passage est mince. Un article avec cinq sources se lit comme un article avec cinq sources.
Vérification, et ce qu'elle prouve ou non
citations.py verify place chaque DOI dans l'un des quatre états, et unknown n'est jamais silencieusement transformé en absent :
- résolu. Crossref ou DataCite a renvoyé l'enregistrement. Citez-le.
- absent. Les deux ont renvoyé 404. Supprimez-le. Ne le réparez pas, ne devinez pas un DOI de remplacement, revenez à
...