révision scientifique complète (editorial board, 2026-10-17)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
24 changed files +2,199 −778
modified
README.md
+70 −52
@@ -3,21 +3,25 @@ | ||
| 3 | 3 | |
| 4 | 4 | **UQO Working Paper No. 13** — *Reasoning-Augmented Tool Orchestration, In-Loop Numerical Computation, and Multi-Format Reporting* |
| 5 | 5 | |
| 6 | −[-b31b1b?logo=latex&logoColor=white)](paper/main.pdf) | |
| 6 | +[-b31b1b?logo=latex&logoColor=white)](paper/main.pdf) | |
| 7 | 7 | [](paper/main.tex) |
| 8 | 8 | [-4051b5)](#-data) |
| 9 | 9 | [](https://uqo.ca) |
| 10 | 10 | [](mailto:simon-pierre.boucher@uqo.ca) |
| 11 | 11 | |
| 12 | −> **TL;DR** — VQuant is a production web platform that turns a natural-language request into a | |
| 13 | −> complete, reproducible quantitative financial report. A reasoning-augmented LLM acts as planner | |
| 14 | −> and synthesizer; all numerical work is delegated to a deterministic execution substrate: an | |
| 15 | −> agentic orchestration loop over 200+ tools (265+ market-data endpoints, four web-research | |
| 16 | −> services, a 17-library Python sandbox), a two-stage context-management algorithm for unbounded | |
| 17 | −> conversations, a single-call computation paradigm (data → estimation → figures in one sandboxed | |
| 18 | −> execution), and a unified document pipeline emitting PDF, DOCX, Beamer and spreadsheets with live | |
| 19 | −> formulas from one Markdown artifact. The paper documents each mechanism as implemented so the | |
| 20 | −> design can be reproduced. | |
| 12 | +> **TL;DR** — VQuant is a deployed web platform that turns a natural-language request into a | |
| 13 | +> quantitative financial report in which every number comes from live data retrieval or auditable | |
| 14 | +> code rather than from the model. This is a **design-science system description, audited line by | |
| 15 | +> line against the platform's source code** (spbgit `vquant.git`, commit `e2a148a`, 2026-10-02): | |
| 16 | +> a recursive, batched, streaming tool-calling loop over **245 schema-defined tools** (two | |
| 17 | +> market-data providers, 249 typed wrappers over 233 endpoint paths; three web-research services; | |
| 18 | +> a Python sandbox pre-loading 29 packages), a **three-stage context-management procedure** | |
| 19 | +> (3,000/15,000-char truncation at execution, 5,000-char re-send cap, adaptive summarisation at | |
| 20 | +> 10^5 tokens keeping the last 5 messages), a **single-call computation convention**, and a | |
| 21 | +> document pipeline (PDF via Puppeteer+KaTeX, DOCX via Pandoc, Beamer via a second model call + | |
| 22 | +> two pdflatex passes, live-formula XLSX). **No empirical evaluation is reported** (no accuracy, | |
| 23 | +> hallucination, latency or cost measurements); a pre-registered evaluation protocol is specified | |
| 24 | +> as future work. | |
| 21 | 25 | |
| 22 | 26 | --- |
| 23 | 27 | |
@@ -25,55 +29,64 @@ | ||
| 25 | 29 | |
| 26 | 30 | | Item | Value | |
| 27 | 31 | |---|---| |
| 28 | −| Version | 1.0 (June 2026) | | |
| 32 | +| Version | **1.1 (October 2026)** — revised 2026-10-17 (editorial-board review; `docs/REVIEW-REPORT.md`, `docs/CHANGELOG-REVISION.md`). v1.0 = June 2026 (`docs/main_pre-revision-20261017.pdf`, 28 p.) | | |
| 29 | 33 | | SSRN | not yet submitted | |
| 30 | −| Journal | — | | |
| 31 | −| Code & data | methodology / system paper — no empirical pipeline; the platform's source code lives in the spbgit repository `vquant.git` | | |
| 34 | +| Journal | not yet submitted; candidate venues *Journal of Financial Data Science*, *Decision Support Systems*, *Expert Systems with Applications* — **only after the evaluation protocol of §6.6 has been executed** | | |
| 35 | +| Code & data | design/system paper — no empirical pipeline. The platform's source code lives in the spbgit repository `vquant.git`; the paper describes commit `e2a148a` (2026-10-02). The audit script and its outputs are in `docs/verify/` | | |
| 32 | 36 | |
| 33 | 37 | ## 🎯 What this paper does |
| 34 | 38 | |
| 35 | 39 | Large language models are fluent in financial discourse, but fluency does not guarantee |
| 36 | 40 | numerically rigorous, reproducible or citable analysis. This paper describes the **architecture** |
| 37 | −of VQuant, a platform that couples a reasoning-augmented LLM with a deterministic execution | |
| 38 | −substrate, and argues that the resulting design pattern — *the model plans and synthesizes, auditable | |
| 39 | −code computes* — is reusable beyond finance. | |
| 40 | − | |
| 41 | −Four mechanisms are documented at implementation level: | |
| 42 | − | |
| 43 | −1. an **agentic orchestration loop** exposing 200+ financial and analytical tools through a | |
| 44 | − constrained function-calling protocol (recursive tool-calling loop, tool-use/tool-result | |
| 45 | − invariant, batched-execution throttle); | |
| 46 | −2. a **context-management algorithm** preserving coherence over effectively unbounded histories | |
| 47 | − via adaptive summarization under a token budget (two-stage machinery, token-accounting correction); | |
| 48 | −3. a **single-call computation paradigm** that consolidates data acquisition, estimation and figure | |
| 49 | − rendering into one sandboxed Python execution (inter-process sandbox that exec's model-authored | |
| 50 | − code and captures its figures); | |
| 51 | −4. a **unified document pipeline** emitting PDF, DOCX, LaTeX Beamer decks and spreadsheet workbooks | |
| 52 | − with live formulas from a single Markdown artifact, streamed through a Server-Sent-Event protocol | |
| 53 | − with eight-way event dispatch. | |
| 54 | − | |
| 55 | −The classical quantitative methods the platform automates are conventional and relegated to the appendix. | |
| 41 | +of VQuant, a platform that couples a reasoning-capable LLM with a deterministic execution | |
| 42 | +substrate, under the principle *the model plans and synthesises, auditable code computes*. It is | |
| 43 | +written as a design-science contribution (Hevner et al. 2004; Gregor & Hevner 2013): a situated | |
| 44 | +implementation plus a demonstration, with the evaluation step specified but not performed. | |
| 45 | + | |
| 46 | +Four mechanisms are documented at implementation level, with their actual constants, and audited | |
| 47 | +against the code (Appendix E maps every claim to a source file): | |
| 48 | + | |
| 49 | +1. an **agentic orchestration loop** over 245 tools (recursive tool-calling, batches of 5 with | |
| 50 | + 500 ms spacing, tool-use/tool-result pairing, prompt-level routing by request complexity); | |
| 51 | +2. a **three-stage context-management procedure** (per-result truncation at execution, re-send | |
| 52 | + cap, adaptive summarisation under a 10^5-token budget) and a **token-accounting correction** | |
| 53 | + (max of provider count and a local BPE count — an approximation, not an exact count); | |
| 54 | +3. a **single-call computation convention** (data → estimation → figures in one sandboxed Python | |
| 55 | + execution; process-isolated child, 90 s timeout, figure sweep at 150 dpi); | |
| 56 | +4. a **document pipeline** (PDF, DOCX, Beamer, live-formula XLSX from one Markdown artifact). | |
| 57 | + | |
| 58 | +The revision corrected several statements of v1.0 that the code audit contradicted: tool count, | |
| 59 | +tokenizer, reachability of the pre-built numerical routines (only the option pricer is in the | |
| 60 | +catalogue), the model layer (now multi-provider), and three features (SSO, daily caps, | |
| 61 | +bring-your-own-keys) that do not exist in any committed version. | |
| 56 | 62 | |
| 57 | 63 | ## 🏆 Headline results |
| 58 | 64 | |
| 59 | −| Object | Value | | |
| 65 | +There are **no empirical results**. The table lists verified design facts (commit `e2a148a`). | |
| 66 | + | |
| 67 | +| Object | Value (audited) | | |
| 60 | 68 | |---|---| |
| 61 | −| Tools exposed to the model | 200+ (265+ market-data endpoints, 4 web-research services, Python sandbox) | | |
| 62 | −| Scientific libraries in the sandbox | 17 | | |
| 63 | −| Model round trips per computation | 1 (single-call paradigm) vs. several in a naïve agent | | |
| 69 | +| Tools exposed to the model | 245 schema-defined tools (17 families, Table 3) | | |
| 70 | +| Market-data wrappers | 249 typed functions over 233 endpoint paths (FMP) + 8 EODHD tools | | |
| 71 | +| Web-research tools | 14 (Firecrawl 7, Tavily 5, Exa 2) | | |
| 72 | +| Sandbox packages attempted at start-up | 29 (platform docs say 17) | | |
| 73 | +| Loop constants | batches of 5, 500 ms; truncation 3,000/15,000 chars; re-send cap 5,000; τ = 10^5 tokens, k = 5 | | |
| 74 | +| Model layer | Anthropic reference path (default `claude-fable-5`, adaptive thinking on 5 models, 64,000-token cap, temperature 1); OpenAI-compatible adapter limited to the first 128 tools | | |
| 64 | 75 | | Output formats from one artifact | PDF, DOCX, Beamer, XLSX (live formulas) | |
| 65 | −| Streaming protocol | SSE, 8 event types | | |
| 76 | +| Measurements of accuracy, hallucination, latency, cost | none (protocol in §6.6, not executed) | | |
| 66 | 77 | |
| 67 | 78 | ## 🗂 Repository layout |
| 68 | 79 | |
| 69 | 80 | ``` |
| 70 | 81 | vquant-llm-quant-platform/ |
| 71 | −└── paper/ # main.tex + sections/ + figures/ (TikZ diagrams) + tables/ + appendix/ → main.pdf | |
| 72 | − ├── figures/ # architecture, loop, context, sandbox, streaming, docpipeline (TikZ) | |
| 73 | − └── tables/ # tools, models, events, robustness | |
| 82 | +├── paper/ # main.tex + sections/ + figures/ (TikZ diagrams) + tables/ + appendix/ → main.pdf | |
| 83 | +│ ├── figures/ # architecture, loop, context, sandbox, streaming, docpipeline (TikZ) | |
| 84 | +│ └── tables/ # tools (generated by docs/verify/audit_vquant_code.py), models, events, robustness (= design rationale) | |
| 85 | +└── docs/ # REVIEW-REPORT.md, CHANGELOG-REVISION.md, main_pre-revision-20261017.pdf, verify/ (audit script + JSON) | |
| 74 | 86 | ``` |
| 75 | 87 | |
| 76 | −No `src/`, `scripts/` or `data/`: the paper has no empirical pipeline. | |
| 88 | +No `src/`, `scripts/` or `data/`: the paper has no empirical pipeline. `docs/verify/audit_vquant_code.py <clone of vquant.git>` | |
| 89 | +regenerates `paper/tables/tools.tex` and the code facts used in the text. | |
| 77 | 90 | |
| 78 | 91 | ## 🚀 Quick start |
| 79 | 92 | |
@@ -88,10 +101,11 @@ is maintained in the spbgit repository `vquant.git` and deployed on the MacLustr | ||
| 88 | 101 | |
| 89 | 102 | ## 🔬 Methodology |
| 90 | 103 | |
| 91 | −1. **Architecture description** — components, invariants and protocols are specified as implemented (§3–§4). | |
| 92 | −2. **Mechanism walkthroughs** — orchestration loop, context management, single-call computation, document pipeline (§4). | |
| 93 | −3. **Design evaluation** — qualitative robustness discussion of failure modes and mitigations (§6). | |
| 94 | −4. **Appendix** — the conventional quantitative methods automated by the platform. | |
| 104 | +1. **Architecture description** — components, data layer, model layer, as implemented at commit `e2a148a` (§3). | |
| 105 | +2. **Mechanism specification** — transport, recursive loop (Algorithm 1), batching, routing, three-stage context management (Algorithm 2), token correction, single-call convention (§4). | |
| 106 | +3. **Execution substrate, document pipeline, illustrative walk-through** — no numbers reported (§5). | |
| 107 | +4. **Design rationale, threats to validity, reproducibility, proposed evaluation protocol (not executed)** — task suite, metrics (incl. unsupported-number rate), ablations, baselines, controls (§6). | |
| 108 | +5. **Appendix** — prompt structure, persistence schema, numerical closed forms, event types, and the claim-by-claim **audit table against the code**. | |
| 95 | 109 | |
| 96 | 110 | ## 🖼 Figures & tables inventory |
| 97 | 111 | |
@@ -104,13 +118,15 @@ is maintained in the spbgit repository `vquant.git` and deployed on the MacLustr | ||
| 104 | 118 | | `figures/streaming.tex` | SSE event dispatch | |
| 105 | 119 | | `figures/docpipeline.tex` | unified document pipeline | |
| 106 | 120 | |
| 107 | −Tables (`paper/tables/*.tex`): tool catalogue, models, streaming events, robustness. | |
| 121 | +Tables (`paper/tables/*.tex`): tool catalogue (generated), model layer, streaming events, design rationale; appendix tables: persisted entities, code audit (longtable). | |
| 108 | 122 | |
| 109 | 123 | ## ⚠️ Limitations |
| 110 | 124 | |
| 111 | −- Descriptive system paper: no benchmark against alternative agent frameworks is reported. | |
| 112 | −- Tool counts and endpoint inventories reflect the platform as of June 2026. | |
| 113 | −- Reproducibility of the *design* is documented; reproducing the *platform* requires the private `vquant.git` code base and API keys. | |
| 125 | +- Design-science description only: **no evaluation** (accuracy, hallucination rate, latency, cost, ablations, baselines). The protocol of §6.6 is pre-registered in the text but has not been run. | |
| 126 | +- Describes one commit (`e2a148a`, 2026-10-02) of a system that keeps changing; counts and constants are facts about that commit. | |
| 127 | +- Outputs are not strictly reproducible (temperature 1, no seeds, model-authored code); the design is. | |
| 128 | +- Known defects surfaced by the audit and not yet fixed in the code: no recursion-depth bound; single $3/$15 price schedule for all models; six numerical handlers unreachable (not in the catalogue) while the prompt still advertises two of them; the sandbox is process isolation, not a security boundary. | |
| 129 | +- Reproducing the *platform* requires the private `vquant.git` code base and API keys. | |
| 114 | 130 | |
| 115 | 131 | ## 📝 Citation |
| 116 | 132 | |
@@ -122,7 +138,8 @@ Tables (`paper/tables/*.tex`): tool catalogue, models, streaming events, robustn | ||
| 122 | 138 | type = {Working Paper}, |
| 123 | 139 | number = {13}, |
| 124 | 140 | year = {2026}, |
| 125 | − month = {June} | |
| 141 | + month = {October}, | |
| 142 | + note = {Version 1.1} | |
| 126 | 143 | } |
| 127 | 144 | ``` |
| 128 | 145 | |
@@ -134,6 +151,7 @@ Université du Québec en Outaouais (UQO), Gatineau, QC. | ||
| 134 | 151 | |
| 135 | 152 | ## 🗒 Notes |
| 136 | 153 | |
| 154 | +- **Revision 2026-10-17 (v1.1)**: full editorial-board review — `docs/REVIEW-REPORT.md` (diagnosis, methodology verdicts, literature, maturity) and `docs/CHANGELOG-REVISION.md` (every corrected statement with its evidence in the code, references added, items not executed). Pre-revision state: git tag `pre-revision-20261017`, `docs/main_pre-revision-20261017.pdf`. Bibliography 20 → 46 entries, all verified (Crossref, arXiv, conference proceedings; one entry flagged as withdrawn by its authors). Sections 5 and 6 were renamed from "Results"/"Performance, Reliability, and Security" to "Execution Substrate … and an Illustrative Walk-Through" and "Design Rationale, Threats to Validity, and a Proposed Evaluation". | |
| 137 | 155 | - Numbering: first circulated as “Working Paper No. 10” (June 2026); renumbered **13** on 2026-10-17 because No. 10 is *The Assessment Gap in Quebec* (see `Recherche-UQO/HARMONISATION.md`). |
| 138 | −- Cover date normalised from “June 13, 2026” to “June 2026”. | |
| 139 | −- The VQuant platform code is not in this repository (spbgit `vquant.git`). | |
| 156 | +- Cover date normalised from “June 13, 2026” to “June 2026” (harmonisation), then “October 2026” (revision). | |
| 157 | +- The VQuant platform code is not in this repository (spbgit `vquant.git`); `docs/verify/` contains the audit script and its JSON outputs, not the code. | |
added
docs/CHANGELOG-REVISION.md
+197 −0
@@ -0,0 +1,197 @@ | ||
| 1 | +<!-- | |
| 2 | +Author: Simon-Pierre Boucher | |
| 3 | +Contact: simon-pierre.boucher@uqo.ca | |
| 4 | +--> | |
| 5 | + | |
| 6 | +# CHANGELOG — Révision scientifique complète (editorial board, 2026-10-17) | |
| 7 | + | |
| 8 | +Papier : **WP 13 — VQuant: An Agentic Large Language Model Architecture for Automated Quantitative | |
| 9 | +Financial Analysis and Document Generation** (`finance/vquant-llm-quant-platform`, dépôt `wp13_uqo.git`). | |
| 10 | +État de départ figé : tag `pre-revision-20261017`, PDF `docs/main_pre-revision-20261017.pdf` (28 pages, v1.0, June 2026). | |
| 11 | +État d'arrivée : `paper/main.pdf` (41 pages, v1.1, October 2026). Pas de `main_anon.tex` (papier jamais soumis). | |
| 12 | +Rapport scientifique : `docs/REVIEW-REPORT.md`. | |
| 13 | + | |
| 14 | +Le papier ne contient ni données ni code ; la « réanalyse » possible était l'**audit de la description | |
| 15 | +contre le code réel** de la plateforme. Il a été fait sur un clone en lecture seule de `gitsrv:srv/git/vquant.git` | |
| 16 | +(HEAD `e2a148a`, « adopt: état déployé sur M2U64 … », 2026-10-02 ; commits antérieurs `cfe8ef7` et `9215dce`, | |
| 17 | +2026-08-05). Script versionné : `docs/verify/audit_vquant_code.py` ; sorties : `docs/verify/code_facts.json`, | |
| 18 | +`docs/verify/tool_families.json` ; table générée : `paper/tables/tools.tex`. | |
| 19 | + | |
| 20 | +Convention : **C** = correction (énoncé démontrablement faux), **A** = ajout/renforcement, **E** = éditorial. | |
| 21 | + | |
| 22 | +--- | |
| 23 | + | |
| 24 | +## 1. Corrections majeures (où, avant → après, preuve) | |
| 25 | + | |
| 26 | +### C1 — Le papier se présentait comme rapportant des « résultats » et une « robustesse » sans aucune mesure | |
| 27 | +- **Où** : titres de §5 (« Execution Substrate and Document Generation » dans un fichier `results.tex`) et §6 | |
| 28 | + (« Performance, Reliability, and Security », fichier `robustness.tex`), Table 4 (« Operational characteristics » | |
| 29 | + avec latences « indicatives »), résumé (« principal innovations »), conclusion. | |
| 30 | +- **Avant** : Table 4 donnait « sub-second perceived response », « several seconds », « roughly ten seconds » | |
| 31 | + sans aucune mesure ; §6.1 affirmait que le single-call « removes the dominant source of latency ». | |
| 32 | +- **Après** : §5 renommée « Execution Substrate, Document Generation, and an Illustrative Walk-Through » | |
| 33 | + (walk-through = *demonstration* au sens design science, sans chiffre) ; §6 renommée « Design Rationale, | |
| 34 | + Threats to Validity, and a Proposed Evaluation » ; Table 4 → « Design rationale » (mécanisme, constante | |
| 35 | + réelle, propriété visée, mesure qui la testerait) ; toutes les latences chiffrées retirées ; §6.6 | |
| 36 | + « A proposed evaluation protocol (not executed) » (suite de tâches, métriques dont le *unsupported-number | |
| 37 | + rate*, ablations, baselines, contrôles). Le résumé dit explicitement « The paper reports no empirical | |
| 38 | + evaluation ». | |
| 39 | +- **Preuve** : absence totale de script, de données ou de journal de mesure dans le dépôt du papier et dans | |
| 40 | + `vquant.git` (6 suites de tests unitaires seulement). | |
| 41 | + | |
| 42 | +### C2 — Comptes d'outils et de bibliothèques | |
| 43 | +- **Avant** : « more than two hundred tools », « over 265 market-data endpoints, wrapped by roughly 230 typed | |
| 44 | + functions », « seventeen scientific libraries », « four web-research services », Table 3 avec des « 40+ », « 8+ ». | |
| 45 | +- **Après** : **245** outils définis par schéma (`toolDefinitions.ts`, noms uniques), **249** fonctions exportées | |
| 46 | + sur **233** chemins d'endpoint distincts (`fmpService.ts`), **29** paquets tentés à l'import par le sandbox | |
| 47 | + (`customPythonExecutor.py` ; la doc de la plateforme dit 17), **3** services web exposés en **14** outils | |
| 48 | + (Firecrawl 7, Tavily 5, Exa 2 ; SerpAPI est intégré côté serveur mais sans définition d'outil). Table 3 | |
| 49 | + régénérée par script avec des comptes exacts par famille (17 familles). | |
| 50 | +- **Preuve** : `docs/verify/code_facts.json`, `docs/verify/tool_families.json`. | |
| 51 | + | |
| 52 | +### C3 — « Exact tokenizer for billing » / le tokenizer piloterait le déclencheur de contexte | |
| 53 | +- **Avant** (§4.7 et §6.2) : « an exact tokenizer for billing » ; §6.2 : « VQuant estimates token counts locally | |
| 54 | + with a tokenizer before each call, which both drives the context-management trigger … ». | |
| 55 | +- **Après** : le comptage local utilise le paquet npm `gpt-tokenizer` (BPE OpenAI), donc une **approximation** | |
| 56 | + dont le signe d'erreur n'est pas fixé ; il ne couvre que le texte de réponse (pas les tokens de raisonnement) ; | |
| 57 | + le déclencheur de contexte utilise l'heuristique chars/4, pas le tokenizer. Barème de coût unique 3 $/15 $ par | |
| 58 | + million pour **tous** les modèles → le grand livre est faux pour tout modèle au prix différent (limite ajoutée). | |
| 59 | +- **Preuve** : `claudeService.ts` l. 2, 44–47, 112–114, 160–175. | |
| 60 | + | |
| 61 | +### C4 — Outils numériques « exposés au modèle » | |
| 62 | +- **Avant** (§5.2) : « the platform exposes a small set of pre-built numerical tools … a Monte Carlo path simulator, | |
| 63 | + a closed-form European option pricer, a GARCH(1,1) estimator, and a Value-at-Risk calculator ». | |
| 64 | +- **Après** : seul `calculate_options_price` est dans le catalogue ; les handlers `run_monte_carlo_simulation`, | |
| 65 | + `estimate_garch_volatility`, `calculate_var`, `optimize_portfolio`, `analyze_risk_metrics`, `create_plot` | |
| 66 | + existent dans `routes.ts` (l. 764–1019) mais n'ont **aucune définition d'outil** → injoignables ; le prompt | |
| 67 | + système cite encore `run_monte_carlo_simulation` et `create_volatility_surface` (`systemPrompt.ts` l. 67, 80). | |
| 68 | + §5.2 réécrite ; Appendix C précise que ces routines servent de référence pour le protocole d'évaluation. | |
| 69 | + | |
| 70 | +### C5 — Couche modèle « Claude only » | |
| 71 | +- **Avant** (§3.5, Table 1) : « model-agnostic within the Claude family », modèles non nommés. | |
| 72 | +- **Après** : chemin de référence Anthropic (défaut `claude-fable-5` ; thinking adaptatif pour fable-5, | |
| 73 | + opus-4-8/4-7/4-6, sonnet-4-6 ; haiku-4-5 sans ; `max_tokens` 64 000 ; température 1) **et** un second | |
| 74 | + adaptateur OpenAI-compatible (OpenAI + Google) limité aux **128 premiers outils** ; appel Beamer épinglé à | |
| 75 | + `claude-opus-4-8`. Identifiants Anthropic vérifiés (liste de modèles du fournisseur) ; identifiants | |
| 76 | + OpenAI/Google reproduits sans audit et signalés comme tels. | |
| 77 | +- **Preuve** : `client/src/lib/models.ts`, `claudeService.ts` l. 18–21, 84–96, `openaiService.ts` l. 14–16, 60–63, | |
| 78 | + `beamerSlidesService.ts` l. 236 ; `git show 9215dce` confirme que le multi-fournisseur existait déjà en août 2026. | |
| 79 | + | |
| 80 | +### C6 — Authentification, limites, BYOK, schéma de persistance | |
| 81 | +- **Avant** (§6.3, Appendix B) : « local accounts and third-party single sign-on », « daily limits that differ for | |
| 82 | + anonymous and authenticated users », « bring-your-own-keys », entité Users avec « optional encrypted custom API | |
| 83 | + keys », entité « Daily usage ». | |
| 84 | +- **Après** : aucune de ces fonctions n'existe dans **aucun** commit (`shared/schema.ts`, `schema-sqlite.ts`, | |
| 85 | + `auth.ts`, grep `daily|apiKey|oauth|google` vide, y compris sur `9215dce`). Réel : comptes locaux | |
| 86 | + e-mail + mot de passe, code à usage unique par courriel, appareils de confiance, limitation des tentatives, | |
| 87 | + journal de sécurité ; 12 entités persistées. §6.2 et Appendix B réécrites ; retrait explicite des trois affirmations. | |
| 88 | + | |
| 89 | +### C7 — Contexte : troisième étage manquant et constantes | |
| 90 | +- **Avant** : deux étapes (cap 5 000 chars, puis résumé). | |
| 91 | +- **Après** : **trois** étapes : (1) troncature à l'exécution 3 000 chars (15 000 pour les 14 outils d'extraction | |
| 92 | + et le Python) `routes.ts` l. 1860–1885 ; (2) cap de renvoi 5 000 ; (3) résumé si > 10^5 tokens, 5 derniers | |
| 93 | + messages, entrée ≤ 10 000 chars, `max_tokens` 2 000, température 0,5, repli 500 premiers caractères | |
| 94 | + (`tokenManagement.ts` l. 64–105). Algorithme 2 réécrit avec ces constantes ; Algorithme 1 intègre | |
| 95 | + `PrepareContext`, l'événement `status` par lot et la troncature. | |
| 96 | + | |
| 97 | +### C8 — Boucle : contenu du tour assistant et absence de borne | |
| 98 | +- **Ajouté** : le message assistant ne contient que les blocs `tool_use` (ni texte ni blocs de raisonnement), | |
| 99 | + la récursion n'a pas de profondeur maximale (`routes.ts` l. 420–495). Signalés comme points de durcissement. | |
| 100 | + | |
| 101 | +### C9 — Référence Kim–Muhn–Nikolaev (2024) | |
| 102 | +- **Avant** : citée comme preuve que « LLMs can analyze financial statements at a level competitive with human | |
| 103 | + analysts ». | |
| 104 | +- **Après** : l'arXiv 2407.17866 a été **retiré par les auteurs le 2025-02-20** (« inconsistencies in the data and | |
| 105 | + analyses ») ; l'affirmation est retirée du texte, la référence conservée en note de bas de page avec le statut | |
| 106 | + de retrait (SSRN 4835311). Preuve : page arXiv consultée le 2026-10-17. | |
| 107 | + | |
| 108 | +### C10 — Lopez-Lira & Tang : publié | |
| 109 | +- **Avant** : arXiv 2304.07619 (2023). **Après** : *Journal of Financial Economics* 184 (2026) 104335, | |
| 110 | + DOI 10.1016/j.jfineco.2026.104335 (Crossref). Clé `lopezlira2026chatgpt`. | |
| 111 | + | |
| 112 | +## 2. Ajouts (A) | |
| 113 | + | |
| 114 | +- **A1** Cadrage design science (Hevner et al. 2004 ; Peffers et al. 2007 ; Gregor & Hevner 2013) : §1 « What kind | |
| 115 | + of paper this is », §2.1, conclusion. | |
| 116 | +- **A2** Paragraphe « Terminology » (agentic, tool use, reasoning-capable) en §1. | |
| 117 | +- **A3** Paragraphe « Audit against the code » en §1 + **Appendix E** : table de 33 énoncés → fichier:lignes → | |
| 118 | + énoncé v1.0 (longtable). | |
| 119 | +- **A4** §2.3 « Evaluating LLM agents » (AgentBench, Reflexion, WebGPT, LLM-as-a-judge, FinanceBench, FinBen, | |
| 120 | + survey Chang et al.) ; §2.2 enrichie (PoT, Mialon, Gorilla, ToolLLM, Lost in the Middle, MCP) ; §2.4 enrichie | |
| 121 | + (Loughran–McDonald, Gentzkow–Kelly–Taddy, Li–Mai–Shen–Yan, Chen–Kelly–Xiu, Hansen–Kazinnik, Li et al. ICAIF, | |
| 122 | + Fatouros et al., Korinek, Dell). | |
| 123 | +- **A5** §5.4 « An illustrative walk-through » (flux de contrôle d'une requête, aucun chiffre). | |
| 124 | +- **A6** §6.4 « Threats to validity » (design vs description), §6.5 « Reproducibility » (température 1 / 0,5, | |
| 125 | + pas de graine, code écrit par le modèle, dépendance CDN KaTeX et TeX local), §6.6 protocole d'évaluation. | |
| 126 | +- **A7** Équations numérotées en Appendix C (GBM, d1/d2, GARCH) ; demi-vie explicitée. | |
| 127 | +- **A8** Figures : compteurs mis à jour (architecture : « 2 providers · 233 endpoints », « 29 packages », | |
| 128 | + « 3 services · 14 tools » ; sandbox : « 29 pkgs »). | |
| 129 | + | |
| 130 | +## 3. Éditorial (E) | |
| 131 | + | |
| 132 | +- Résumé réécrit (« design-science description », « reports no empirical evaluation ») ; mots-clés et JEL (+O33). | |
| 133 | +- Suppression du vocabulaire promotionnel (« production-grade », « remarkable », « unusually broad », « strategically | |
| 134 | + engineered », « innovations ») ; « agentic financial intelligence » retiré de la conclusion. | |
| 135 | +- Orthographe britannique uniformisée (summarise, visualisation…) ; `\path` pour les chemins de fichiers ; tables en | |
| 136 | + `\footnotesize` avec colonnes `p{}` (0 Overfull > 10 pt ; un Overfull résiduel de 5,8 pt dans l'Appendix B). | |
| 137 | +- Métadonnées : `\WPversion` 1.0 → 1.1, `\WPdate` June 2026 → October 2026 ; page titre canonique inchangée. | |
| 138 | + | |
| 139 | +## 4. Références | |
| 140 | + | |
| 141 | +Avant : 20 entrées, aucune avec DOI. Après : **46 entrées**, DOI ou identifiant arXiv/SSRN pour toutes celles qui | |
| 142 | +en ont. Vérification le 2026-10-17 : Crossref `api.crossref.org/works?query.bibliographic=` (30 requêtes), | |
| 143 | +API arXiv `export.arxiv.org/api/query?id_list=` (22 identifiants), OpenAlex, pages PMLR / ICLR / TMLR | |
| 144 | +(mlanthology, proceedings.iclr.cc), page docs Anthropic, spécification MCP, registre npm (gpt-tokenizer). | |
| 145 | + | |
| 146 | +| Référence ajoutée | Vérification | | |
| 147 | +|---|---| | |
| 148 | +| Hevner, March, Park, Ram 2004 MISQ 28(1) 75–105 | Crossref 10.2307/25148625 | | |
| 149 | +| Peffers et al. 2007 JMIS 24(3) 45–77 | Crossref 10.2753/MIS0742-1222240302 | | |
| 150 | +| Gregor & Hevner 2013 MISQ 37(2) 337–355 | Crossref 10.25300/MISQ/2013/37.2.01 | | |
| 151 | +| Liu et al. 2024 TACL 12 157–173 (Lost in the Middle) | Crossref 10.1162/tacl_a_00638 | | |
| 152 | +| Ji et al. 2023 ACM CSUR 55(12) | Crossref 10.1145/3571730 | | |
| 153 | +| Chen, Ma, Wang, Cohen 2023 TMLR (Program of Thoughts) | arXiv 2211.12588 + mlanthology TMLR 2023 | | |
| 154 | +| Mialon et al. 2023 TMLR (Augmented LMs survey) | arXiv 2302.07842 + mlanthology TMLR 2023 | | |
| 155 | +| Patil et al. 2024 NeurIPS 37 (Gorilla) | Crossref 10.52202/079017-4020 | | |
| 156 | +| Qin et al. 2024 ICLR (ToolLLM) | arXiv 2307.16789 + proceedings.iclr.cc 2024 | | |
| 157 | +| Liu et al. 2024 ICLR (AgentBench) | arXiv 2308.03688 + proceedings.iclr.cc 2024 | | |
| 158 | +| Shinn et al. 2023 NeurIPS 36 (Reflexion) | Crossref 10.52202/075280-0377 | | |
| 159 | +| Nakano et al. 2021 arXiv (WebGPT) | arXiv 2112.09332 | | |
| 160 | +| Wang et al. 2024 Frontiers of Computer Science 18(6) | Crossref 10.1007/s11704-024-40231-1 | | |
| 161 | +| Anthropic 2026, « Tool use with Claude » (docs) | page consultée (platform.claude.com) | | |
| 162 | +| Model Context Protocol, spécification 2025-06-18 | page consultée (modelcontextprotocol.io) | | |
| 163 | +| Zheng et al. 2023 NeurIPS 36 (LLM-as-a-judge) | Crossref 10.52202/075280-2020 | | |
| 164 | +| Chang et al. 2024 ACM TIST 15(3) | Crossref 10.1145/3641289 | | |
| 165 | +| Islam et al. 2023 arXiv (FinanceBench) | arXiv 2311.11944 | | |
| 166 | +| Xie et al. 2024 NeurIPS 37 (FinBen) | OpenAlex / Crossref 10.52202/079017-3033 | | |
| 167 | +| Loughran & McDonald 2016 JAR 54(4) 1187–1230 | Crossref 10.1111/1475-679X.12123 | | |
| 168 | +| Gentzkow, Kelly, Taddy 2019 JEL 57(3) 535–574 | Crossref 10.1257/jel.20181020 | | |
| 169 | +| Li, Mai, Shen, Yan 2021 RFS 34(7) 3265–3315 | Crossref 10.1093/rfs/hhaa079 | | |
| 170 | +| Li, Wang, Ding, Chen 2023 ICAIF 374–382 | Crossref 10.1145/3604237.3626869 | | |
| 171 | +| Chen, Kelly, Xiu 2023 (working paper) | titre/auteurs confirmés par la présentation Wharton Jacobs Levy (sept. 2024) et listes de séminaires ; page SSRN inaccessible (403) → pas de numéro SSRN cité | | |
| 172 | +| Hansen & Kazinnik 2023 SSRN 4399406 | Crossref 10.2139/ssrn.4399406 | | |
| 173 | +| Fatouros et al. 2025 Neural Computing and Applications 37(30) 24893–24918 | Crossref 10.1007/s00521-024-10613-4 (print 2025-10) | | |
| 174 | +| Korinek 2023 JEL 61(4) 1281–1317 | Crossref 10.1257/jel.20231736 | | |
| 175 | +| Dell 2025 JEL 63(1) 5–58 | Crossref 10.1257/jel.20241733 | | |
| 176 | + | |
| 177 | +Références existantes corrigées : Vaswani (pages 5998–6008), Wei (DOI), Toolformer (pages 68539–68551, DOI), PAL | |
| 178 | +(PMLR 202), Lopez-Lira & Tang (JFE 2026, C10), Kim et al. (statut retiré, C9), Black–Scholes, Merton, Engle, | |
| 179 | +Bollerslev, Glasserman (DOI ajoutés), Anthropic doc (titre/URL actuels). Aucune référence retirée ; aucune non vérifiée. | |
| 180 | + | |
| 181 | +## 5. Réanalyses exécutées | |
| 182 | + | |
| 183 | +| Analyse | Script / commande | Durée | Sortie | | |
| 184 | +|---|---|---|---| | |
| 185 | +| Audit du code (comptes, constantes, handlers injoignables, familles d'outils) | `docs/verify/audit_vquant_code.py /tmp/vquant` | < 5 s | `code_facts.json`, `tool_families.json`, `paper/tables/tools.tex` | | |
| 186 | +| Vérification de l'historique git de `vquant.git` (3 commits ; multi-fournisseur et EODHD présents dès `9215dce`) | `git log`, `git show 9215dce --stat`, `git show 9215dce:client/src/lib/models.ts` | — | consigné ici | | |
| 187 | + | |
| 188 | +## 6. Non modifié / non exécuté (faute de données ou hors périmètre) | |
| 189 | + | |
| 190 | +- **Protocole d'évaluation de §6.6** : non exécuté (nécessite des clés API, un instantané de données figé, deux | |
| 191 | + évaluateurs humains). Décrit comme pré-enregistrement. | |
| 192 | +- **Corrections du code** (borne de récursion, barème de prix par modèle, réintégration des outils numériques dans le | |
| 193 | + catalogue, cohérence prompt/catalogue, conteneurisation du sandbox) : relèvent de `vquant.git` (remote-first, | |
| 194 | + nœud M2U64), **non faites** dans le cadre de la révision du papier ; listées en §7 et en conclusion. | |
| 195 | +- Identifiants de modèles OpenAI/Google du sélecteur : non audités (hors connaissance vérifiable), signalés comme tels. | |
| 196 | +- Pas de version anonyme (`main_anon.tex`) : le papier n'a jamais été soumis ; à créer avant soumission selon | |
| 197 | + `HARMONISATION.md` §7. | |
added
docs/REVIEW-REPORT.md
+120 −0
@@ -0,0 +1,120 @@ | ||
| 1 | +<!-- | |
| 2 | +Author: Simon-Pierre Boucher | |
| 3 | +Contact: simon-pierre.boucher@uqo.ca | |
| 4 | +--> | |
| 5 | + | |
| 6 | +# REVIEW REPORT — Editorial board, révision scientifique complète (2026-10-17) | |
| 7 | + | |
| 8 | +**Papier** : WP 13 — *VQuant: An Agentic Large Language Model Architecture for Automated Quantitative Financial | |
| 9 | +Analysis and Document Generation* (v1.0, June 2026 → v1.1, October 2026 ; ex « WP 10 », jamais audité, jamais soumis). | |
| 10 | +**Board** : systèmes d'information (design science), LLM et agents, finance computationnelle, méthodologie de la | |
| 11 | +recherche en systèmes. | |
| 12 | +**Revues de référence** : *Journal of Financial Data Science*, *Decision Support Systems*, *Expert Systems with | |
| 13 | +Applications*, *ACM TMIS*, *Information Systems Research* ; *JEL* pour la littérature IA-économie. | |
| 14 | +**Journal des modifications** : `docs/CHANGELOG-REVISION.md`. **Preuves** : `docs/verify/` (script d'audit, JSON), | |
| 15 | +clone lecture seule de `vquant.git` (commit `e2a148a`). | |
| 16 | + | |
| 17 | +--- | |
| 18 | + | |
| 19 | +## 1. Verdict d'ensemble | |
| 20 | + | |
| 21 | +Le manuscrit v1.0 est un **papier système sans évaluation**. Il décrit avec soin et, pour l'essentiel, exactement | |
| 22 | +une architecture réelle (boucle d'outils récursive en streaming, gestion de contexte, sandbox Python, pipeline | |
| 23 | +documentaire), mais il présentait cette description sous les étiquettes d'un papier empirique — fichiers | |
| 24 | +`results.tex`/`robustness.tex`, section « Performance, Reliability, and Security », table de « caractéristiques | |
| 25 | +opérationnelles » avec des latences non mesurées, résumé parlant d'« innovations » — sans aucune mesure | |
| 26 | +d'exactitude numérique, de taux d'hallucination, de latence, de coût, d'ablation ni de baseline. Il n'y a rien à | |
| 27 | +recalculer : il n'y a ni données ni scripts. La seule vérification possible — **confronter la description au | |
| 28 | +code** — a été faite ligne par ligne et a révélé une dizaine d'écarts, dont trois substantiels : (i) des fonctions | |
| 29 | +décrites (SSO, plafonds quotidiens, bring-your-own-keys, clés API chiffrées) **n'existent dans aucun commit** ; | |
| 30 | +(ii) quatre « outils numériques exposés au modèle » n'ont **pas de définition d'outil** et sont donc injoignables | |
| 31 | +(seul le pricer d'options l'est) ; (iii) la « correction exacte » du comptage de tokens repose sur un tokenizer | |
| 32 | +OpenAI appliqué à des sorties Claude. La couche modèle décrite comme « Claude only » est multi-fournisseur depuis | |
| 33 | +au moins août 2026, et une référence centrale de la revue de littérature (Kim–Muhn–Nikolaev 2024) a été retirée par | |
| 34 | +ses auteurs en février 2025. | |
| 35 | + | |
| 36 | +La révision a (1) **requalifié** le papier en contribution de design science (implémentation située + | |
| 37 | +démonstration, évaluation spécifiée mais non exécutée), avec un résumé qui dit ce qu'il ne contient pas ; | |
| 38 | +(2) **corrigé** chaque écart avec le code et ajouté une table d'audit (33 énoncés → fichier:lignes) ; | |
| 39 | +(3) remplacé les « résultats » par une table de **rationale** (mécanisme, constante, propriété visée, mesure qui | |
| 40 | +la testerait), un **walk-through** sans chiffre, des **menaces à la validité** et une section **reproductibilité** | |
| 41 | +honnête (température 1, pas de graine, code écrit par le modèle) ; (4) rédigé un **protocole d'évaluation | |
| 42 | +pré-enregistré** (suite de tâches, métriques dont le taux de nombres non étayés, ablations, baselines, contrôles), | |
| 43 | +explicitement non exécuté ; (5) vérifié les 20 références et porté la bibliographie à 46 entrées toutes vérifiées. | |
| 44 | + | |
| 45 | +**Le papier révisé est honnête et reproductible dans sa description, mais il n'est pas publiable en l'état dans une | |
| 46 | +revue empirique** : sa valeur scientifique dépend de l'exécution du protocole de §6.6. Voir §7. | |
| 47 | + | |
| 48 | +## 2. Diagnostic par section (v1.0 → v1.1) | |
| 49 | + | |
| 50 | +| Section | Forces (v1.0) | Faiblesses / erreurs trouvées | Traitement | | |
| 51 | +|---|---|---|---| | |
| 52 | +| Titre / résumé | Problème (grounding) bien posé | « production-grade », « innovations », « remarkable » ; aucune mention de l'absence d'évaluation ; comptes faux (200+/265+/17/4) | Résumé réécrit : design science, comptes audités, « reports no empirical evaluation » ; titre et sous-titre conservés | | |
| 53 | +| Introduction | Division du travail modèle/code claire ; 4 contributions | « Contributions … methodological and architectural rather than empirical » mais le reste du texte parle de résultats ; termes « agentic », « tool use », « reasoning » non définis ; pas de genre déclaré | Paragraphes « What kind of paper this is », « Audit against the code », « Terminology » ; contributions reformulées + protocole comme 5e contribution | | |
| 54 | +| Related work | Quatre axes pertinents ; classiques présents | 20 réf., 0 DOI ; rien sur l'évaluation des agents, sur la sélection d'outils à grande échelle (Gorilla, ToolLLM), sur les longs contextes, sur le design science ; Kim et al. retiré ; Lopez-Lira & Tang publié depuis | 5 sous-sections, 46 réf. vérifiées ; §2.1 design science ; §2.3 évaluation ; note sur le retrait de Kim et al. | | |
| 55 | +| Architecture (§3) | Trois tiers, SSE, ORM bien décrits | « Claude family » (faux depuis août 2026) ; second fournisseur EODHD absent ; « four web services » (3 exposés) ; schéma inventé (clés chiffrées, daily usage) ; comptes approximatifs | Tout réaligné sur `e2a148a` ; Table 1 avec identifiants Anthropic vérifiés, adaptateur OpenAI-compatible (cap 128 outils), appel Beamer épinglé | | |
| 56 | +| Méthodologie (§4) | Description fidèle du parseur SSE, de la récursion, du batching, de la summarisation | Troncature à l'exécution (3 000/15 000) omise ; constantes du résumé (2 000 tokens, T = 0,5, repli 500) non données ; « exact tokenizer » faux ; barème de coût unique non dit ; tour assistant sans texte ni thinking non dit ; pas de borne de récursion ; outils cités dans le prompt mais absents du catalogue | Algorithmes 1–2 réécrits avec les constantes réelles ; §4.7 corrigée ; §4.8 « convention » (appliquée par instruction, pas par code) ; incohérence prompt/catalogue signalée | | |
| 57 | +| « Results » (§5) | Sandbox et pipeline PDF/Beamer/DOCX exacts | Section nommée comme des résultats ; 17 bibliothèques (29 tentées) ; quatre outils numériques « exposés » (un seul l'est) ; dépendance CDN KaTeX et figures éphémères non dites | Renommée ; §5.2 corrigée ; §5.4 walk-through de contrôle (sans chiffre) | | |
| 58 | +| « Robustness » (§6) | §6.5 Limitations déjà honnête | Table 4 de latences « indicatives » sans mesure ; §6.2 contredit §4.7 ; §6.3 décrit SSO/limites/BYOK inexistants ; « sandbox » présenté comme sécurité | Renommée ; Table 4 → rationale ; §6.2 authentification réelle ; §6.3 sécurité avec modèle de menace ; §6.4 menaces ; §6.5 reproductibilité ; §6.6 protocole | | |
| 59 | +| Conclusion | Agenda d'évaluation esquissé | Reprend « innovations », « agentic financial intelligence » | Réécrite : situated implementation + demonstration ; trois corrections de code recommandées ; pattern présenté comme hypothèse | | |
| 60 | +| Annexes | Structure du prompt, formules classiques | Schéma faux (C6) ; événements client incomplets (15 types émis) ; pas d'équations numérotées | Appendix B corrigée (12 entités) ; D : 15 types ; C : équations (1)–(3) ; **E : table d'audit** | | |
| 61 | +| Figures (TikZ) | Lisibles, cohérentes | Compteurs périmés (265+, 17, 4) | Mis à jour ; un Overfull de 16 pt corrigé | | |
| 62 | + | |
| 63 | +## 3. Méthodologie — verdict motivé (points du §3 du master prompt, adaptés à un papier système) | |
| 64 | + | |
| 65 | +| Point | Verdict | Motif / action | | |
| 66 | +|---|---|---| | |
| 67 | +| Spécification de l'artefact justifiée | Oui (v1.1) | Chaque décision reliée à une propriété visée et à une mesure (Table 4) ; genre design science déclaré | | |
| 68 | +| Hypothèses explicites | Oui (v1.1) | Constantes réelles (5/500 ms ; 3 000/15 000/5 000 ; 10^5 ; k = 5 ; 2 000 ; 0,5 ; 64 000 ; T = 1 ; 90 s ; 150 dpi) et leur origine (jugement, pas mesure) | | |
| 69 | +| Définitions correctes | Oui | « agentic », « tool use », « reasoning-capable » définis ; « convention » vs « mécanisme » distingués | | |
| 70 | +| Correspondance description ↔ implémentation | **Non en v1.0 → Oui en v1.1** | 33 énoncés tracés (Appendix E) ; 10 corrections | | |
| 71 | +| Inférence / robustesse | Sans objet | Aucune statistique dans le papier ; aucune n'a été inventée | | |
| 72 | +| Interprétation vs mécanisme établi | Oui (v1.1) | Toute affirmation de gain (latence, hallucination) reformulée en hypothèse testable | | |
| 73 | +| Claims causaux / de supériorité | Retirés | « materially reduces latency », « largest latency saving », « eliminates » → hypothèses du protocole | | |
| 74 | +| Reproductibilité | Partielle, documentée | Design reproductible ; sorties non (T = 1, pas de graine, code généré) ; chaque nombre d'un rapport l'est à partir des entrées persistées | | |
| 75 | +| Sécurité (spécifique) | Qualifiée | Isolation par processus ≠ frontière de sécurité ; guardrail de prompt sans garantie | | |
| 76 | + | |
| 77 | +## 4. Littérature | |
| 78 | + | |
| 79 | +- **Vérifiées** : les 20 références initiales (Crossref/arXiv/PMLR) ; corrections de pages/DOI pour 9 d'entre elles ; | |
| 80 | + Lopez-Lira & Tang passée en JFE 2026 ; Kim et al. marquée retirée. | |
| 81 | +- **Ajoutées (26)** : design science (3), LLM/agents/contexte (9), évaluation (6), finance-économie (8) — toutes avec | |
| 82 | + DOI ou identifiant arXiv/SSRN/venue (liste et sources dans le changelog §4). | |
| 83 | +- **Non ajoutées faute de vérification complète** : aucune ; Chen–Kelly–Xiu citée comme working paper sans numéro SSRN | |
| 84 | + (page SSRN inaccessible), existence confirmée par la présentation Wharton Jacobs Levy et des listes de séminaires. | |
| 85 | +- **Retirées** : aucune. | |
| 86 | + | |
| 87 | +## 5. Résultats — incohérences trouvées | |
| 88 | + | |
| 89 | +Il n'y a pas de résultats empiriques. Incohérences internes de v1.0 corrigées : §6.2 vs §4.7 sur le rôle du | |
| 90 | +tokenizer ; Appendix D (9 types d'événements « principaux ») vs code (15) ; Table 3 (« 200+ ») vs README de la | |
| 91 | +plateforme (213) vs code (245) ; §3.5 « Claude family » vs sélecteur à trois fournisseurs ; §5.2 vs catalogue | |
| 92 | +d'outils ; §6.3/Appendix B vs schéma. | |
| 93 | + | |
| 94 | +## 6. Analyses recommandées non exécutées | |
| 95 | + | |
| 96 | +1. **Protocole §6.6** (≈ 350 tâches, 3 répétitions, 6 ablations, 4 baselines, instantané de données figé) — le | |
| 97 | + cœur de ce qui manque. Coût estimé : quelques centaines de dollars d'API et deux évaluateurs humains pour les | |
| 98 | + 50 rapports. | |
| 99 | +2. **Rétention d'information après summarisation** (faits plantés en début de session, seuils 5·10^4 / 10^5 / 2·10^5, | |
| 100 | + k = 3/5/10). | |
| 101 | +3. **Taux de désobéissance à la convention single-call** et taux d'échec du sandbox par cause. | |
| 102 | +4. **Audit de facturation** : grand livre vs facture fournisseur sur un mois (le barème unique 3 $/15 $ est faux | |
| 103 | + pour plusieurs modèles). | |
| 104 | +5. **Test de pénétration du sandbox** (le processus enfant a les privilèges et le réseau du serveur). | |
| 105 | + | |
| 106 | +## 7. Maturité pour publication | |
| 107 | + | |
| 108 | +- **État** : description de système honnête, précise et auditée ; aucune preuve empirique. En vocabulaire design | |
| 109 | + science : *situated implementation* + *demonstration* ; *evaluation* manquante. | |
| 110 | +- **Revue cible réaliste aujourd'hui** : aucune revue empirique n'acceptera le papier sans §6.6 exécutée. Options : | |
| 111 | + (a) **exécuter le protocole** puis viser *Decision Support Systems* ou *Expert Systems with Applications* (papier | |
| 112 | + système + évaluation) ou *Journal of Financial Data Science* (angle finance) ; (b) en l'état, un atelier | |
| 113 | + « systems/demo » (ICAIF demo track, FinNLP) ou un dépôt comme *working paper* technique. | |
| 114 | +- **Risques de rejet** : absence d'évaluation (rédhibitoire en revue) ; dépendance à des API propriétaires et à un | |
| 115 | + code privé (reproductibilité limitée au design) ; contribution perçue comme ingénierie plutôt que comme | |
| 116 | + connaissance de design (il faudrait au moins formuler des principes de design testables, ce que la Table 4 | |
| 117 | + amorce) ; évolution rapide des modèles (identifiants et constantes datés). | |
| 118 | +- **Corrections de code à faire avant toute évaluation** (dans `vquant.git`, remote-first) : borne de récursion ; | |
| 119 | + barème de prix par modèle ; réintégration des outils numériques dans le catalogue ou retrait du prompt ; | |
| 120 | + vérification au démarrage des dépendances (TeX, CDN KaTeX) ; graine optionnelle pour le Monte Carlo. | |
added
docs/verify/audit_vquant_code.py
+97 −0
@@ -0,0 +1,97 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +"""Audit of the VQuant description against the platform code (vquant.git, commit e2a148a, 2026-10-02). | |
| 3 | + | |
| 4 | +Usage: python3 audit_vquant_code.py /path/to/vquant-clone | |
| 5 | +Writes: tool_families.json, code_facts.json and ../../paper/tables/tools.tex (generated table). | |
| 6 | +Run on 2026-10-17 for the editorial-board revision of UQO WP 13. | |
| 7 | +""" | |
| 8 | +import re, json, sys, os, collections, pathlib | |
| 9 | +root = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else '/tmp/vquant') | |
| 10 | +here = pathlib.Path(__file__).resolve().parent | |
| 11 | +paper_tables = here.parent.parent / 'paper' / 'tables' | |
| 12 | + | |
| 13 | +src = (root / 'server/services/claude/toolDefinitions.ts').read_text() | |
| 14 | +names = sorted(set(re.findall(r"name: '([a-zA-Z0-9_]+)'", src))) | |
| 15 | +rules = [ | |
| 16 | + ('Global market data (EODHD)', r'eodhd'), | |
| 17 | + ('Fundamentals, valuation and classification', r'(income_statement|balance_sheet|cash_?flow|key_metrics|ratios|financial_(growth|scores|statement)|enterprise_values|owner_earnings|dcf|revenue_|market_capitalization|shares_float|company_profile|company_outlook|key_executives|profile_by_cik|latest_financial_statements|peers|stock_screener|stock_price_change|industry_pe|sector_pe|industry_performance|sector_performance|industry_classification|available_|exchange|sec_company_full_profile)'), | |
| 18 | + ('SEC filings, transcripts and ownership', r'(sec_filings|8k|cik|company_notes|transcript|form_13f|institutional|mutual_fund_disclosure|holder|positions_summary|beneficial_ownership|crowdfunding|equity_offering|ipo_prospectus|ipo_disclosures|filings_extract)'), | |
| 19 | + ('Events, calendars and corporate actions', r'(calendar|dividend|split|ipo|earnings_report|mergers_acquisitions|symbol_change|delisted|market_hours|holidays)'), | |
| 20 | + ('Forex, crypto and commodities', r'(forex|crypto|commodit)'), | |
| 21 | + ('Web research (Firecrawl, Tavily, Exa)', r'^(firecrawl_|tavily_|web_search_exa|get_contents_exa)'), | |
| 22 | + ('Insider and congressional trading', r'(insider|congressional|senate|house_)'), | |
| 23 | + ('Indices, ETFs and funds', r'(constituent|etf_|index_list|sp500|nasdaq|dow_jones|mutualfund)'), | |
| 24 | + ('Quotes, prices and market movers', r'(quote|historical_price|intraday|gainers|losers|actives|actively_trading|stock_list|batch_|aftermarket)'), | |
| 25 | + ('Technical indicators', r'^get_(rsi|macd|ema|sma|wma|dema|tema|adx|cci|stochastic|williams_r|standard_deviation)$'), | |
| 26 | + ('News and press releases', r'(news|press_release|fmp_articles)'), | |
| 27 | + ('Analysts, ratings and price targets', r'(analyst|price_target|grades|ratings_snapshot|historical_ratings|upgrades_downgrades|earnings_surprises)'), | |
| 28 | + ('ESG, compensation and alternative data', r'(esg|social_sentiment|employee|executive_comp)'), | |
| 29 | + ('Economic and macro', r'(treasury|economic|cot_|market_risk_premium)'), | |
| 30 | + ('Search and identifiers', r'^(search_|get_cik_list)'), | |
| 31 | + ('Options', r'option'), | |
| 32 | + ('Advanced analysis', r'^(download_fmp_data|execute_custom_python_analysis|extract_sec_filings)$'), | |
| 33 | +] | |
| 34 | +fam = collections.OrderedDict((r[0], []) for r in rules); other = [] | |
| 35 | +for n in names: | |
| 36 | + for lab, pat in rules: | |
| 37 | + if re.search(pat, n): | |
| 38 | + fam[lab].append(n); break | |
| 39 | + else: | |
| 40 | + other.append(n) | |
| 41 | +assert not other, other | |
| 42 | +assert sum(len(v) for v in fam.values()) == len(names) | |
| 43 | + | |
| 44 | +fmp = (root / 'server/services/fmpService.ts').read_text() | |
| 45 | +fmp_funcs = len(re.findall(r'^export (?:async )?function [a-zA-Z0-9_]+', fmp, re.M)) | |
| 46 | +fmp_paths = len(set(re.findall(r"'/[a-z0-9-]+(?:/[a-z0-9-]+)*'", fmp))) | |
| 47 | +py = (root / 'server/services/python/customPythonExecutor.py').read_text() | |
| 48 | +std = {'sys','json','io','base64','traceback','os','re','time','tempfile','contextlib','datetime','warnings','typing','math','collections','functools','itertools','random','string','pathlib','subprocess'} | |
| 49 | +pk = sorted({m.group(1) for m in re.finditer(r'^\s*(?:import|from)\s+([a-zA-Z_][a-zA-Z0-9_]*)', py, re.M)} - std) | |
| 50 | +routes = (root / 'server/routes.ts').read_text() | |
| 51 | +handlers = sorted(set(re.findall(r"toolCall\.name === '([a-zA-Z0-9_]+)'", routes))) | |
| 52 | +unreachable = sorted(set(handlers) - set(names)) | |
| 53 | +facts = { | |
| 54 | + 'commit': 'e2a148a (2026-10-02)', 'tools_defined': len(names), 'families': {k: len(v) for k, v in fam.items()}, | |
| 55 | + 'fmp_wrapper_functions': fmp_funcs, 'fmp_distinct_endpoint_paths': fmp_paths, | |
| 56 | + 'sandbox_packages_preimported': pk, 'sandbox_packages_count': len(pk), | |
| 57 | + 'handlers_in_routes_not_in_catalogue': unreachable, | |
| 58 | + 'batch_size': int(re.search(r'MAX_TOOLS_PER_BATCH = (\d+)', routes).group(1)), | |
| 59 | + 'inter_batch_delay_ms': 500, | |
| 60 | + 'per_tool_truncation_chars': [3000, 15000], 'resend_cap_chars': 5000, 'token_threshold': 100000, | |
| 61 | + 'recent_messages_kept': 5, 'summary_input_cap_chars': 10000, 'summary_max_tokens': 2000, 'summary_temperature': 0.5, | |
| 62 | + 'main_max_tokens': 64000, 'main_temperature': 1, 'sandbox_timeout_s': 90, 'figure_dpi': 150, | |
| 63 | + 'openai_tool_cap': 128, | |
| 64 | +} | |
| 65 | +json.dump({'families': fam, 'total': len(names)}, open(here / 'tool_families.json', 'w'), indent=1) | |
| 66 | +json.dump(facts, open(here / 'code_facts.json', 'w'), indent=1) | |
| 67 | + | |
| 68 | +ex = { | |
| 69 | + 'Fundamentals, valuation and classification': 'profile, income statement, balance sheet, cash flow, key metrics, DCF, screener', | |
| 70 | + 'SEC filings, transcripts and ownership': 'filings by form/CIK/symbol, 8-K, call transcripts, 13F, institutional holders', | |
| 71 | + 'Events, calendars and corporate actions': 'earnings, dividends, splits, IPO calendars, M\\&A, market hours', | |
| 72 | + 'Forex, crypto and commodities': 'FX and crypto quotes and lists, commodity quotes, batch quotes', | |
| 73 | + 'Web research (Firecrawl, Tavily, Exa)': 'scrape, crawl, map, extract, agent; search, research; neural search', | |
| 74 | + 'Insider and congressional trading': 'insider trades and statistics, House and Senate disclosures', | |
| 75 | + 'Indices, ETFs and funds': 'S\\&P 500 / Nasdaq / Dow constituents, ETF holdings and weightings', | |
| 76 | + 'Quotes, prices and market movers': 'quote, historical and intraday prices, gainers, losers, actives', | |
| 77 | + 'Technical indicators': 'RSI, MACD, SMA/EMA/WMA/DEMA/TEMA, ADX, CCI, stochastic, Williams \\%R', | |
| 78 | + 'News and press releases': 'stock, forex, crypto and general news; press releases', | |
| 79 | + 'Analysts, ratings and price targets': 'estimates, price targets, grades, ratings, upgrades/downgrades', | |
| 80 | + 'ESG, compensation and alternative data': 'ESG scores and benchmarks, social sentiment, headcount, executive pay', | |
| 81 | + 'Global market data (EODHD)': 'symbol search, EOD and intraday bars, fundamentals, news (70+ exchanges)', | |
| 82 | + 'Economic and macro': 'treasury rates, indicators, economic calendar, COT reports, risk premium', | |
| 83 | + 'Search and identifiers': 'company, symbol, CUSIP, ISIN and CIK lookup', | |
| 84 | + 'Options': 'option chain, contract prices, Greeks (EODHD); Black--Scholes pricer', | |
| 85 | + 'Advanced analysis': 'custom Python execution, bulk data download, SEC filing extraction', | |
| 86 | +} | |
| 87 | +rows = sorted(fam.items(), key=lambda kv: -len(kv[1])) | |
| 88 | +with open(paper_tables / 'tools.tex', 'w') as f: | |
| 89 | + f.write("% Generated by docs/verify/audit_vquant_code.py from vquant.git commit e2a148a (2026-10-17). Do not edit by hand.\n") | |
| 90 | + f.write("\\begin{table}[htbp]\n\\centering\n") | |
| 91 | + f.write("\\caption{Tool catalogue exposed to the model, by family. Counts are exact and were extracted programmatically from the tool-definition module of the audited code (vquant.git, commit e2a148a, 2 October 2026): %d schema-defined tools. The financial families wrap two commercial market-data providers (%d typed wrapper functions over %d distinct endpoint paths of the primary provider, plus the EODHD family); the web-research family wraps three services. Models served through the OpenAI-compatible adapter receive only the first %d tools of the catalogue because of that interface's limit.}\n" % (len(names), fmp_funcs, fmp_paths, facts['openai_tool_cap'])) | |
| 92 | + f.write("\\label{tab:tools}\n\\begin{threeparttable}\n\\small\n\\begin{tabular}{@{}lrl@{}}\n\\toprule\nFamily & Tools & Representative tools \\\\\n\\midrule\n") | |
| 93 | + for lab, v in rows: | |
| 94 | + f.write("%s & %d & %s \\\\\n" % (lab, len(v), ex[lab])) | |
| 95 | + f.write("\\midrule\nTotal & %d & \\\\\n\\bottomrule\n\\end{tabular}\n" % len(names)) | |
| 96 | + f.write("\\begin{tablenotes}[flushleft]\n\\footnotesize\n\\item \\textit{Notes.} Family assignment follows keyword rules on tool names (\\texttt{docs/verify/audit\\_vquant\\_code.py}); a tool belongs to exactly one family. The system prompt (Section~\\ref{subsec:routing}) describes only a subset of these tools explicitly; the full catalogue is transmitted as JSON schemas with every model call. Six server-side handlers for pre-built numerical routines (Monte Carlo, GARCH, VaR, portfolio optimisation, risk metrics, plotting) exist in the route module but are not in the catalogue at the audited commit and are therefore unreachable by the model (Section~\\ref{subsec:numerical}).\n\\end{tablenotes}\n\\end{threeparttable}\n\\end{table}\n") | |
| 97 | +print(json.dumps(facts, indent=1)[:1500]) | |
added
docs/verify/code_facts.json
+82 −0
@@ -0,0 +1,82 @@ | ||
| 1 | +{ | |
| 2 | + "commit": "e2a148a (2026-10-02)", | |
| 3 | + "tools_defined": 245, | |
| 4 | + "families": { | |
| 5 | + "Global market data (EODHD)": 8, | |
| 6 | + "Fundamentals, valuation and classification": 56, | |
| 7 | + "SEC filings, transcripts and ownership": 37, | |
| 8 | + "Events, calendars and corporate actions": 15, | |
| 9 | + "Forex, crypto and commodities": 15, | |
| 10 | + "Web research (Firecrawl, Tavily, Exa)": 14, | |
| 11 | + "Insider and congressional trading": 14, | |
| 12 | + "Indices, ETFs and funds": 14, | |
| 13 | + "Quotes, prices and market movers": 14, | |
| 14 | + "Technical indicators": 12, | |
| 15 | + "News and press releases": 9, | |
| 16 | + "Analysts, ratings and price targets": 11, | |
| 17 | + "ESG, compensation and alternative data": 9, | |
| 18 | + "Economic and macro": 6, | |
| 19 | + "Search and identifiers": 5, | |
| 20 | + "Options": 4, | |
| 21 | + "Advanced analysis": 2 | |
| 22 | + }, | |
| 23 | + "fmp_wrapper_functions": 249, | |
| 24 | + "fmp_distinct_endpoint_paths": 233, | |
| 25 | + "sandbox_packages_preimported": [ | |
| 26 | + "arch", | |
| 27 | + "cvxpy", | |
| 28 | + "docx", | |
| 29 | + "duckdb", | |
| 30 | + "hmmlearn", | |
| 31 | + "lightgbm", | |
| 32 | + "matplotlib", | |
| 33 | + "mplfinance", | |
| 34 | + "networkx", | |
| 35 | + "numba", | |
| 36 | + "numpy", | |
| 37 | + "openpyxl", | |
| 38 | + "pandas", | |
| 39 | + "plotly", | |
| 40 | + "pmdarima", | |
| 41 | + "polars", | |
| 42 | + "prophet", | |
| 43 | + "pypfopt", | |
| 44 | + "requests", | |
| 45 | + "riskfolio", | |
| 46 | + "scipy", | |
| 47 | + "seaborn", | |
| 48 | + "sklearn", | |
| 49 | + "statsmodels", | |
| 50 | + "sympy", | |
| 51 | + "ta", | |
| 52 | + "vectorbt", | |
| 53 | + "xgboost", | |
| 54 | + "yfinance" | |
| 55 | + ], | |
| 56 | + "sandbox_packages_count": 29, | |
| 57 | + "handlers_in_routes_not_in_catalogue": [ | |
| 58 | + "analyze_risk_metrics", | |
| 59 | + "calculate_var", | |
| 60 | + "create_plot", | |
| 61 | + "estimate_garch_volatility", | |
| 62 | + "optimize_portfolio", | |
| 63 | + "run_monte_carlo_simulation" | |
| 64 | + ], | |
| 65 | + "batch_size": 5, | |
| 66 | + "inter_batch_delay_ms": 500, | |
| 67 | + "per_tool_truncation_chars": [ | |
| 68 | + 3000, | |
| 69 | + 15000 | |
| 70 | + ], | |
| 71 | + "resend_cap_chars": 5000, | |
| 72 | + "token_threshold": 100000, | |
| 73 | + "recent_messages_kept": 5, | |
| 74 | + "summary_input_cap_chars": 10000, | |
| 75 | + "summary_max_tokens": 2000, | |
| 76 | + "summary_temperature": 0.5, | |
| 77 | + "main_max_tokens": 64000, | |
| 78 | + "main_temperature": 1, | |
| 79 | + "sandbox_timeout_s": 90, | |
| 80 | + "figure_dpi": 150, | |
| 81 | + "openai_tool_cap": 128 | |
| 82 | +} | |
| \ No newline at end of file | ||
added
docs/verify/tool_families.json
+284 −0
@@ -0,0 +1,284 @@ | ||
| 1 | +{ | |
| 2 | + "families": { | |
| 3 | + "Global market data (EODHD)": [ | |
| 4 | + "get_eodhd_dividends", | |
| 5 | + "get_eodhd_fundamentals", | |
| 6 | + "get_eodhd_historical", | |
| 7 | + "get_eodhd_intraday", | |
| 8 | + "get_eodhd_news", | |
| 9 | + "get_eodhd_quote", | |
| 10 | + "get_eodhd_splits", | |
| 11 | + "search_eodhd" | |
| 12 | + ], | |
| 13 | + "Fundamentals, valuation and classification": [ | |
| 14 | + "get_all_exchange_market_hours", | |
| 15 | + "get_all_industry_classification", | |
| 16 | + "get_all_shares_float", | |
| 17 | + "get_available_countries", | |
| 18 | + "get_available_exchanges", | |
| 19 | + "get_available_industries", | |
| 20 | + "get_available_sectors", | |
| 21 | + "get_balance_sheet", | |
| 22 | + "get_balance_sheet_ttm", | |
| 23 | + "get_batch_exchange_quote", | |
| 24 | + "get_batch_market_capitalization", | |
| 25 | + "get_cash_flow", | |
| 26 | + "get_cashflow_statement_ttm", | |
| 27 | + "get_company_outlook", | |
| 28 | + "get_company_profile", | |
| 29 | + "get_custom_dcf", | |
| 30 | + "get_custom_levered_dcf", | |
| 31 | + "get_dcf_valuation", | |
| 32 | + "get_enterprise_values", | |
| 33 | + "get_exchange_market_hours", | |
| 34 | + "get_financial_growth", | |
| 35 | + "get_financial_ratios", | |
| 36 | + "get_financial_scores", | |
| 37 | + "get_financial_statement_symbol_list", | |
| 38 | + "get_historical_industry_pe", | |
| 39 | + "get_historical_industry_performance", | |
| 40 | + "get_historical_market_capitalization", | |
| 41 | + "get_historical_sector_pe", | |
| 42 | + "get_historical_sector_performance", | |
| 43 | + "get_holidays_by_exchange", | |
| 44 | + "get_income_statement", | |
| 45 | + "get_income_statement_ttm", | |
| 46 | + "get_industry_classification_list", | |
| 47 | + "get_industry_pe_snapshot", | |
| 48 | + "get_industry_performance_snapshot", | |
| 49 | + "get_industry_performance_summary", | |
| 50 | + "get_key_executives", | |
| 51 | + "get_key_metrics", | |
| 52 | + "get_key_metrics_ttm", | |
| 53 | + "get_latest_financial_statements", | |
| 54 | + "get_levered_dcf", | |
| 55 | + "get_market_capitalization", | |
| 56 | + "get_market_sector_performance_snapshot", | |
| 57 | + "get_owner_earnings", | |
| 58 | + "get_profile_by_cik", | |
| 59 | + "get_ratios_ttm", | |
| 60 | + "get_revenue_geographic_segmentation", | |
| 61 | + "get_revenue_product_segmentation", | |
| 62 | + "get_sec_company_full_profile", | |
| 63 | + "get_sector_pe_snapshot", | |
| 64 | + "get_shares_float", | |
| 65 | + "get_stock_peers", | |
| 66 | + "get_stock_price_change", | |
| 67 | + "get_stock_screener", | |
| 68 | + "search_exchange_variants", | |
| 69 | + "search_industry_classification" | |
| 70 | + ], | |
| 71 | + "SEC filings, transcripts and ownership": [ | |
| 72 | + "extract_sec_filings", | |
| 73 | + "get_acquisition_of_beneficial_ownership", | |
| 74 | + "get_cik_list", | |
| 75 | + "get_company_equity_offerings_by_cik", | |
| 76 | + "get_company_notes", | |
| 77 | + "get_crowdfunding_by_cik", | |
| 78 | + "get_earning_call_transcript_dates", | |
| 79 | + "get_earnings_call_transcript", | |
| 80 | + "get_earnings_transcript_list", | |
| 81 | + "get_equity_offering_updates", | |
| 82 | + "get_filings_extract_with_analytics", | |
| 83 | + "get_form_13f_filings_dates", | |
| 84 | + "get_holder_performance_summary", | |
| 85 | + "get_holders_industry_breakdown", | |
| 86 | + "get_institutional_holders", | |
| 87 | + "get_institutional_ownership_filings", | |
| 88 | + "get_ipo_disclosures", | |
| 89 | + "get_ipo_prospectus", | |
| 90 | + "get_latest_8k_sec_filings", | |
| 91 | + "get_latest_crowdfunding_campaigns", | |
| 92 | + "get_latest_earning_transcripts", | |
| 93 | + "get_latest_sec_filings", | |
| 94 | + "get_mutual_fund_disclosure", | |
| 95 | + "get_mutual_fund_disclosure_dates", | |
| 96 | + "get_mutual_fund_disclosure_latest", | |
| 97 | + "get_mutual_fund_disclosure_search", | |
| 98 | + "get_positions_summary", | |
| 99 | + "get_sec_filings", | |
| 100 | + "get_sec_filings_by_cik", | |
| 101 | + "get_sec_filings_by_form_type", | |
| 102 | + "get_sec_filings_by_name", | |
| 103 | + "get_sec_filings_by_symbol", | |
| 104 | + "get_sec_filings_company_search_by_cik", | |
| 105 | + "get_sec_filings_company_search_by_symbol", | |
| 106 | + "search_by_cik", | |
| 107 | + "search_crowdfunding_campaigns", | |
| 108 | + "search_equity_offerings" | |
| 109 | + ], | |
| 110 | + "Events, calendars and corporate actions": [ | |
| 111 | + "get_delisted_companies", | |
| 112 | + "get_dividend_history", | |
| 113 | + "get_dividends_calendar", | |
| 114 | + "get_dividends_company", | |
| 115 | + "get_earnings_calendar", | |
| 116 | + "get_earnings_report", | |
| 117 | + "get_economic_calendar", | |
| 118 | + "get_ipo_calendar", | |
| 119 | + "get_latest_mergers_acquisitions", | |
| 120 | + "get_market_hours", | |
| 121 | + "get_splits", | |
| 122 | + "get_splits_calendar", | |
| 123 | + "get_stock_split_history", | |
| 124 | + "get_symbol_change", | |
| 125 | + "search_mergers_acquisitions" | |
| 126 | + ], | |
| 127 | + "Forex, crypto and commodities": [ | |
| 128 | + "get_batch_commodity_quotes", | |
| 129 | + "get_batch_crypto_quotes", | |
| 130 | + "get_batch_forex_quotes", | |
| 131 | + "get_commodities_list", | |
| 132 | + "get_commodity_quotes", | |
| 133 | + "get_crypto_list", | |
| 134 | + "get_crypto_news", | |
| 135 | + "get_crypto_quote", | |
| 136 | + "get_forex_currency_pairs", | |
| 137 | + "get_forex_historical", | |
| 138 | + "get_forex_list", | |
| 139 | + "get_forex_news", | |
| 140 | + "get_forex_quote", | |
| 141 | + "search_crypto_news", | |
| 142 | + "search_forex_news" | |
| 143 | + ], | |
| 144 | + "Web research (Firecrawl, Tavily, Exa)": [ | |
| 145 | + "firecrawl_agent", | |
| 146 | + "firecrawl_batch_scrape", | |
| 147 | + "firecrawl_crawl", | |
| 148 | + "firecrawl_extract", | |
| 149 | + "firecrawl_map", | |
| 150 | + "firecrawl_scrape", | |
| 151 | + "firecrawl_search", | |
| 152 | + "get_contents_exa", | |
| 153 | + "tavily_crawl", | |
| 154 | + "tavily_extract", | |
| 155 | + "tavily_map", | |
| 156 | + "tavily_research", | |
| 157 | + "tavily_search", | |
| 158 | + "web_search_exa" | |
| 159 | + ], | |
| 160 | + "Insider and congressional trading": [ | |
| 161 | + "get_all_insider_transaction_types", | |
| 162 | + "get_congressional_trading", | |
| 163 | + "get_house_trades_by_name", | |
| 164 | + "get_house_trades_symbol", | |
| 165 | + "get_insider_trade_statistics", | |
| 166 | + "get_insider_trading", | |
| 167 | + "get_latest_house_disclosures", | |
| 168 | + "get_latest_insider_trading", | |
| 169 | + "get_latest_senate_disclosures", | |
| 170 | + "get_senate_trades_by_name", | |
| 171 | + "get_senate_trades_symbol", | |
| 172 | + "get_senate_trading", | |
| 173 | + "search_insider_trades", | |
| 174 | + "search_insider_trades_by_name" | |
| 175 | + ], | |
| 176 | + "Indices, ETFs and funds": [ | |
| 177 | + "get_batch_etf_quotes", | |
| 178 | + "get_batch_mutualfund_quotes", | |
| 179 | + "get_dow_jones_constituent", | |
| 180 | + "get_etf_asset_exposure", | |
| 181 | + "get_etf_country_weightings", | |
| 182 | + "get_etf_holdings", | |
| 183 | + "get_etf_list", | |
| 184 | + "get_etf_sector_weightings", | |
| 185 | + "get_historical_dow_jones_constituent", | |
| 186 | + "get_historical_nasdaq_constituent", | |
| 187 | + "get_historical_sp500_constituent", | |
| 188 | + "get_index_list", | |
| 189 | + "get_nasdaq_constituent", | |
| 190 | + "get_sp500_constituent" | |
| 191 | + ], | |
| 192 | + "Quotes, prices and market movers": [ | |
| 193 | + "get_actively_trading_list", | |
| 194 | + "get_actives", | |
| 195 | + "get_aftermarket_quote", | |
| 196 | + "get_aftermarket_trade", | |
| 197 | + "get_batch_index_quotes", | |
| 198 | + "get_batch_quote", | |
| 199 | + "get_batch_quote_short", | |
| 200 | + "get_gainers", | |
| 201 | + "get_historical_price", | |
| 202 | + "get_intraday_price", | |
| 203 | + "get_losers", | |
| 204 | + "get_quote_short", | |
| 205 | + "get_stock_list", | |
| 206 | + "get_stock_quote" | |
| 207 | + ], | |
| 208 | + "Technical indicators": [ | |
| 209 | + "get_adx", | |
| 210 | + "get_cci", | |
| 211 | + "get_dema", | |
| 212 | + "get_ema", | |
| 213 | + "get_macd", | |
| 214 | + "get_rsi", | |
| 215 | + "get_sma", | |
| 216 | + "get_standard_deviation", | |
| 217 | + "get_stochastic", | |
| 218 | + "get_tema", | |
| 219 | + "get_williams_r", | |
| 220 | + "get_wma" | |
| 221 | + ], | |
| 222 | + "News and press releases": [ | |
| 223 | + "get_financial_news", | |
| 224 | + "get_fmp_articles", | |
| 225 | + "get_general_news", | |
| 226 | + "get_press_releases", | |
| 227 | + "get_press_releases_latest", | |
| 228 | + "get_stock_news_latest", | |
| 229 | + "get_stock_news_sentiment", | |
| 230 | + "search_press_releases_new", | |
| 231 | + "search_stock_news" | |
| 232 | + ], | |
| 233 | + "Analysts, ratings and price targets": [ | |
| 234 | + "get_analyst_estimates", | |
| 235 | + "get_earnings_surprises", | |
| 236 | + "get_grades", | |
| 237 | + "get_grades_summary", | |
| 238 | + "get_historical_grades", | |
| 239 | + "get_historical_ratings", | |
| 240 | + "get_price_target", | |
| 241 | + "get_price_target_consensus", | |
| 242 | + "get_price_target_summary", | |
| 243 | + "get_ratings_snapshot", | |
| 244 | + "get_upgrades_downgrades" | |
| 245 | + ], | |
| 246 | + "ESG, compensation and alternative data": [ | |
| 247 | + "get_employee_count", | |
| 248 | + "get_esg_benchmark", | |
| 249 | + "get_esg_disclosures", | |
| 250 | + "get_esg_ratings", | |
| 251 | + "get_esg_score", | |
| 252 | + "get_executive_compensation", | |
| 253 | + "get_executive_compensation_benchmark", | |
| 254 | + "get_historical_employee_count", | |
| 255 | + "get_social_sentiment" | |
| 256 | + ], | |
| 257 | + "Economic and macro": [ | |
| 258 | + "get_cot_analysis", | |
| 259 | + "get_cot_list", | |
| 260 | + "get_cot_report", | |
| 261 | + "get_economic_indicator", | |
| 262 | + "get_market_risk_premium", | |
| 263 | + "get_treasury_rates" | |
| 264 | + ], | |
| 265 | + "Search and identifiers": [ | |
| 266 | + "search_by_cusip", | |
| 267 | + "search_by_isin", | |
| 268 | + "search_companies", | |
| 269 | + "search_name", | |
| 270 | + "search_symbol" | |
| 271 | + ], | |
| 272 | + "Options": [ | |
| 273 | + "calculate_options_price", | |
| 274 | + "get_option_chain", | |
| 275 | + "get_option_greeks", | |
| 276 | + "get_option_prices" | |
| 277 | + ], | |
| 278 | + "Advanced analysis": [ | |
| 279 | + "download_fmp_data", | |
| 280 | + "execute_custom_python_analysis" | |
| 281 | + ] | |
| 282 | + }, | |
| 283 | + "total": 245 | |
| 284 | +} | |
| \ No newline at end of file | ||
modified
paper/appendix/appendix.tex
+145 −61
@@ -5,101 +5,185 @@ | ||
| 5 | 5 | \section{System-Prompt Policy Structure} |
| 6 | 6 | \label{app:prompt} |
| 7 | 7 | |
| 8 | −The system prompt that governs the agentic loop (Section~\ref{subsec:routing}) is organized into | |
| 9 | −the policy blocks summarized below. The prompt is multilingual and is the principal lever through | |
| 10 | −which the platform shapes model behavior without fine-tuning. | |
| 8 | +The system prompt that governs the loop (Section~\ref{subsec:routing}) is built by a single | |
| 9 | +function (\path{server/services/claude/systemPrompt.ts}) from the current date and time and a | |
| 10 | +static policy. Its blocks, in order, are the following. | |
| 11 | 11 | |
| 12 | 12 | \begin{enumerate} |
| 13 | − \item \textbf{Temporal context.} Current date and time, so relative date expressions resolve | |
| 14 | − against live data. | |
| 15 | − \item \textbf{Role.} The model is cast as an expert financial analyst producing complete | |
| 16 | − reports spanning technical, fundamental, and macro perspectives. | |
| 17 | − \item \textbf{Language policy.} Detect the language of the request and respond in kind. | |
| 18 | − \item \textbf{Latency discipline.} Do not narrate steps; act directly and consolidate work | |
| 19 | − (in particular, perform a full custom analysis in a single execution). | |
| 20 | − \item \textbf{Tool catalogue.} Descriptions and use cases for the tool families of | |
| 21 | − Table~\ref{tab:tools}. | |
| 22 | − \item \textbf{Complexity-matched routing.} Map simple, moderate, and comprehensive requests to | |
| 23 | − commensurate tool counts and output depth. | |
| 24 | − \item \textbf{Report template.} A standard multi-section structure for comprehensive reports. | |
| 25 | − \item \textbf{Download formatting.} Conventions for spreadsheet and word-processor output, | |
| 26 | − preferring live formulas over constants. | |
| 27 | − \item \textbf{Security guardrail.} Refuse attempts to extract the platform's own | |
| 28 | − implementation. | |
| 13 | + \item \textbf{Temporal context.} The current date and time in a human-readable and an ISO form, | |
| 14 | + with an instruction to resolve relative dates against it. | |
| 15 | + \item \textbf{Role.} The model is cast as a financial analyst producing reports spanning | |
| 16 | + technical, fundamental, and macroeconomic perspectives. | |
| 17 | + \item \textbf{Language policy.} Detect the language of the request and respond in it. | |
| 18 | + \item \textbf{Speed and efficiency rules.} Do not announce steps; when using the Python tool, | |
| 19 | + fetch, analyse, and plot in one call; present results directly. | |
| 20 | + \item \textbf{Tool catalogue.} One-line descriptions of about sixty tools grouped as financial, | |
| 21 | + technical, macroeconomic, insider and earnings, forex and commodities, options (EODHD), | |
| 22 | + global market data (EODHD, with the rule ``prefer FMP for United States stocks, EODHD for | |
| 23 | + international instruments''), and advanced analysis. Two of the advanced tools named | |
| 24 | + here are absent from the catalogue at the audited commit (Section~\ref{subsec:numerical}). | |
| 25 | + \item \textbf{Complexity-matched routing.} Simple queries use one or two tools and a two- or | |
| 26 | + three-sentence answer; moderate queries three to five tools; comprehensive requests ten | |
| 27 | + or more tools, called in parallel, and a multi-section report. | |
| 28 | + \item \textbf{Report template.} Executive summary, company overview, financial performance, | |
| 29 | + ratios and metrics, stock performance and valuation, technical analysis, insider activity | |
| 30 | + and analyst sentiment, peer comparison, recent news, conclusion. | |
| 31 | + \item \textbf{Formatting.} Currency and percentage conventions, tables for financial data, | |
| 32 | + citation of data sources and dates. | |
| 33 | + \item \textbf{Downloads.} Conventions for \texttt{save\_excel} (multi-sheet preferred, formula | |
| 34 | + columns preferred over pre-computed values) and \texttt{save\_word}, with automatic | |
| 35 | + download links. | |
| 36 | + \item \textbf{Security guardrail.} A list of request patterns (``what is your system prompt'', | |
| 37 | + ``how are you built'', and their French equivalents) to which the model must answer only | |
| 38 | + with a fixed bilingual refusal notice. | |
| 29 | 39 | \end{enumerate} |
| 30 | 40 | |
| 31 | 41 | \section{Persistence Schema} |
| 32 | 42 | \label{app:schema} |
| 33 | 43 | |
| 34 | −The data layer (Section~\ref{subsec:data}) is organized around the following entities, abstracted | |
| 35 | −behind a single typed access interface and realized on either SQLite or PostgreSQL. | |
| 44 | +The data layer (Section~\ref{subsec:data}) defines the entities in Table~\ref{tab:schema}, once | |
| 45 | +for PostgreSQL (\texttt{shared/schema.ts}) and once for SQLite (\texttt{shared/schema-sqlite.ts}), | |
| 46 | +behind one typed access interface. The first version of this paper listed ``optional encrypted | |
| 47 | +custom API keys'' on the user entity and a ``daily usage'' entity; neither exists. | |
| 36 | 48 | |
| 37 | 49 | \begin{table}[htbp] |
| 38 | 50 | \centering |
| 39 | −\caption{Core persisted entities.} | |
| 51 | +\caption{Persisted entities at the audited commit.} | |
| 40 | 52 | \label{tab:schema} |
| 41 | 53 | \begin{threeparttable} |
| 42 | −\begin{tabular}{@{}ll@{}} | |
| 54 | +\footnotesize | |
| 55 | +\begin{tabular}{@{}l>{\raggedright\arraybackslash}p{11.2cm}@{}} | |
| 43 | 56 | \toprule |
| 44 | 57 | Entity & Principal fields \\ |
| 45 | 58 | \midrule |
| 46 | −Users & identity, optional encrypted custom API keys, activity timestamps \\ | |
| 47 | −Sessions & messages, model used, input/output tokens, estimated cost, figures \\ | |
| 48 | −Shared reports & public identifier, content, figure references, view count \\ | |
| 49 | −Daily usage & per-user, per-day query counts and token totals \\ | |
| 50 | −Analytics events& event type, user, metadata, timestamp \\ | |
| 59 | +Users & display name, opaque token, e-mail and verification time, password hash, timestamps \\ | |
| 60 | +Authentication codes & one-time e-mail codes with purpose and expiry \\ | |
| 61 | +Trusted devices & device identifiers that skip the code on later logins \\ | |
| 62 | +Authentication events & security log (login, failure, code sent, device trusted) \\ | |
| 63 | +Conversation sessions & serialised messages, model, input and output tokens, estimated cost \\ | |
| 64 | +Messages & individual turns with tool results and figure references \\ | |
| 65 | +Shared reports & eight-character public identifier, content, figure references, view count \\ | |
| 66 | +Active users & presence, current query, heartbeat, user agent, address \\ | |
| 67 | +Analytics metrics & aggregated request, failure, user, and response-time counters \\ | |
| 68 | +Request logs & per-request path, status, duration \\ | |
| 69 | +Crawled pages, embeddings & cached web content and vector embeddings for research tools \\ | |
| 51 | 70 | \bottomrule |
| 52 | 71 | \end{tabular} |
| 53 | −\begin{tablenotes}[flushleft] | |
| 54 | −\footnotesize | |
| 55 | −\item \textit{Notes.} The schema supports authentication, daily rate limiting, report sharing, | |
| 56 | −session continuity, and the operational observability discussed in | |
| 57 | −Section~\ref{subsec:security}. | |
| 58 | −\end{tablenotes} | |
| 59 | 72 | \end{threeparttable} |
| 60 | 73 | \end{table} |
| 61 | 74 | |
| 62 | 75 | \section{Embedded Numerical Methods} |
| 63 | 76 | \label{app:numerical} |
| 64 | 77 | |
| 65 | −For completeness we record the closed forms behind the pre-built numerical tools of | |
| 66 | −Section~\ref{subsec:numerical}. They are standard; the architectural point is only that each is a | |
| 67 | −deterministic computation over live data, exposed through the same sandbox contract. | |
| 78 | +For completeness we record the closed forms behind the pre-built numerical routines of | |
| 79 | +Section~\ref{subsec:numerical}. They are standard, and at the audited commit only the option | |
| 80 | +pricer is reachable by the model; the others are available to the server and are the natural | |
| 81 | +reference implementations for the computation tasks of the evaluation protocol. | |
| 68 | 82 | |
| 69 | 83 | \paragraph{Monte Carlo.} Prices are simulated under geometric Brownian motion |
| 70 | −\citep{glasserman2004monte}, discretized exactly as | |
| 71 | −$ | |
| 84 | +\citep{glasserman2004monte}, discretised exactly as | |
| 85 | +\begin{equation} | |
| 72 | 86 | S_{t+\Delta t} = S_t \exp\!\big[(\mu - \tfrac{1}{2}\sigma^{2})\Delta t + \sigma\sqrt{\Delta t}\,Z_t\big], |
| 73 | −$ | |
| 74 | −with $Z_t \sim \mathcal{N}(0,1)$ and $(\mu,\sigma)$ estimated from historical closes; the default | |
| 75 | −run generates $10{,}000$ paths over a $252$-day horizon and reports the terminal mean, empirical | |
| 76 | −confidence intervals, and exceedance probabilities. | |
| 87 | + \qquad Z_t \sim \mathcal{N}(0,1), | |
| 88 | + \label{eq:gbm} | |
| 89 | +\end{equation} | |
| 90 | +with $(\mu,\sigma)$ estimated from historical log returns; the default run generates $10{,}000$ | |
| 91 | +paths over a $252$-day horizon and reports the terminal mean, empirical quantiles, and exceedance | |
| 92 | +probabilities. The routine does not fix a random seed (Section~\ref{subsec:repro}). | |
| 77 | 93 | |
| 78 | 94 | \paragraph{Option pricing.} European options use Black--Scholes--Merton |
| 79 | −\citep{black1973pricing,merton1973theory}: with | |
| 80 | −$d_1 = [\ln(S/K) + (r+\tfrac{1}{2}\sigma^{2})T]/(\sigma\sqrt{T})$ and $d_2 = d_1 - \sigma\sqrt{T}$, | |
| 81 | −the call price is $C = S\,\Phi(d_1) - Ke^{-rT}\Phi(d_2)$, with the put by parity and the full set | |
| 82 | −of Greeks ($\Delta,\Gamma,\mathcal{V},\Theta,\rho$) returned analytically. | |
| 95 | +\citep{black1973pricing,merton1973theory}. With | |
| 96 | +\begin{equation} | |
| 97 | + d_1 = \frac{\ln(S/K) + (r+\tfrac{1}{2}\sigma^{2})T}{\sigma\sqrt{T}}, \qquad d_2 = d_1 - \sigma\sqrt{T}, | |
| 98 | + \label{eq:bsm_d} | |
| 99 | +\end{equation} | |
| 100 | +the call price is $C = S\,\Phi(d_1) - Ke^{-rT}\Phi(d_2)$, the put follows from put--call parity, | |
| 101 | +and the Greeks ($\Delta,\Gamma,\mathcal{V},\Theta,\rho$) are returned analytically. | |
| 83 | 102 | |
| 84 | 103 | \paragraph{Conditional volatility.} A GARCH(1,1) model |
| 85 | −\citep{engle1982autoregressive,bollerslev1986generalized} estimates | |
| 86 | −$h_t = \omega + \alpha\varepsilon_{t-1}^{2} + \beta h_{t-1}$, reporting the parameters, | |
| 87 | −persistence $\alpha+\beta$, and shock half-life. | |
| 104 | +\citep{engle1982autoregressive,bollerslev1986generalized}, | |
| 105 | +\begin{equation} | |
| 106 | + h_t = \omega + \alpha\varepsilon_{t-1}^{2} + \beta h_{t-1}, | |
| 107 | + \label{eq:garch} | |
| 108 | +\end{equation} | |
| 109 | +is estimated by maximum likelihood (the \texttt{arch} package), reporting the parameters, the | |
| 110 | +persistence $\alpha+\beta$, and the shock half-life $\ln(0.5)/\ln(\alpha+\beta)$. | |
| 88 | 111 | |
| 89 | −\paragraph{Value-at-Risk.} VaR \citep{jorion2007value} is computed by historical, parametric | |
| 90 | −($\mu + \sigma\,\Phi^{-1}(1-\alpha)$), and Monte Carlo methods, with expected shortfall and the | |
| 91 | −Sharpe, Sortino, and Calmar ratios. | |
| 112 | +\paragraph{Value-at-Risk.} VaR \citep{jorion2007value} at level $\alpha$ is computed by the | |
| 113 | +historical method (empirical quantile of returns), the parametric method | |
| 114 | +$\mu + \sigma\,\Phi^{-1}(1-\alpha)$, and simulation under~\eqref{eq:gbm}, with expected | |
| 115 | +shortfall and the Sharpe, Sortino, and Calmar ratios. | |
| 92 | 116 | |
| 93 | −\section{Streaming Event Types} | |
| 117 | +\section{Client-Side Streaming Event Types} | |
| 94 | 118 | \label{app:events} |
| 95 | 119 | |
| 96 | 120 | The client--server channel (Section~\ref{subsec:frontend}) transmits discrete Server-Sent Events, |
| 97 | −each dispatched to a dedicated renderer. The principal types are: incremental \emph{text}; | |
| 98 | −reasoning \emph{thinking} summaries; \emph{tools} announcements that drive the progress indicator; | |
| 99 | −\emph{tool-result} payloads; \emph{sources} for web research; \emph{Python code} that was | |
| 100 | −executed; \emph{figure} references as images are produced; specialized result objects with bespoke | |
| 101 | −visualizations; and a terminal \emph{done} event carrying the session identifier and token usage. | |
| 102 | −This taxonomy is the client-side counterpart to the provider-event dispatch of | |
| 103 | −Table~\ref{tab:events}. | |
| 121 | +each dispatched to a dedicated renderer. The server emits fifteen types at the audited commit: | |
| 122 | +\emph{text} (incremental answer), \emph{thinking} (reasoning summary), \emph{tools} (the list of | |
| 123 | +requested calls), \emph{tool\_use}, \emph{tool\_start}, \emph{tool\_complete}, \emph{tool\_error}, | |
| 124 | +and \emph{tool\_result} (per-call progress and payloads), \emph{status} (batch progress), | |
| 125 | +\emph{sources} (web-research citations), \emph{python\_code} (the code that was executed), | |
| 126 | +\emph{custom\_python\_figures} and \emph{image} (figure references), \emph{done} (session | |
| 127 | +identifier and token usage), and \emph{error}. The client additionally handles three | |
| 128 | +search-progress types. This taxonomy is the client-side counterpart of the provider-event | |
| 129 | +dispatch of Table~\ref{tab:events}. | |
| 130 | + | |
| 131 | +\section{Audit of the Description Against the Code} | |
| 132 | +\label{app:audit} | |
| 133 | + | |
| 134 | +Table~\ref{tab:audit} lists the principal statements of the paper with the file in | |
| 135 | +\texttt{vquant.git} (commit \texttt{e2a148a}, 2 October 2026) that supports each, and flags the | |
| 136 | +statements of the first version (v1.0, June 2026) that the audit found to be inaccurate. Counts | |
| 137 | +were produced by the script \path{docs/verify/audit_vquant_code.py} distributed with the paper. | |
| 138 | + | |
| 139 | +\begin{footnotesize} | |
| 140 | +\begin{longtable}{@{}>{\raggedright\arraybackslash}p{4.9cm}>{\raggedright\arraybackslash}p{6.3cm}>{\raggedright\arraybackslash}p{4.3cm}@{}} | |
| 141 | +\caption{Claims and their sources in the audited code.} | |
| 142 | +\label{tab:audit}\\ | |
| 143 | +\toprule | |
| 144 | +Statement in this paper & Source (file) & v1.0 statement \\ | |
| 145 | +\midrule | |
| 146 | +\endfirsthead | |
| 147 | +\toprule | |
| 148 | +Statement in this paper & Source (file) & v1.0 statement \\ | |
| 149 | +\midrule | |
| 150 | +\endhead | |
| 151 | +\bottomrule | |
| 152 | +\endfoot | |
| 153 | +245 schema-defined tools & \path{server/services/claude/toolDefinitions.ts} & ``more than two hundred'' \\ | |
| 154 | +249 wrapper functions, 233 endpoint paths & \path{server/services/fmpService.ts} & ``265+ endpoints, roughly 230 functions'' \\ | |
| 155 | +Second provider (EODHD), 8 tools & \path{server/services/eodhdService.ts} & not mentioned \\ | |
| 156 | +Three web services, 14 tools & \path{toolDefinitions.ts}; \texttt{firecrawlService}, \texttt{tavilyService}, \texttt{exaService} & ``four services'' (SerpAPI has no tool) \\ | |
| 157 | +Raw HTTP to provider, no SDK & \path{server/services/claudeService.ts} l.~14--15 & same \\ | |
| 158 | +Buffer, split, keep partial line & \path{claudeService.ts} l.~118--125 & same \\ | |
| 159 | +Eight provider event cases & \path{claudeService.ts} l.~133--210 & same \\ | |
| 160 | +Adaptive thinking list; \texttt{display: summarized} & \path{claudeService.ts} l.~19, 90 & same (models unnamed) \\ | |
| 161 | +\texttt{max\_tokens} 64{,}000; temperature 1 & \path{claudeService.ts} l.~88--89 & cap stated; temperature not \\ | |
| 162 | +Default model \texttt{claude-fable-5} & \path{claudeService.ts} l.~18; \path{client/src/lib/models.ts} & ``Claude family'' only \\ | |
| 163 | +OpenAI-compatible adapter, 128-tool cap & \path{server/services/openaiService.ts} l.~14--16, 60--63 & not mentioned \\ | |
| 164 | +Recursion; assistant turn has tool-use blocks only & \path{server/routes.ts} l.~420--495 & recursion stated; block content not \\ | |
| 165 | +Batches of 5; 500 ms between batches & \path{routes.ts} l.~470, 1933 & same \\ | |
| 166 | +\texttt{status} event per batch & \path{routes.ts} l.~499--504 & ``progress event'' \\ | |
| 167 | +Per-result truncation 3{,}000 / 15{,}000 & \path{routes.ts} l.~1860--1885 & not mentioned \\ | |
| 168 | +Re-send cap 5{,}000; threshold $10^{5}$; last 5 messages & \path{claudeService.ts} l.~41--66 & same \\ | |
| 169 | +Estimate $\lceil$chars/4$\rceil$ & \path{server/services/claude/tokenManagement.ts} l.~10--12 & same \\ | |
| 170 | +Summary: 2{,}000 tokens, temperature 0.5, 10{,}000-char input, 500-char fallback & \path{tokenManagement.ts} l.~64--105 & ``low temperature, tight cap'' \\ | |
| 171 | +Local count with \texttt{gpt-tokenizer}; max rule & \path{claudeService.ts} l.~2, 160--175 & ``exact tokenizer'' (incorrect) \\ | |
| 172 | +Fixed \$3 / \$15 schedule for all models & \path{claudeService.ts} l.~112--114 & ``linear schedule'' (model dependence not stated) \\ | |
| 173 | +Tokenizer does not drive the context trigger & \path{claudeService.ts} l.~44 & \S6.2 said it did (incorrect) \\ | |
| 174 | +Child process, stdin JSON, 90 s timeout, unbuffered & \path{server/services/python/var.ts} l.~1285--1300 & same \\ | |
| 175 | +29 packages attempted; \texttt{exec}; \texttt{main()} & \path{server/services/python/customPythonExecutor.py} l.~17--360, 946--980 & ``seventeen libraries'' \\ | |
| 176 | +Figure sweep, PNG 150 dpi, base64 & \path{customPythonExecutor.py} l.~1018--1035 & same \\ | |
| 177 | +Only the option pricer is in the catalogue & \path{toolDefinitions.ts} vs.\ \path{routes.ts} l.~764--1019 & four routines ``exposed'' (incorrect) \\ | |
| 178 | +Prompt names Monte Carlo and surface tools & \path{server/services/claude/systemPrompt.ts} l.~67, 80 & not mentioned \\ | |
| 179 | +Protect--parse--restore; Puppeteer; KaTeX; wait & \path{server/services/pdfService.ts} l.~71--107, 298--317 & same \\ | |
| 180 | +Pandoc for DOCX & \path{pdfService.ts} l.~383 & ``document converter'' \\ | |
| 181 | +Beamer: second call pinned to \texttt{claude-opus-4-8}; two \texttt{pdflatex} passes & \path{server/services/beamerSlidesService.ts} l.~236, 496--540 & model not stated \\ | |
| 182 | +Share identifier of 8 characters; figures ephemeral & \path{server/routes/reports.ts} l.~45--70 & same, without the caveat \\ | |
| 183 | +Twelve persisted entities; no API keys, no daily usage & \path{shared/schema.ts}, \path{shared/schema-sqlite.ts} & five entities incl.\ keys and daily usage (incorrect) \\ | |
| 184 | +E-mail code login, trusted devices, rate limiting & \path{server/services/auth.ts} & ``SSO'', ``daily limits'', ``BYOK'' (not in code) \\ | |
| 185 | +Six test suites & \path{*.test.ts(x)} & not mentioned \\ | |
| 186 | +\end{longtable} | |
| 187 | +\end{footnotesize} | |
| 104 | 188 | |
| 105 | 189 | \end{appendices} |
modified
paper/figures/architecture.tex
+3 −3
@@ -17,11 +17,11 @@ | ||
| 17 | 17 | |
| 18 | 18 | % ---- Executor row ---- |
| 19 | 19 | \node[vqblue, below left=1.15cm and -0.2cm of loop, minimum width=2.7cm] (fin) |
| 20 | − {\textbf{Financial tools}\\[1pt]\vqsmall 265+ endpoints}; | |
| 20 | + {\textbf{Financial tools}\\[1pt]\vqsmall 2 providers $\cdot$ 233 endpoints}; | |
| 21 | 21 | \node[vqblue, below=1.15cm of loop, minimum width=2.7cm] (py) |
| 22 | − {\textbf{Python sandbox}\\[1pt]\vqsmall 17 libraries}; | |
| 22 | + {\textbf{Python sandbox}\\[1pt]\vqsmall 29 packages}; | |
| 23 | 23 | \node[vqblue, below right=1.15cm and -0.2cm of loop, minimum width=2.7cm] (web) |
| 24 | − {\textbf{Web research}\\[1pt]\vqsmall 4 services}; | |
| 24 | + {\textbf{Web research}\\[1pt]\vqsmall 3 services $\cdot$ 14 tools}; | |
| 25 | 25 | |
| 26 | 26 | % ---- External tier ---- |
| 27 | 27 | \node[vqpurple, below=of fin, minimum width=2.7cm] (fmp) |
modified
paper/figures/sandbox.tex
+1 −1
@@ -9,7 +9,7 @@ | ||
| 9 | 9 | |
| 10 | 10 | % ---- Child inner stages ---- |
| 11 | 11 | \node[vqgreen, text width=4.5cm] (ns) at (8.0,2.05) |
| 12 | − {\textbf{Build namespace}\\\vqsmall 17 libs $\cdot$ \texttt{save\_excel}/\texttt{save\_word} $\cdot$ \texttt{fmp} client $\cdot$ context vars}; | |
| 12 | + {\textbf{Build namespace}\\\vqsmall 29 pkgs $\cdot$ \texttt{save\_excel}/\texttt{save\_word} $\cdot$ \texttt{fmp} client $\cdot$ context vars}; | |
| 13 | 13 | \node[vqorange, text width=4.5cm] (ex) at (8.0,0.35) |
| 14 | 14 | {\textbf{\texttt{exec(code, ns)}}\\\vqsmall \texttt{stdout}/\texttt{stderr} $\to$ string buffers $\cdot$ optional \texttt{main()}}; |
| 15 | 15 | \node[vqpurple, text width=4.5cm] (cap) at (8.0,-1.35) |
modified
paper/figures/streaming.tex
+1 −1
@@ -19,7 +19,7 @@ | ||
| 19 | 19 | \node[vqorange, text width=3.0cm] (tool) at (11.0,-0.65) |
| 20 | 20 | {\textbf{Tool assembler}\\\vqsmall \texttt{start} $\cdot$ \texttt{input\_json\_delta}$^\ast$ $\cdot$ \texttt{stop} $\to$ args}; |
| 21 | 21 | \node[vqred, text width=3.0cm] (tok) at (11.0,-2.35) |
| 22 | − {\textbf{Token ledger}\\\vqsmall \texttt{message\_start/delta/stop} $\to$ usage}; | |
| 22 | + {\textbf{Token ledger}\\\vqsmall \texttt{message\_start/}\allowbreak\texttt{delta/}\allowbreak\texttt{stop} $\to$ usage}; | |
| 23 | 23 | |
| 24 | 24 | % Backbone arrows |
| 25 | 25 | \draw[vqflow] (prov) -- node[vqtag, above]{raw bytes} (buf); |
modified
paper/main.pdf
+0 −0
Binary file not shown.
modified
paper/main.tex
+26 −30
@@ -47,6 +47,7 @@ | ||
| 47 | 47 | |
| 48 | 48 | % --- Tables --- |
| 49 | 49 | \usepackage{booktabs} |
| 50 | +\usepackage{array} | |
| 50 | 51 | \usepackage{tabularx} |
| 51 | 52 | \usepackage{multirow} |
| 52 | 53 | \usepackage{threeparttable} |
@@ -108,6 +109,7 @@ | ||
| 108 | 109 | % --- Misc --- |
| 109 | 110 | \usepackage{enumitem} |
| 110 | 111 | \setlist{nosep,leftmargin=*} |
| 112 | +\usepackage{longtable} | |
| 111 | 113 | |
| 112 | 114 | % --- Custom colors (VQuant palette) --- |
| 113 | 115 | \definecolor{VQTeal}{HTML}{119993} |
@@ -155,38 +157,32 @@ | ||
| 155 | 157 | \newcommand{\WPnumber}{13} |
| 156 | 158 | \newcommand{\WPtitle}{VQuant: An Agentic Large Language Model Architecture for Automated Quantitative Financial Analysis and Document Generation} |
| 157 | 159 | \newcommand{\WPsubtitle}{Reasoning-Augmented Tool Orchestration, In-Loop Numerical Computation, and Multi-Format Reporting} |
| 158 | −\newcommand{\WPdate}{June 2026} | |
| 159 | −\newcommand{\WPversion}{1.0} | |
| 160 | +\newcommand{\WPdate}{October 2026} | |
| 161 | +\newcommand{\WPversion}{1.1} | |
| 160 | 162 | \newcommand{\WPabstract}{% |
| 161 | − Large language models (LLMs) have shown remarkable fluency in financial discourse, yet | |
| 162 | − conversational fluency alone does not guarantee numerically rigorous, reproducible, or | |
| 163 | − citable analysis. This paper presents \textbf{VQuant}, a production-grade web platform that | |
| 164 | − couples a reasoning-augmented LLM with a deterministic execution substrate to transform a | |
| 165 | − natural-language request into a complete quantitative financial report. We document the | |
| 166 | − system's methodology and its principal innovations: (i)~an \emph{agentic orchestration loop} | |
| 167 | − that exposes more than two hundred financial and analytical tools---spanning over 265 | |
| 168 | − market-data endpoints, four web-research services, and an arbitrary-code Python sandbox of | |
| 169 | − seventeen scientific libraries---to the model through a constrained function-calling protocol; | |
| 170 | − (ii)~a \emph{context-management algorithm} that preserves conversational coherence over | |
| 171 | − effectively unbounded histories via adaptive summarization under a token budget; | |
| 172 | − (iii)~a \emph{single-call computation paradigm} that consolidates data acquisition, numerical | |
| 173 | − estimation, and figure rendering into one sandboxed Python execution, collapsing what would | |
| 174 | − otherwise be several model round trips into one; and (iv)~a \emph{unified document pipeline} | |
| 175 | − that emits publication-ready PDF, DOCX, \LaTeX{}~Beamer slide decks, and spreadsheet workbooks | |
| 176 | − with live formulas from a single Markdown artifact. We describe each mechanism as it is | |
| 177 | − implemented---the streaming Server-Sent-Event protocol and its eight-way event dispatch, the | |
| 178 | − recursive tool-calling loop and its tool-use/tool-result invariant, the batched-execution | |
| 179 | − throttle, the two-stage context-management machinery, the token-accounting correction, and the | |
| 180 | − inter-process sandbox that exec's model-authored code and captures its figures---so that the | |
| 181 | − design can be reproduced. The classical quantitative methods the platform automates are | |
| 182 | − conventional and relegated to an appendix; our contribution is the \emph{architecture} that | |
| 183 | − makes them accessible through natural language while preserving reproducibility. We argue that | |
| 184 | − VQuant illustrates a reusable design pattern in which the language model is positioned as a | |
| 185 | − planner and synthesizer rather than as a calculator, with all numerical work delegated to | |
| 186 | − auditable, deterministic code. | |
| 163 | + Large language models (LLMs) write fluently about finance, but fluency does not make a number | |
| 164 | + correct, current, or reproducible. This paper is a design-science description of \textbf{VQuant}, | |
| 165 | + a deployed web platform that couples a reasoning-capable LLM with a deterministic execution | |
| 166 | + substrate so that a natural-language request (``analyse NVDA's fundamentals and run a Monte Carlo | |
| 167 | + simulation'') is turned into a report in which every figure is produced by live data retrieval or | |
| 168 | + auditable code rather than by the model. We document four mechanisms as they are implemented and | |
| 169 | + audit the description line by line against the platform's source code (vquant.git, commit | |
| 170 | + e2a148a): (i)~an agentic orchestration loop that exposes 245 schema-defined tools---wrapping two | |
| 171 | + market-data providers (249 typed functions over 233 endpoint paths), three web-research services, | |
| 172 | + and a Python sandbox pre-loading 29 scientific packages---through a recursive, batched, | |
| 173 | + streaming tool-calling protocol; (ii)~a three-stage context-management procedure (per-result | |
| 174 | + truncation at execution, a re-send cap, and adaptive summarisation under a token budget) that | |
| 175 | + keeps long sessions within the model's window; (iii)~a single-call computation convention that | |
| 176 | + consolidates data acquisition, estimation, and figure rendering into one sandboxed execution; and | |
| 177 | + (iv)~a document pipeline that renders one Markdown artifact into PDF, DOCX, \LaTeX{} Beamer, and | |
| 178 | + spreadsheets with live formulas. The paper reports no empirical evaluation: it contains no | |
| 179 | + measurements of numerical accuracy, hallucination rates, latency, or cost, and makes no comparative | |
| 180 | + claims. Its contribution is a reproducible specification of the architecture, an honest account of | |
| 181 | + where the implementation departs from its own documentation, and a pre-registered evaluation | |
| 182 | + protocol---benchmark, metrics, ablations, and baselines---that has not yet been executed. | |
| 187 | 183 | } |
| 188 | −\newcommand{\WPkeywords}{Large language models, agentic systems, tool use, quantitative finance, automated reporting, retrieval-augmented generation, financial NLP} | |
| 189 | −\newcommand{\WPjel}{C45, C63, C88, G17} | |
| 184 | +\newcommand{\WPkeywords}{large language models, LLM agents, tool use, design science, quantitative finance, automated report generation, reproducibility} | |
| 185 | +\newcommand{\WPjel}{C45, C63, C88, G17, O33} | |
| 190 | 186 | |
| 191 | 187 | % --- Author --- |
| 192 | 188 | \newcommand{\WPauthor}{Simon-Pierre Boucher} |
modified
paper/references.bib
+330 −31
@@ -1,7 +1,42 @@ | ||
| 1 | 1 | % ============================================================================ |
| 2 | −% References — BibTeX Database | |
| 2 | +% References — UQO WP 13 (VQuant). All entries verified on 2026-10-17 | |
| 3 | +% (Crossref, arXiv API, publisher or conference pages); see docs/CHANGELOG-REVISION.md. | |
| 3 | 4 | % ============================================================================ |
| 4 | 5 | |
| 6 | +% --- Design science --- | |
| 7 | +@article{hevner2004design, | |
| 8 | + author = {Hevner, Alan R. and March, Salvatore T. and Park, Jinsoo and Ram, Sudha}, | |
| 9 | + title = {Design Science in Information Systems Research}, | |
| 10 | + journal = {MIS Quarterly}, | |
| 11 | + volume = {28}, | |
| 12 | + number = {1}, | |
| 13 | + pages = {75--105}, | |
| 14 | + year = {2004}, | |
| 15 | + doi = {10.2307/25148625} | |
| 16 | +} | |
| 17 | + | |
| 18 | +@article{peffers2007design, | |
| 19 | + author = {Peffers, Ken and Tuunanen, Tuure and Rothenberger, Marcus A. and Chatterjee, Samir}, | |
| 20 | + title = {A Design Science Research Methodology for Information Systems Research}, | |
| 21 | + journal = {Journal of Management Information Systems}, | |
| 22 | + volume = {24}, | |
| 23 | + number = {3}, | |
| 24 | + pages = {45--77}, | |
| 25 | + year = {2007}, | |
| 26 | + doi = {10.2753/MIS0742-1222240302} | |
| 27 | +} | |
| 28 | + | |
| 29 | +@article{gregor2013positioning, | |
| 30 | + author = {Gregor, Shirley and Hevner, Alan R.}, | |
| 31 | + title = {Positioning and Presenting Design Science Research for Maximum Impact}, | |
| 32 | + journal = {MIS Quarterly}, | |
| 33 | + volume = {37}, | |
| 34 | + number = {2}, | |
| 35 | + pages = {337--355}, | |
| 36 | + year = {2013}, | |
| 37 | + doi = {10.25300/MISQ/2013/37.2.01} | |
| 38 | +} | |
| 39 | + | |
| 5 | 40 | % --- Language models and reasoning --- |
| 6 | 41 | @inproceedings{vaswani2017attention, |
| 7 | 42 | author = {Vaswani, Ashish and Shazeer, Noam and Parmar, Niki and Uszkoreit, Jakob and |
@@ -9,11 +44,14 @@ | ||
| 9 | 44 | title = {Attention Is All You Need}, |
| 10 | 45 | booktitle = {Advances in Neural Information Processing Systems}, |
| 11 | 46 | volume = {30}, |
| 47 | + pages = {5998--6008}, | |
| 12 | 48 | year = {2017} |
| 13 | 49 | } |
| 14 | 50 | |
| 15 | 51 | @inproceedings{brown2020language, |
| 16 | − author = {Brown, Tom B. and Mann, Benjamin and Ryder, Nick and Subbiah, Melanie and others}, | |
| 52 | + author = {Brown, Tom B. and Mann, Benjamin and Ryder, Nick and Subbiah, Melanie and Kaplan, Jared and | |
| 53 | + Dhariwal, Prafulla and Neelakantan, Arvind and Shyam, Pranav and Sastry, Girish and | |
| 54 | + Askell, Amanda and others}, | |
| 17 | 55 | title = {Language Models Are Few-Shot Learners}, |
| 18 | 56 | booktitle = {Advances in Neural Information Processing Systems}, |
| 19 | 57 | volume = {33}, |
@@ -28,14 +66,31 @@ | ||
| 28 | 66 | booktitle = {Advances in Neural Information Processing Systems}, |
| 29 | 67 | volume = {35}, |
| 30 | 68 | pages = {24824--24837}, |
| 31 | − year = {2022} | |
| 69 | + year = {2022}, | |
| 70 | + doi = {10.52202/068431-1800} | |
| 32 | 71 | } |
| 33 | 72 | |
| 34 | −@article{bommasani2021opportunities, | |
| 35 | − author = {Bommasani, Rishi and Hudson, Drew A. and Adeli, Ehsan and Altman, Russ and others}, | |
| 36 | − title = {On the Opportunities and Risks of Foundation Models}, | |
| 37 | − journal = {arXiv preprint arXiv:2108.07258}, | |
| 38 | − year = {2021} | |
| 73 | +@article{liu2024lost, | |
| 74 | + author = {Liu, Nelson F. and Lin, Kevin and Hewitt, John and Paranjape, Ashwin and | |
| 75 | + Bevilacqua, Michele and Petroni, Fabio and Liang, Percy}, | |
| 76 | + title = {Lost in the Middle: How Language Models Use Long Contexts}, | |
| 77 | + journal = {Transactions of the Association for Computational Linguistics}, | |
| 78 | + volume = {12}, | |
| 79 | + pages = {157--173}, | |
| 80 | + year = {2024}, | |
| 81 | + doi = {10.1162/tacl_a_00638} | |
| 82 | +} | |
| 83 | + | |
| 84 | +@article{ji2023hallucination, | |
| 85 | + author = {Ji, Ziwei and Lee, Nayeon and Frieske, Rita and Yu, Tiezheng and Su, Dan and Xu, Yan and | |
| 86 | + Ishii, Etsuko and Bang, Ye Jin and Madotto, Andrea and Fung, Pascale}, | |
| 87 | + title = {Survey of Hallucination in Natural Language Generation}, | |
| 88 | + journal = {ACM Computing Surveys}, | |
| 89 | + volume = {55}, | |
| 90 | + number = {12}, | |
| 91 | + pages = {1--38}, | |
| 92 | + year = {2023}, | |
| 93 | + doi = {10.1145/3571730} | |
| 39 | 94 | } |
| 40 | 95 | |
| 41 | 96 | % --- Tool use and agents --- |
@@ -46,7 +101,9 @@ | ||
| 46 | 101 | title = {Toolformer: Language Models Can Teach Themselves to Use Tools}, |
| 47 | 102 | booktitle = {Advances in Neural Information Processing Systems}, |
| 48 | 103 | volume = {36}, |
| 49 | − year = {2023} | |
| 104 | + pages = {68539--68551}, | |
| 105 | + year = {2023}, | |
| 106 | + doi = {10.52202/075280-2997} | |
| 50 | 107 | } |
| 51 | 108 | |
| 52 | 109 | @inproceedings{yao2023react, |
@@ -54,23 +111,166 @@ | ||
| 54 | 111 | Narasimhan, Karthik and Cao, Yuan}, |
| 55 | 112 | title = {{ReAct}: Synergizing Reasoning and Acting in Language Models}, |
| 56 | 113 | booktitle = {International Conference on Learning Representations (ICLR)}, |
| 57 | − year = {2023} | |
| 114 | + year = {2023}, | |
| 115 | + note = {arXiv:2210.03629} | |
| 58 | 116 | } |
| 59 | 117 | |
| 60 | 118 | @inproceedings{gao2023pal, |
| 61 | 119 | author = {Gao, Luyu and Madaan, Aman and Zhou, Shuyan and Alon, Uri and Liu, Pengfei and |
| 62 | 120 | Yang, Yiming and Callan, Jamie and Neubig, Graham}, |
| 63 | 121 | title = {{PAL}: Program-Aided Language Models}, |
| 64 | − booktitle = {International Conference on Machine Learning (ICML)}, | |
| 122 | + booktitle = {Proceedings of the 40th International Conference on Machine Learning}, | |
| 123 | + series = {Proceedings of Machine Learning Research}, | |
| 124 | + volume = {202}, | |
| 65 | 125 | pages = {10764--10799}, |
| 66 | 126 | year = {2023} |
| 67 | 127 | } |
| 68 | 128 | |
| 69 | −@misc{anthropic2024tooluse, | |
| 129 | +@article{chen2023pot, | |
| 130 | + author = {Chen, Wenhu and Ma, Xueguang and Wang, Xinyi and Cohen, William W.}, | |
| 131 | + title = {Program of Thoughts Prompting: Disentangling Computation from Reasoning for Numerical Reasoning Tasks}, | |
| 132 | + journal = {Transactions on Machine Learning Research}, | |
| 133 | + year = {2023}, | |
| 134 | + note = {arXiv:2211.12588} | |
| 135 | +} | |
| 136 | + | |
| 137 | +@article{mialon2023augmented, | |
| 138 | + author = {Mialon, Gr{\'e}goire and Dess{\`i}, Roberto and Lomeli, Maria and Nalmpantis, Christoforos and | |
| 139 | + Pasunuru, Ram and Raileanu, Roberta and Rozi{\`e}re, Baptiste and Schick, Timo and | |
| 140 | + Dwivedi-Yu, Jane and Celikyilmaz, Asli and Grave, Edouard and LeCun, Yann and Scialom, Thomas}, | |
| 141 | + title = {Augmented Language Models: A Survey}, | |
| 142 | + journal = {Transactions on Machine Learning Research}, | |
| 143 | + year = {2023}, | |
| 144 | + note = {arXiv:2302.07842} | |
| 145 | +} | |
| 146 | + | |
| 147 | +@inproceedings{patil2024gorilla, | |
| 148 | + author = {Patil, Shishir G. and Zhang, Tianjun and Wang, Xin and Gonzalez, Joseph E.}, | |
| 149 | + title = {Gorilla: Large Language Model Connected with Massive {APIs}}, | |
| 150 | + booktitle = {Advances in Neural Information Processing Systems}, | |
| 151 | + volume = {37}, | |
| 152 | + pages = {126544--126565}, | |
| 153 | + year = {2024}, | |
| 154 | + doi = {10.52202/079017-4020} | |
| 155 | +} | |
| 156 | + | |
| 157 | +@inproceedings{qin2024toolllm, | |
| 158 | + author = {Qin, Yujia and Liang, Shihao and Ye, Yining and Zhu, Kunlun and Yan, Lan and Lu, Yaxi and | |
| 159 | + Lin, Yankai and Cong, Xin and Tang, Xiangru and Qian, Bill and Zhao, Sihan and Hong, Lauren and | |
| 160 | + Tian, Runchu and Xie, Ruobing and Zhou, Jie and Gerstein, Mark and Li, Dahai and Liu, Zhiyuan and | |
| 161 | + Sun, Maosong}, | |
| 162 | + title = {{ToolLLM}: Facilitating Large Language Models to Master 16000+ Real-World {APIs}}, | |
| 163 | + booktitle = {International Conference on Learning Representations (ICLR)}, | |
| 164 | + year = {2024}, | |
| 165 | + note = {arXiv:2307.16789} | |
| 166 | +} | |
| 167 | + | |
| 168 | +@inproceedings{liu2024agentbench, | |
| 169 | + author = {Liu, Xiao and Yu, Hao and Zhang, Hanchen and Xu, Yifan and Lei, Xuanyu and Lai, Hanyu and | |
| 170 | + Gu, Yu and Ding, Hangliang and Men, Kaiwen and Yang, Kejuan and Zhang, Shudan and Deng, Xiang and | |
| 171 | + Zeng, Aohan and Du, Zhengxiao and Zhang, Chenhui and Shen, Sheng and Zhang, Tianjun and | |
| 172 | + Su, Yu and Sun, Huan and Huang, Minlie and Dong, Yuxiao and Tang, Jie}, | |
| 173 | + title = {{AgentBench}: Evaluating {LLMs} as Agents}, | |
| 174 | + booktitle = {International Conference on Learning Representations (ICLR)}, | |
| 175 | + year = {2024}, | |
| 176 | + note = {arXiv:2308.03688} | |
| 177 | +} | |
| 178 | + | |
| 179 | +@inproceedings{shinn2023reflexion, | |
| 180 | + author = {Shinn, Noah and Cassano, Federico and Gopinath, Ashwin and Narasimhan, Karthik and Yao, Shunyu}, | |
| 181 | + title = {Reflexion: Language Agents with Verbal Reinforcement Learning}, | |
| 182 | + booktitle = {Advances in Neural Information Processing Systems}, | |
| 183 | + volume = {36}, | |
| 184 | + pages = {8634--8652}, | |
| 185 | + year = {2023}, | |
| 186 | + doi = {10.52202/075280-0377} | |
| 187 | +} | |
| 188 | + | |
| 189 | +@article{nakano2021webgpt, | |
| 190 | + author = {Nakano, Reiichiro and Hilton, Jacob and Balaji, Suchir and Wu, Jeff and Ouyang, Long and | |
| 191 | + Kim, Christina and Hesse, Christopher and Jain, Shantanu and Kosaraju, Vineet and | |
| 192 | + Saunders, William and Jiang, Xu and Cobbe, Karl and Eloundou, Tyna and Krueger, Gretchen and | |
| 193 | + Button, Kevin and Knight, Matthew and Chess, Benjamin and Schulman, John}, | |
| 194 | + title = {{WebGPT}: Browser-Assisted Question-Answering with Human Feedback}, | |
| 195 | + journal = {arXiv preprint arXiv:2112.09332}, | |
| 196 | + year = {2021} | |
| 197 | +} | |
| 198 | + | |
| 199 | +@article{wang2024agents, | |
| 200 | + author = {Wang, Lei and Ma, Chen and Feng, Xueyang and Zhang, Zeyu and Yang, Hao and Zhang, Jingsen and | |
| 201 | + Chen, Zhiyuan and Tang, Jiakai and Chen, Xu and Lin, Yankai and Zhao, Wayne Xin and | |
| 202 | + Wei, Zhewei and Wen, Ji-Rong}, | |
| 203 | + title = {A Survey on Large Language Model Based Autonomous Agents}, | |
| 204 | + journal = {Frontiers of Computer Science}, | |
| 205 | + volume = {18}, | |
| 206 | + number = {6}, | |
| 207 | + pages = {186345}, | |
| 208 | + year = {2024}, | |
| 209 | + doi = {10.1007/s11704-024-40231-1} | |
| 210 | +} | |
| 211 | + | |
| 212 | +@misc{anthropic2026tooluse, | |
| 70 | 213 | author = {{Anthropic}}, |
| 71 | − title = {Tool Use (Function Calling) with the {Claude} {API}}, | |
| 72 | − howpublished = {Anthropic Documentation}, | |
| 73 | − year = {2024} | |
| 214 | + title = {Tool Use with {Claude}}, | |
| 215 | + howpublished = {Claude Developer Platform documentation, \url{https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview}}, | |
| 216 | + year = {2026}, | |
| 217 | + note = {Accessed 17 October 2026} | |
| 218 | +} | |
| 219 | + | |
| 220 | +@misc{mcp2025spec, | |
| 221 | + author = {{Model Context Protocol}}, | |
| 222 | + title = {Model Context Protocol Specification, Revision 2025-06-18}, | |
| 223 | + howpublished = {\url{https://modelcontextprotocol.io/specification/2025-06-18}}, | |
| 224 | + year = {2025}, | |
| 225 | + note = {Accessed 17 October 2026} | |
| 226 | +} | |
| 227 | + | |
| 228 | +% --- Evaluation --- | |
| 229 | +@inproceedings{zheng2023judge, | |
| 230 | + author = {Zheng, Lianmin and Chiang, Wei-Lin and Sheng, Ying and Zhuang, Siyuan and Wu, Zhanghao and | |
| 231 | + Zhuang, Yonghao and Lin, Zi and Li, Zhuohan and Li, Dacheng and Xing, Eric P. and | |
| 232 | + Zhang, Hao and Gonzalez, Joseph E. and Stoica, Ion}, | |
| 233 | + title = {Judging {LLM}-as-a-Judge with {MT-Bench} and {Chatbot Arena}}, | |
| 234 | + booktitle = {Advances in Neural Information Processing Systems}, | |
| 235 | + volume = {36}, | |
| 236 | + pages = {46595--46623}, | |
| 237 | + year = {2023}, | |
| 238 | + doi = {10.52202/075280-2020} | |
| 239 | +} | |
| 240 | + | |
| 241 | +@article{chang2024survey, | |
| 242 | + author = {Chang, Yupeng and Wang, Xu and Wang, Jindong and Wu, Yuan and Yang, Linyi and Zhu, Kaijie and | |
| 243 | + Chen, Hao and Yi, Xiaoyuan and Wang, Cunxiang and Wang, Yidong and Ye, Wei and Zhang, Yue and | |
| 244 | + Chang, Yi and Yu, Philip S. and Yang, Qiang and Xie, Xing}, | |
| 245 | + title = {A Survey on Evaluation of Large Language Models}, | |
| 246 | + journal = {ACM Transactions on Intelligent Systems and Technology}, | |
| 247 | + volume = {15}, | |
| 248 | + number = {3}, | |
| 249 | + pages = {1--45}, | |
| 250 | + year = {2024}, | |
| 251 | + doi = {10.1145/3641289} | |
| 252 | +} | |
| 253 | + | |
| 254 | +@article{islam2023financebench, | |
| 255 | + author = {Islam, Pranab and Kannappan, Anand and Kiela, Douwe and Qian, Rebecca and Scherrer, Nino and | |
| 256 | + Vidgen, Bertie}, | |
| 257 | + title = {{FinanceBench}: A New Benchmark for Financial Question Answering}, | |
| 258 | + journal = {arXiv preprint arXiv:2311.11944}, | |
| 259 | + year = {2023} | |
| 260 | +} | |
| 261 | + | |
| 262 | +@inproceedings{xie2024finben, | |
| 263 | + author = {Xie, Qianqian and Han, Weiguang and Chen, Zhengyu and Xiang, Ruoyu and Zhang, Xiao and | |
| 264 | + He, Yueru and Xiao, Mengxi and Li, Dong and Dai, Yongfu and Feng, Duanyu and Xu, Yijing and | |
| 265 | + Kang, Haoqiang and Kuang, Ziyan and Yuan, Chenhan and Yang, Kailai and Luo, Zheheng and | |
| 266 | + Zhang, Tianlin and Liu, Zhiwei and Xiong, Guojun and Zhang, Zhiyang and Lopez-Lira, Alejandro and | |
| 267 | + others}, | |
| 268 | + title = {{FinBen}: A Holistic Financial Benchmark for Large Language Models}, | |
| 269 | + booktitle = {Advances in Neural Information Processing Systems}, | |
| 270 | + volume = {37}, | |
| 271 | + pages = {95716--95743}, | |
| 272 | + year = {2024}, | |
| 273 | + doi = {10.52202/079017-3033} | |
| 74 | 274 | } |
| 75 | 275 | |
| 76 | 276 | % --- Retrieval and grounding --- |
@@ -89,10 +289,44 @@ | ||
| 89 | 289 | author = {L{\'o}pez de Prado, Marcos}, |
| 90 | 290 | title = {Advances in Financial Machine Learning}, |
| 91 | 291 | publisher = {John Wiley \& Sons}, |
| 292 | + address = {Hoboken, NJ}, | |
| 92 | 293 | year = {2018} |
| 93 | 294 | } |
| 94 | 295 | |
| 95 | −% --- LLMs in finance --- | |
| 296 | +% --- LLMs and text in finance and economics --- | |
| 297 | +@article{loughran2016textual, | |
| 298 | + author = {Loughran, Tim and McDonald, Bill}, | |
| 299 | + title = {Textual Analysis in Accounting and Finance: A Survey}, | |
| 300 | + journal = {Journal of Accounting Research}, | |
| 301 | + volume = {54}, | |
| 302 | + number = {4}, | |
| 303 | + pages = {1187--1230}, | |
| 304 | + year = {2016}, | |
| 305 | + doi = {10.1111/1475-679X.12123} | |
| 306 | +} | |
| 307 | + | |
| 308 | +@article{gentzkow2019text, | |
| 309 | + author = {Gentzkow, Matthew and Kelly, Bryan and Taddy, Matt}, | |
| 310 | + title = {Text as Data}, | |
| 311 | + journal = {Journal of Economic Literature}, | |
| 312 | + volume = {57}, | |
| 313 | + number = {3}, | |
| 314 | + pages = {535--574}, | |
| 315 | + year = {2019}, | |
| 316 | + doi = {10.1257/jel.20181020} | |
| 317 | +} | |
| 318 | + | |
| 319 | +@article{li2021culture, | |
| 320 | + author = {Li, Kai and Mai, Feng and Shen, Rui and Yan, Xinyan}, | |
| 321 | + title = {Measuring Corporate Culture Using Machine Learning}, | |
| 322 | + journal = {Review of Financial Studies}, | |
| 323 | + volume = {34}, | |
| 324 | + number = {7}, | |
| 325 | + pages = {3265--3315}, | |
| 326 | + year = {2021}, | |
| 327 | + doi = {10.1093/rfs/hhaa079} | |
| 328 | +} | |
| 329 | + | |
| 96 | 330 | @article{wu2023bloomberggpt, |
| 97 | 331 | author = {Wu, Shijie and Irsoy, Ozan and Lu, Steven and Dabravolski, Vadim and Dredze, Mark and |
| 98 | 332 | Gehrmann, Sebastian and Kambadur, Prabhanjan and Rosenberg, David and Mann, Gideon}, |
@@ -108,19 +342,77 @@ | ||
| 108 | 342 | year = {2023} |
| 109 | 343 | } |
| 110 | 344 | |
| 111 | −@article{lopezlira2023chatgpt, | |
| 345 | +@inproceedings{li2023survey, | |
| 346 | + author = {Li, Yinheng and Wang, Shaofei and Ding, Han and Chen, Hang}, | |
| 347 | + title = {Large Language Models in Finance: A Survey}, | |
| 348 | + booktitle = {Proceedings of the Fourth ACM International Conference on AI in Finance (ICAIF '23)}, | |
| 349 | + pages = {374--382}, | |
| 350 | + year = {2023}, | |
| 351 | + doi = {10.1145/3604237.3626869} | |
| 352 | +} | |
| 353 | + | |
| 354 | +@article{lopezlira2026chatgpt, | |
| 112 | 355 | author = {Lopez-Lira, Alejandro and Tang, Yuehua}, |
| 113 | − title = {Can {ChatGPT} Forecast Stock Price Movements? Return Predictability and Large | |
| 114 | − Language Models}, | |
| 115 | − journal = {arXiv preprint arXiv:2304.07619}, | |
| 116 | − year = {2023} | |
| 356 | + title = {Can {ChatGPT} Forecast Stock Price Movements? Return Predictability and Large Language Models}, | |
| 357 | + journal = {Journal of Financial Economics}, | |
| 358 | + volume = {184}, | |
| 359 | + pages = {104335}, | |
| 360 | + year = {2026}, | |
| 361 | + doi = {10.1016/j.jfineco.2026.104335} | |
| 362 | +} | |
| 363 | + | |
| 364 | +@unpublished{chen2023expected, | |
| 365 | + author = {Chen, Yifei and Kelly, Bryan and Xiu, Dacheng}, | |
| 366 | + title = {Expected Returns and Large Language Models}, | |
| 367 | + note = {Working paper, Yale University and University of Chicago Booth School of Business}, | |
| 368 | + year = {2023} | |
| 369 | +} | |
| 370 | + | |
| 371 | +@unpublished{hansen2023fedspeak, | |
| 372 | + author = {Hansen, Anne Lundgaard and Kazinnik, Sophia}, | |
| 373 | + title = {Can {ChatGPT} Decipher {Fedspeak}?}, | |
| 374 | + note = {SSRN working paper 4399406, \url{https://doi.org/10.2139/ssrn.4399406}}, | |
| 375 | + year = {2023} | |
| 376 | +} | |
| 377 | + | |
| 378 | +@unpublished{kim2024financial, | |
| 379 | + author = {Kim, Alex and Muhn, Maximilian and Nikolaev, Valeri}, | |
| 380 | + title = {Financial Statement Analysis with Large Language Models}, | |
| 381 | + note = {Chicago Booth Research Paper, SSRN 4835311, \url{https://doi.org/10.2139/ssrn.4835311}; arXiv:2407.17866, withdrawn by the authors on 20 February 2025 pending a review of data inconsistencies}, | |
| 382 | + year = {2024} | |
| 383 | +} | |
| 384 | + | |
| 385 | +@article{fatouros2025marketsenseai, | |
| 386 | + author = {Fatouros, Georgios and Metaxas, Konstantinos and Soldatos, John and Kyriazis, Dimosthenis}, | |
| 387 | + title = {Can Large Language Models Beat {Wall Street}? Evaluating {GPT-4}'s Impact on Financial Decision-Making with {MarketSenseAI}}, | |
| 388 | + journal = {Neural Computing and Applications}, | |
| 389 | + volume = {37}, | |
| 390 | + number = {30}, | |
| 391 | + pages = {24893--24918}, | |
| 392 | + year = {2025}, | |
| 393 | + doi = {10.1007/s00521-024-10613-4} | |
| 117 | 394 | } |
| 118 | 395 | |
| 119 | −@article{kim2024financial, | |
| 120 | − author = {Kim, Alex and Muhn, Maximilian and Nikolaev, Valeri}, | |
| 121 | − title = {Financial Statement Analysis with Large Language Models}, | |
| 122 | − journal = {arXiv preprint arXiv:2407.17866}, | |
| 123 | − year = {2024} | |
| 396 | +@article{korinek2023generative, | |
| 397 | + author = {Korinek, Anton}, | |
| 398 | + title = {Generative {AI} for Economic Research: Use Cases and Implications for Economists}, | |
| 399 | + journal = {Journal of Economic Literature}, | |
| 400 | + volume = {61}, | |
| 401 | + number = {4}, | |
| 402 | + pages = {1281--1317}, | |
| 403 | + year = {2023}, | |
| 404 | + doi = {10.1257/jel.20231736} | |
| 405 | +} | |
| 406 | + | |
| 407 | +@article{dell2025deep, | |
| 408 | + author = {Dell, Melissa}, | |
| 409 | + title = {Deep Learning for Economists}, | |
| 410 | + journal = {Journal of Economic Literature}, | |
| 411 | + volume = {63}, | |
| 412 | + number = {1}, | |
| 413 | + pages = {5--58}, | |
| 414 | + year = {2025}, | |
| 415 | + doi = {10.1257/jel.20241733} | |
| 124 | 416 | } |
| 125 | 417 | |
| 126 | 418 | % --- Classical quantitative finance --- |
@@ -131,7 +423,8 @@ | ||
| 131 | 423 | volume = {81}, |
| 132 | 424 | number = {3}, |
| 133 | 425 | pages = {637--654}, |
| 134 | − year = {1973} | |
| 426 | + year = {1973}, | |
| 427 | + doi = {10.1086/260062} | |
| 135 | 428 | } |
| 136 | 429 | |
| 137 | 430 | @article{merton1973theory, |
@@ -141,7 +434,8 @@ | ||
| 141 | 434 | volume = {4}, |
| 142 | 435 | number = {1}, |
| 143 | 436 | pages = {141--183}, |
| 144 | − year = {1973} | |
| 437 | + year = {1973}, | |
| 438 | + doi = {10.2307/3003143} | |
| 145 | 439 | } |
| 146 | 440 | |
| 147 | 441 | @article{engle1982autoregressive, |
@@ -152,7 +446,8 @@ | ||
| 152 | 446 | volume = {50}, |
| 153 | 447 | number = {4}, |
| 154 | 448 | pages = {987--1007}, |
| 155 | − year = {1982} | |
| 449 | + year = {1982}, | |
| 450 | + doi = {10.2307/1912773} | |
| 156 | 451 | } |
| 157 | 452 | |
| 158 | 453 | @article{bollerslev1986generalized, |
@@ -162,14 +457,17 @@ | ||
| 162 | 457 | volume = {31}, |
| 163 | 458 | number = {3}, |
| 164 | 459 | pages = {307--327}, |
| 165 | − year = {1986} | |
| 460 | + year = {1986}, | |
| 461 | + doi = {10.1016/0304-4076(86)90063-1} | |
| 166 | 462 | } |
| 167 | 463 | |
| 168 | 464 | @book{glasserman2004monte, |
| 169 | 465 | author = {Glasserman, Paul}, |
| 170 | 466 | title = {Monte Carlo Methods in Financial Engineering}, |
| 171 | 467 | publisher = {Springer}, |
| 172 | − year = {2004} | |
| 468 | + address = {New York}, | |
| 469 | + year = {2004}, | |
| 470 | + doi = {10.1007/978-0-387-21617-1} | |
| 173 | 471 | } |
| 174 | 472 | |
| 175 | 473 | @book{jorion2007value, |
@@ -177,5 +475,6 @@ | ||
| 177 | 475 | title = {Value at Risk: The New Benchmark for Managing Financial Risk}, |
| 178 | 476 | edition = {3rd}, |
| 179 | 477 | publisher = {McGraw-Hill}, |
| 478 | + address = {New York}, | |
| 180 | 479 | year = {2007} |
| 181 | 480 | } |
modified
paper/sections/conclusion.tex
+25 −37
@@ -3,41 +3,29 @@ | ||
| 3 | 3 | \label{sec:conclusion} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | −This paper has documented the methodology and innovations of VQuant, a production-grade platform | |
| 7 | −that turns a natural-language request into a complete, reproducible quantitative financial | |
| 8 | −report. The system's organizing principle is a strict division of labor: the large language | |
| 9 | −model plans and synthesizes, while deterministic code retrieves data and performs computation. | |
| 10 | −This separation is what allows VQuant to combine the accessibility of a conversational interface | |
| 11 | −with the rigor demanded by financial analysis. | |
| 6 | +This paper has described VQuant, a deployed platform that turns a natural-language request into | |
| 7 | +a quantitative financial report under one organising principle: the language model plans and | |
| 8 | +synthesises, and deterministic code retrieves data and performs computation. We specified four | |
| 9 | +mechanisms as implemented and audited against the source code---a recursive, batched, streaming | |
| 10 | +tool-calling loop over a 245-tool catalogue; a three-stage context-management procedure with its | |
| 11 | +actual constants; a single-call computation convention and the process-isolated sandbox that | |
| 12 | +executes it; and a document pipeline from one Markdown artifact to PDF, DOCX, Beamer, and | |
| 13 | +live-formula spreadsheets---and we corrected the earlier description of the system where the | |
| 14 | +code differs from it. In the vocabulary of design science, the paper contributes a situated | |
| 15 | +implementation and a demonstration; the evaluation step is specified but not performed. | |
| 12 | 16 | |
| 13 | −We highlighted four methodological contributions. The \emph{agentic orchestration loop} | |
| 14 | −(Section~\ref{subsec:loop}) exposes a curated catalogue of more than two hundred tools to the | |
| 15 | −model through a constrained, batched, fully streaming protocol, with a system prompt that routes | |
| 16 | −requests by complexity. The \emph{context-management algorithm} (Section~\ref{subsec:context}) | |
| 17 | −keeps arbitrarily long conversations within the model's window by adaptively summarizing older | |
| 18 | −history while preserving recent turns verbatim. The \emph{single-call computation paradigm} | |
| 19 | −(Section~\ref{subsec:onecall}) consolidates data acquisition, estimation, and visualization into | |
| 20 | −one sandboxed Python execution, materially reducing latency relative to sequential tool calling. | |
| 21 | −And the \emph{unified document pipeline} (Section~\ref{subsec:docs}) emits PDF, Word, Beamer | |
| 22 | −slides, and live-formula spreadsheets from a single Markdown artifact. We described each of these | |
| 23 | −at the mechanism level---the eight-way event dispatch, the recursive loop and its | |
| 24 | −tool-use/tool-result invariant, the batching throttle, the two-stage context machinery, the | |
| 25 | −token-accounting correction, and the inter-process sandbox that exec's model-authored code and | |
| 26 | −captures its figures---together with the streaming experience, multi-model selection, cost | |
| 27 | −discipline, and security measures that make the system practical. The classical quantitative | |
| 28 | −methods the platform automates are conventional and recorded compactly in the appendix; the | |
| 29 | −contribution is the architecture, not the formulae. | |
| 30 | − | |
| 31 | −The natural next step is empirical. A rigorous evaluation would benchmark VQuant against | |
| 32 | −baseline agentic patterns along three axes: \emph{quality}, via expert assessment of report | |
| 33 | −accuracy and completeness on a fixed task suite; \emph{efficiency}, via controlled measurement of | |
| 34 | −latency, token consumption, and dollar cost, isolating the contribution of the single-call | |
| 35 | −paradigm and the context-management algorithm; and \emph{reliability}, via systematic probing | |
| 36 | −for numerical and interpretive errors. Methodologically, the design admits several extensions: | |
| 37 | −incorporating provider-agnostic tool exposure to broaden the model layer; adding a verification | |
| 38 | −pass in which a second model audits the first model's narrative against the computed numbers; and | |
| 39 | −generalizing the deterministic-computation substrate beyond finance to any domain where | |
| 40 | −auditable numbers matter. We offer VQuant as a concrete, reproducible instance of \emph{agentic | |
| 41 | −financial intelligence}---a design pattern in which the language model is a disciplined | |
| 42 | −orchestrator of trustworthy tools rather than an unverified oracle---and as a foundation for the | |
| 43 | −evaluation agenda above. | |
| 17 | +The limits of what has been shown are therefore clear. The architecture removes numbers from | |
| 18 | +the model's remit, but whether this reduces unsupported numbers to near zero, by how much the | |
| 19 | +single-call convention reduces round trips and at what cost in failed executions, how much the | |
| 20 | +summarisation procedure loses, and what the design costs relative to simpler agents are empirical | |
| 21 | +questions that the protocol of Section~\ref{subsec:protocol} is written to answer and that this | |
| 22 | +paper does not. Executing that protocol is the natural next step and the one on which any claim | |
| 23 | +of superiority must wait. Three engineering changes are also warranted by the audit: a bound on | |
| 24 | +recursion depth, a per-model price table in the ledger, and the restoration of the pre-built | |
| 25 | +numerical routines to the tool catalogue. Beyond these, the design admits extensions that the | |
| 26 | +protocol could also evaluate: a verification pass in which a second model audits the first's | |
| 27 | +narrative against the computed numbers, provider-independent tool exposure through the Model | |
| 28 | +Context Protocol, and generalisation of the deterministic-computation substrate to other domains | |
| 29 | +in which auditable numbers matter. We offer the specification, the audit, and the protocol as the | |
| 30 | +contribution, and the pattern they describe---a language model as a disciplined orchestrator of | |
| 31 | +trustworthy tools rather than as an unverified oracle---as a hypothesis to be tested. | |
modified
paper/sections/data.tex
+77 −62
@@ -1,90 +1,105 @@ | ||
| 1 | 1 | % ============================================================================ |
| 2 | −\section{System Architecture and Data Layer} | |
| 2 | +\section{System Architecture, Data Layer, and Model Layer} | |
| 3 | 3 | \label{sec:architecture} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | −This section describes VQuant's architecture, the data it consumes, and the external services | |
| 7 | −it integrates. We treat the architecture as the ``setting'' of the paper: the methodology of | |
| 8 | −Section~\ref{sec:methodology} is a set of algorithms that run \emph{within} the structure | |
| 9 | −described here. | |
| 6 | +This section describes the setting within which the mechanisms of Section~\ref{sec:methodology} | |
| 7 | +operate: the three tiers of the platform, the external data and services it integrates, its | |
| 8 | +persistence layer, and the model layer. All statements refer to the audited commit; where the | |
| 9 | +first version of this paper described a different state, the difference is noted. | |
| 10 | 10 | |
| 11 | 11 | \subsection{Overview} |
| 12 | 12 | \label{subsec:overview} |
| 13 | 13 | |
| 14 | −VQuant is a full-stack TypeScript monorepo comprising three cooperating tiers | |
| 15 | −(Figure~\ref{fig:architecture}). A \textbf{React front end} renders a conversational interface | |
| 16 | −and streams results to the user as they are produced. A \textbf{modular Express back end} | |
| 17 | −orchestrates the LLM, executes tool calls, manages context and authentication, and persists | |
| 18 | −sessions. An \textbf{isolated Python layer} performs numerical computation in a sandboxed | |
| 19 | −subprocess. The three tiers communicate over HTTP, with the client--server channel using | |
| 20 | −Server-Sent Events (SSE) to stream incremental output. The data layer is abstracted through an | |
| 21 | −object-relational mapper that targets SQLite in development and PostgreSQL in production behind | |
| 22 | −a single typed access interface, so that storage logic is identical across environments. | |
| 14 | +VQuant is a TypeScript monorepo with three cooperating tiers (Figure~\ref{fig:architecture}). A | |
| 15 | +\textbf{React front end} renders a conversational interface and updates it as events arrive. A | |
| 16 | +\textbf{modular Express back end} orchestrates the model, executes tool calls, manages context | |
| 17 | +and authentication, and persists sessions. An \textbf{isolated Python layer} performs numerical | |
| 18 | +computation in a sandboxed child process. The client--server channel uses Server-Sent Events (SSE) | |
| 19 | +to stream incremental output. Persistence is abstracted through an object-relational mapper | |
| 20 | +(Drizzle) with two parallel schema definitions---SQLite for development and single-node | |
| 21 | +deployment, PostgreSQL for hosted deployment---behind one typed access interface, so that storage | |
| 22 | +logic is identical across environments. The code base is organised into six route modules | |
| 23 | +(authentication, administration, analytics, market-data proxying, report management, and the chat | |
| 24 | +stream) and a set of services, each encapsulating one external capability; the repository ships | |
| 25 | +with six automated test suites covering request validation and client state. | |
| 23 | 26 | |
| 24 | 27 | \input{figures/architecture} |
| 25 | 28 | |
| 26 | 29 | \subsection{The front end} |
| 27 | 30 | \label{subsec:frontend} |
| 28 | 31 | |
| 29 | −The client is a single-page application. Its central abstraction is a session hook that owns | |
| 30 | −the full conversational state---the streaming answer, the model's intermediate reasoning, the | |
| 31 | −ordered list of tool invocations, retrieved sources, generated figures, and the results of | |
| 32 | −specialized computations such as Monte Carlo simulations and option-pricing tables. A companion | |
| 33 | −mutation hook manages the SSE connection: it issues the request, reads the byte stream, decodes | |
| 34 | −discrete events, and dispatches each to the appropriate state setter. Because state updates are | |
| 35 | −event-driven, the interface renders the agent's behavior \emph{as it happens}---text appears | |
| 36 | −token by token, tool calls populate a progress indicator, reasoning expands in a collapsible | |
| 37 | −panel, and figures materialize as the Python layer emits them. This streaming design is central | |
| 38 | −to the user experience and is discussed further in Section~\ref{sec:evaluation}. | |
| 32 | +The client is a single-page application whose central abstraction is a session hook owning the | |
| 33 | +full conversational state: the streaming answer, the model's reasoning summary, the ordered list of | |
| 34 | +tool invocations with their status, retrieved sources, generated figures, and the results of | |
| 35 | +specialised computations. A companion mutation hook manages the SSE connection: it issues the | |
| 36 | +request, reads the byte stream, decodes discrete events, and dispatches each to the appropriate | |
| 37 | +state setter. Because state updates are event-driven, the interface renders the agent's behaviour | |
| 38 | +as it happens---text appears incrementally, tool calls populate a progress indicator, reasoning | |
| 39 | +expands in a collapsible panel, and figures appear as the Python layer emits them. The client-side | |
| 40 | +event taxonomy is listed in Appendix~\ref{app:events}. | |
| 39 | 41 | |
| 40 | 42 | \subsection{The back end} |
| 41 | 43 | \label{subsec:backend} |
| 42 | 44 | |
| 43 | −The server is organized into route modules (authentication, administration, analytics, | |
| 44 | −market-data proxying, report management, and the chat stream) and a set of isolated services | |
| 45 | −that encapsulate business logic. The most important service mediates all communication with the | |
| 46 | −LLM: it assembles the system prompt and tool catalogue, enforces the token budget, opens the | |
| 47 | −streaming connection, parses the provider's event stream, dispatches tool calls, and relays | |
| 48 | −results back to the client. Document generation, web research, and the quantitative-method | |
| 49 | −wrappers are each implemented as separate services, so that the orchestration logic remains | |
| 50 | −decoupled from the mechanics of any single capability. All request bodies are validated against | |
| 51 | −schemas at the boundary, eliminating untyped inputs and yielding uniform error handling. | |
| 45 | +The most important service mediates all communication with the model provider: it assembles the | |
| 46 | +system prompt and tool catalogue, applies the context-management procedure, opens the streaming | |
| 47 | +connection, parses the provider's event stream, and returns text, tool requests, and usage to the | |
| 48 | +route that owns the recursive loop (Section~\ref{subsec:loop}). Document generation, web research, | |
| 49 | +the two market-data clients, and the Python executors are separate services, so that orchestration | |
| 50 | +logic is decoupled from the mechanics of any single capability. Request bodies are validated | |
| 51 | +against Zod schemas at the boundary, which rejects malformed input uniformly before it reaches | |
| 52 | +business logic. | |
| 52 | 53 | |
| 53 | −\subsection{The data layer and external integrations} | |
| 54 | +\subsection{Data layer and external integrations} | |
| 54 | 55 | \label{subsec:data} |
| 55 | 56 | |
| 56 | −VQuant is grounded in live data; it stores essentially no market data itself. Its primary | |
| 57 | −financial source is a commercial market-data provider exposing more than 265 endpoints, wrapped | |
| 58 | −by roughly 230 typed functions on the server and mirrored by a Python client used inside the | |
| 59 | −sandbox. These endpoints cover company fundamentals (income statements, balance sheets, cash | |
| 60 | −flows, key metrics and ratios), market data (real-time and historical quotes, intraday series, | |
| 61 | −market movers), technical indicators (RSI, MACD, moving averages, ADX, stochastics, and | |
| 62 | −others), analyst data (estimates, price targets, upgrades and downgrades, rating histories), | |
| 63 | −insider and institutional activity (insider transactions, 13F filings, congressional and | |
| 64 | −senate trading), macroeconomic series (treasury rates, economic indicators, the economic | |
| 65 | −calendar, COT reports), foreign exchange and commodities, SEC filings and earnings-call | |
| 66 | −transcripts, corporate events (earnings, dividends, splits, IPOs), and ESG and alternative-data | |
| 67 | −signals. Table~\ref{tab:tools} in Section~\ref{sec:methodology} summarizes the resulting tool | |
| 68 | −taxonomy. | |
| 57 | +VQuant stores essentially no market data; it is grounded in live retrieval. Its primary financial | |
| 58 | +source is a commercial market-data provider (Financial Modeling Prep) whose ``stable'' API is | |
| 59 | +wrapped by 249 exported, typed server functions spanning 233 distinct endpoint paths, and | |
| 60 | +mirrored by a small Python client injected into the sandbox. A second provider (EODHD) supplies | |
| 61 | +end-of-day and intraday history, fundamentals, and news for instruments on more than seventy | |
| 62 | +exchanges outside the United States, and is the source of the platform's options chains and Greeks. | |
| 63 | +Together these endpoints cover company fundamentals, quotes and intraday series, technical | |
| 64 | +indicators (several of which, such as MACD and CCI, are computed server-side from price history | |
| 65 | +because the provider does not expose them), analyst data, insider and institutional activity, | |
| 66 | +macroeconomic series, foreign exchange and commodities, SEC filings and earnings-call transcripts, | |
| 67 | +corporate events, indices and funds, and ESG and alternative data. Table~\ref{tab:tools} in | |
| 68 | +Section~\ref{sec:methodology} gives the resulting tool taxonomy with exact counts. | |
| 69 | 69 | |
| 70 | −Beyond structured financial data, VQuant integrates four complementary web-research services---a | |
| 71 | −web-scraping and extraction service, an AI search service, a neural semantic-search service, and | |
| 72 | −a general search-engine API---so that the agent can incorporate qualitative and breaking | |
| 73 | −information that no structured endpoint captures. The persistence layer stores users (with | |
| 74 | −optional encrypted custom API keys), conversation sessions (including token accounting and cost | |
| 75 | −estimates), shared reports addressable by a unique public identifier, daily-usage counters, and | |
| 76 | −analytics events. This schema supports the platform's authentication, rate-limiting, | |
| 77 | −report-sharing, and observability features, which we revisit in Section~\ref{sec:evaluation}. | |
| 70 | +Beyond structured data, three web-research services are exposed to the model as fourteen tools: a | |
| 71 | +scraping, crawling, and extraction service (Firecrawl), an AI search and research service | |
| 72 | +(Tavily), and a neural search service (Exa). A fourth service (a search-engine API) and a | |
| 73 | +text-to-speech service are integrated server-side but have no tool definitions at the audited | |
| 74 | +commit and are therefore not reachable by the model. | |
| 75 | + | |
| 76 | +The persistence layer defines twelve entities (Appendix~\ref{app:schema}): users, one-time | |
| 77 | +authentication codes, trusted devices, a security event log, conversation sessions with their | |
| 78 | +serialised messages and token and cost ledgers, individual messages, shared reports addressable by | |
| 79 | +a public identifier, live-user presence, aggregated analytics metrics, request logs, and two | |
| 80 | +tables for crawled pages and their embeddings. The first version of this paper described | |
| 81 | +per-user encrypted API keys and daily usage counters; neither exists in any committed version of | |
| 82 | +the schema, and the corresponding ``bring-your-own-keys'' feature described there is not | |
| 83 | +implemented. We correct the record in Section~\ref{subsec:auth}. | |
| 78 | 84 | |
| 79 | 85 | \subsection{Model layer} |
| 80 | 86 | \label{subsec:models} |
| 81 | 87 | |
| 82 | −VQuant is model-agnostic within the Claude family and exposes a user-facing selector | |
| 83 | −(Table~\ref{tab:models}). The default is a reasoning-augmented model with a very large context | |
| 84 | −window; users may instead select higher-capability or lower-latency alternatives to trade off | |
| 85 | −quality, speed, and cost per query. The orchestration service detects which models support | |
| 86 | −adaptive extended thinking and enables it only for those, so that the same code path serves the | |
| 87 | −full model range. This abstraction is what allows the methodology of the next section to be | |
| 88 | −stated independently of any particular model. | |
| 88 | +The platform exposes a user-facing model selector (Table~\ref{tab:models}). The reference path, | |
| 89 | +and the one described in Section~\ref{sec:methodology}, targets the Anthropic Messages API: the | |
| 90 | +default model is \texttt{claude-fable-5}, and the orchestration service enables adaptive extended | |
| 91 | +thinking for the five models that support it (Table~\ref{tab:models}) by attaching a thinking | |
| 92 | +directive of type \texttt{adaptive} with a summarised display; the Haiku model is served without | |
| 93 | +it. A uniform generation cap of 64{,}000 output tokens applies, and the request | |
| 94 | +sets the sampling temperature to~1 (the provider default). At the audited commit the selector | |
| 95 | +also lists OpenAI and Google models, served through a second adapter that speaks the | |
| 96 | +OpenAI-compatible chat-completions interface, converts the Anthropic-style tool schemas and | |
| 97 | +message history into that interface's function-calling format, and---because that interface caps | |
| 98 | +the number of tools at 128---transmits only the first 128 tools of the catalogue. We do not audit | |
| 99 | +those model identifiers or that path further; the first version of this paper described the | |
| 100 | +platform as Claude-only, which was accurate for the version then deployed but is no longer so. | |
| 101 | +What matters for the methodology is that the loop of Section~\ref{sec:methodology} is written | |
| 102 | +against one internal representation (Anthropic-style content blocks) and that provider | |
| 103 | +differences are confined to the two transport adapters. | |
| 89 | 104 | |
| 90 | 105 | \input{tables/models} |
modified
paper/sections/introduction.tex
+85 −74
@@ -3,82 +3,93 @@ | ||
| 3 | 3 | \label{sec:introduction} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | −The rapid maturation of large language models (LLMs) has transformed expectations about | |
| 7 | −what conversational software can accomplish in finance. Models such as the Claude, GPT, and | |
| 8 | −Gemini families now produce fluent commentary on earnings, valuations, and macroeconomic | |
| 9 | −conditions, and a growing literature documents their ability to extract signal from financial | |
| 10 | −text \citep{lopezlira2023chatgpt,kim2024financial,wu2023bloomberggpt}. Yet fluency is not the | |
| 11 | −same as rigor. A model that \emph{describes} a value-at-risk calculation in prose has not | |
| 12 | −\emph{computed} one; a model that \emph{recalls} a stale price from pre-training has not | |
| 13 | −\emph{retrieved} the current quote; and a model that narrates a Monte Carlo experiment has | |
| 14 | −not run the simulation whose numbers a portfolio manager would act upon. The central | |
| 15 | −engineering problem in applied financial AI is therefore not generation but | |
| 16 | −\emph{grounding}: how to bind a probabilistic text generator to live data, deterministic | |
| 17 | −computation, and reproducible artifacts without sacrificing the conversational interface that | |
| 18 | −makes the technology accessible. | |
| 6 | +Large language models (LLMs) now produce fluent commentary on earnings, valuations, and | |
| 7 | +macroeconomic conditions, and a growing literature documents their ability to extract signal | |
| 8 | +from financial text \citep{lopezlira2026chatgpt,wu2023bloomberggpt,hansen2023fedspeak}. Fluency, | |
| 9 | +however, is not rigour. A model that \emph{describes} a value-at-risk calculation has not | |
| 10 | +\emph{computed} one; a model that \emph{recalls} a price from its training data has not | |
| 11 | +\emph{retrieved} the current quote; and a model that narrates a Monte Carlo experiment has not run | |
| 12 | +the simulation whose numbers a portfolio manager would act upon. Surveys of hallucination in | |
| 13 | +natural-language generation \citep{ji2023hallucination} and of LLM evaluation | |
| 14 | +\citep{chang2024survey} make the same point from the other side: generated numbers are not | |
| 15 | +trustworthy unless they are produced, or at least checked, outside the model. The central | |
| 16 | +engineering problem in applied financial AI is therefore \emph{grounding}: how to bind a | |
| 17 | +probabilistic text generator to live data, deterministic computation, and reproducible artifacts | |
| 18 | +without giving up the conversational interface that makes the technology accessible. | |
| 19 | 19 | |
| 20 | −This paper documents the methodology and innovations of \textbf{VQuant}, a production-grade | |
| 21 | −web platform built to address precisely this problem. VQuant accepts a natural-language | |
| 22 | −request---``analyze NVDA's fundamentals, technicals, and run a Monte Carlo simulation,'' for | |
| 23 | −example---and returns a complete, multi-section quantitative report containing live data, | |
| 24 | −computed figures, and downloadable documents. The platform is implemented as a full-stack | |
| 25 | −TypeScript monorepo: a React front end, a modular Express back end, and an isolated Python | |
| 26 | −scientific-computing layer. At its core, the system orchestrates a reasoning-augmented LLM | |
| 27 | −through an \emph{agentic loop} that exposes more than two hundred financial and analytical | |
| 28 | −tools to the model, executes the model's tool calls deterministically, streams the results | |
| 29 | −back in real time, and synthesizes a final report that can be exported in five document | |
| 30 | −formats. | |
| 20 | +This paper describes \textbf{VQuant}, a deployed web platform built around one answer to that | |
| 21 | +problem. VQuant accepts a natural-language request---``analyse NVDA's fundamentals, technicals, | |
| 22 | +and run a Monte Carlo simulation,'' for example---and returns a multi-section report with live | |
| 23 | +data, computed figures, and downloadable documents. The platform is a full-stack TypeScript | |
| 24 | +monorepo: a React front end, a modular Express back end, and an isolated Python | |
| 25 | +scientific-computing layer. Its organising principle is a division of labour: the language model | |
| 26 | +\emph{plans and synthesises}, while deterministic server code \emph{retrieves, schedules, | |
| 27 | +computes, and accounts}. Every number in a VQuant report is meant to originate from a market-data | |
| 28 | +endpoint, a closed-form formula, or Python code that the reader can inspect. The design belongs to | |
| 29 | +the family of program-aided and tool-augmented language models | |
| 30 | +\citep{gao2023pal,chen2023pot,schick2023toolformer,yao2023react,mialon2023augmented}; its | |
| 31 | +specific contribution is to work out, at the level of a production system, what that family's | |
| 32 | +principles require when the tool surface is large, the data are live, and the deliverable is a | |
| 33 | +document. | |
| 31 | 34 | |
| 32 | −The motivation for studying this system is fourfold. \emph{First}, VQuant operationalizes a | |
| 33 | −design philosophy that we believe is the correct one for high-stakes numerical domains: the | |
| 34 | −LLM is a \emph{planner and synthesizer}, never a calculator. Every number in a VQuant report | |
| 35 | −originates from a deterministic source---a market-data API, a closed-form pricing formula, or | |
| 36 | −auditable Python code---so that the analysis is reproducible and the model's well-known | |
| 37 | −propensity for numerical hallucination is structurally contained. \emph{Second}, the platform | |
| 38 | −confronts the practical constraints of agentic systems---bounded context windows, tool-call | |
| 39 | −latency, rate limits, and cost---with concrete algorithmic solutions whose logic generalizes | |
| 40 | −beyond finance. \emph{Third}, VQuant integrates an unusually broad tool ecosystem (over 265 | |
| 41 | −market-data endpoints, four web-research services, and a seventeen-library Python sandbox) | |
| 42 | −under a single function-calling protocol, providing a useful case study in tool taxonomy and | |
| 43 | −prompt-level routing. \emph{Fourth}, the system closes the loop from query to deliverable by | |
| 44 | −generating publication-ready PDF, Word, \LaTeX{} Beamer, and spreadsheet outputs from a single | |
| 45 | −internal representation, illustrating a reusable pattern for automated report generation. | |
| 35 | +\paragraph{What kind of paper this is.} This is a \emph{design-science} paper in the sense of | |
| 36 | +\citet{hevner2004design} and \citet{gregor2013positioning}: it presents an artifact, states the | |
| 37 | +problem it addresses, and specifies its construction precisely enough to be reproduced and later | |
| 38 | +evaluated. It is \emph{not} an empirical evaluation. We report no measurements of numerical | |
| 39 | +accuracy against ground truth, no hallucination rates, no latency or cost benchmarks, and no | |
| 40 | +ablations; where the first version of this paper used the words ``results'' and ``robustness'', the | |
| 41 | +present version uses ``design rationale'' and ``threats to validity''. Section~\ref{sec:evaluation} | |
| 42 | +instead specifies the evaluation we think the artifact warrants---benchmark, metrics, ablations, | |
| 43 | +and baselines---and marks it explicitly as not yet executed. We regard this separation as a | |
| 44 | +matter of research integrity: a system paper that reports qualitative impressions as results | |
| 45 | +invites exactly the kind of unverifiable claim that the system itself is designed to prevent. | |
| 46 | 46 | |
| 47 | −Our contributions are methodological and architectural rather than empirical. We make four | |
| 48 | −specific contributions. \textbf{(1)~Agentic orchestration with constrained tool use.} We | |
| 49 | −describe a streaming tool-calling loop (Section~\ref{sec:methodology}) in which a strategically | |
| 50 | −engineered system prompt routes requests to an appropriate subset of more than two hundred | |
| 51 | −tools, batches tool execution to respect external rate limits, and surfaces the model's | |
| 52 | −intermediate reasoning to the user in real time. \textbf{(2)~Context management under a token | |
| 53 | −budget.} We formalize an adaptive-summarization algorithm that preserves coherence across | |
| 54 | −effectively unbounded conversation histories by compressing older turns once a token threshold | |
| 55 | −is crossed, while retaining the most recent exchanges verbatim. \textbf{(3)~A single-call | |
| 56 | −computation paradigm.} We argue that consolidating data acquisition, numerical estimation, and | |
| 57 | −visualization into one sandboxed Python execution---rather than the sequential | |
| 58 | −fetch-then-analyze pattern typical of naive agents---materially reduces end-to-end latency, and | |
| 59 | −we describe the sandbox and its safety properties (Section~\ref{sec:capabilities}). \textbf{(4)~A | |
| 60 | −unified multi-format document pipeline.} We detail how a single Markdown artifact is | |
| 61 | −transformed into PDF (headless-browser rendering with mathematical typesetting), DOCX (document | |
| 62 | −converter), Beamer slides (model-structured \LaTeX{} compiled to PDF), and spreadsheets with | |
| 63 | −live formulas. | |
| 47 | +\paragraph{Audit against the code.} A second feature of this version is that every mechanism | |
| 48 | +described has been checked against the platform's source code at a fixed commit | |
| 49 | +(\texttt{vquant.git}, commit \texttt{e2a148a}, 2 October 2026, hereafter ``the audited | |
| 50 | +commit''). Where the implementation differs from the platform's own documentation, or from the | |
| 51 | +first version of this paper, we say so. Three such discrepancies are material and are reported in | |
| 52 | +the text: the tool catalogue contains 245 tools rather than the ``200+'' and ``213'' figures used in | |
| 53 | +earlier descriptions; the token-accounting correction uses a general-purpose byte-pair tokenizer | |
| 54 | +whose vocabulary differs from the provider's, so the ``exact'' count of the earlier description is | |
| 55 | +an approximation; and several pre-built numerical routines (Monte Carlo, GARCH, VaR, portfolio | |
| 56 | +optimisation) have server-side handlers but are absent from the tool catalogue, so the model cannot | |
| 57 | +invoke them. Appendix~\ref{app:audit} tabulates each claim of the paper with the file that | |
| 58 | +supports it. | |
| 64 | 59 | |
| 65 | −Our emphasis throughout is on \emph{mechanism}. We describe each component as it is actually | |
| 66 | −built---the byte-level streaming protocol, the recursion that drives the loop, the throttle that | |
| 67 | −batches tool calls, the two-stage machinery that keeps the context within budget, the correction | |
| 68 | −that keeps token accounting honest, and the inter-process boundary that executes model-authored | |
| 69 | −code---so that the design is reproducible rather than merely sketched. The classical quantitative | |
| 70 | −methods the platform automates (option pricing, volatility modeling, simulation, and risk | |
| 71 | −metrics) are standard and not the contribution of this paper; we record them compactly in an | |
| 72 | −appendix and otherwise keep the focus on the architecture. | |
| 60 | +\paragraph{Terminology.} Three terms recur and are used in a fixed sense. An \emph{agentic} loop is | |
| 61 | +a control structure in which the model's output can request actions (tool calls) whose results are | |
| 62 | +fed back to the model, repeatedly, until it produces a final answer | |
| 63 | +\citep{yao2023react,wang2024agents}; the loop is agentic in this operational sense and no claim | |
| 64 | +about autonomy is implied. \emph{Tool use} (or function calling) is the provider-level protocol by | |
| 65 | +which a model emits a structured call against a declared JSON schema and receives a structured | |
| 66 | +result \citep{anthropic2026tooluse,schick2023toolformer}. A \emph{reasoning-capable} model is one | |
| 67 | +that can allocate an adaptive budget of private intermediate tokens to deliberation before and | |
| 68 | +between its visible outputs \citep{wei2022chain}; the platform surfaces a summary of this | |
| 69 | +deliberation to the user but does not depend on its content. | |
| 73 | 70 | |
| 74 | −The remainder of the paper is organized as follows. | |
| 75 | −Section~\ref{sec:literature} situates VQuant within the literatures on LLM agents, tool use, | |
| 76 | −retrieval augmentation, and AI in finance. | |
| 77 | −Section~\ref{sec:architecture} presents the system architecture, data layer, and external | |
| 78 | −integrations. | |
| 79 | −Section~\ref{sec:methodology} develops the agentic orchestration methodology, including the | |
| 80 | −tool taxonomy, context-management algorithm, and single-call execution paradigm. | |
| 81 | −Section~\ref{sec:capabilities} formalizes the embedded quantitative methods and the | |
| 82 | −document-generation pipeline. | |
| 83 | −Section~\ref{sec:evaluation} discusses performance, reliability, security, and limitations. | |
| 84 | −Section~\ref{sec:conclusion} concludes and outlines directions for evaluation and extension. | |
| 71 | +\paragraph{Contributions.} Within these bounds the paper makes four contributions. | |
| 72 | +\textbf{(1)~A specified orchestration loop.} Section~\ref{sec:methodology} gives the streaming | |
| 73 | +transport, the recursive tool-calling procedure, the batching throttle, and the prompt-level | |
| 74 | +routing that let a model navigate a catalogue of 245 tools without an explicit planner. | |
| 75 | +\textbf{(2)~A specified context-management procedure.} We state, as an algorithm with its actual | |
| 76 | +constants, the three-stage mechanism---per-result truncation at execution time, a re-send cap, and | |
| 77 | +adaptive summarisation under a token budget---that keeps long sessions within the model's context | |
| 78 | +window, and we relate it to the known degradation of long-context attention | |
| 79 | +\citep{liu2024lost}. \textbf{(3)~A single-call computation convention and its substrate.} We argue | |
| 80 | +that consolidating data acquisition, estimation, and visualisation into one sandboxed execution | |
| 81 | +removes model round trips, and we specify the inter-process sandbox that executes model-authored | |
| 82 | +code. \textbf{(4)~A document pipeline.} We describe how one Markdown artifact becomes PDF, DOCX, | |
| 83 | +Beamer slides, and spreadsheets with live formulas. A fifth, methodological, contribution is the | |
| 84 | +evaluation protocol of Section~\ref{subsec:protocol}. | |
| 85 | + | |
| 86 | +The classical quantitative methods the platform automates---option pricing, conditional-volatility | |
| 87 | +modelling, simulation, and risk metrics---are standard and are recorded compactly in | |
| 88 | +Appendix~\ref{app:numerical}. The remainder of the paper is organised as follows. | |
| 89 | +Section~\ref{sec:literature} situates the artifact in the literatures on tool-augmented LLMs, LLM | |
| 90 | +agents and their evaluation, and LLMs in finance and economics. Section~\ref{sec:architecture} | |
| 91 | +describes the architecture, data layer, and model layer. Section~\ref{sec:methodology} develops | |
| 92 | +the orchestration mechanisms. Section~\ref{sec:capabilities} describes the execution substrate and | |
| 93 | +the document pipeline and walks through one request as an illustration. | |
| 94 | +Section~\ref{sec:evaluation} gives the design rationale, threats to validity, reproducibility | |
| 95 | +information, and the proposed evaluation protocol. Section~\ref{sec:conclusion} concludes. | |
modified
paper/sections/literature.tex
+97 −61
@@ -3,78 +3,114 @@ | ||
| 3 | 3 | \label{sec:literature} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | −VQuant sits at the intersection of four research strands: (i)~large language models and | |
| 7 | −reasoning, (ii)~tool-augmented and agentic systems, (iii)~retrieval augmentation and grounding, | |
| 8 | −and (iv)~the application of LLMs to finance. We review each in turn and position our | |
| 9 | −contribution accordingly. | |
| 6 | +VQuant draws on four strands of research: the design-science tradition in information systems, | |
| 7 | +which supplies the paper's genre; the literature on tool-augmented language models and LLM | |
| 8 | +agents, which supplies the mechanisms; work on the evaluation of such agents, which supplies the | |
| 9 | +standard the paper does not yet meet; and the rapidly growing literature on LLMs in finance and | |
| 10 | +economics, which supplies the application and its risks. | |
| 10 | 11 | |
| 11 | −\subsection{Language models and reasoning} | |
| 12 | −\label{subsec:lit_lms} | |
| 12 | +\subsection{Design science and system descriptions} | |
| 13 | +\label{subsec:lit_ds} | |
| 13 | 14 | |
| 14 | −The transformer architecture of \citet{vaswani2017attention} and the demonstration of | |
| 15 | −in-context, few-shot learning at scale by \citet{brown2020language} established the modern | |
| 16 | −paradigm of general-purpose language models. A complementary line of work showed that | |
| 17 | −intermediate ``chain-of-thought'' reasoning improves performance on multi-step problems | |
| 18 | −\citep{wei2022chain}, motivating a generation of models that allocate explicit computation to | |
| 19 | −deliberation before answering. VQuant builds directly on this development: it targets | |
| 20 | −reasoning-augmented models that can ``think'' under an adaptive token budget prior to | |
| 21 | −responding, and it surfaces this intermediate reasoning to the user. We treat the foundation | |
| 22 | −model as a fixed, externally provided capability \citep{bommasani2021opportunities} and study | |
| 23 | −the \emph{system} that must be engineered around it. | |
| 15 | +Information-systems research distinguishes behavioural studies, which test theories about the use | |
| 16 | +of artifacts, from design-science studies, which build and evaluate artifacts that solve | |
| 17 | +identified problems \citep{hevner2004design}. \citet{peffers2007design} give the canonical | |
| 18 | +process---problem identification, objectives, design and development, demonstration, evaluation, | |
| 19 | +communication---and \citet{gregor2013positioning} classify contributions by their maturity, from | |
| 20 | +situated implementations to nascent design theories. In those terms the present paper reports a | |
| 21 | +\emph{situated implementation} together with a \emph{demonstration} (a walk-through of one | |
| 22 | +request); the \emph{evaluation} step is specified but not performed. We adopt this vocabulary | |
| 23 | +deliberately: it lets us describe a working system in detail while making clear which of the | |
| 24 | +process's steps remain open. | |
| 24 | 25 | |
| 25 | −\subsection{Tool use and agentic systems} | |
| 26 | +\subsection{Tool-augmented language models and agents} | |
| 26 | 27 | \label{subsec:lit_agents} |
| 27 | 28 | |
| 28 | −A model confined to its parametric memory cannot retrieve live prices or perform exact | |
| 29 | −arithmetic. The tool-use literature addresses this by teaching models to call external | |
| 30 | −functions. \citet{schick2023toolformer} showed that models can learn to invoke APIs, while the | |
| 31 | −ReAct framework of \citet{yao2023react} interleaved reasoning traces with actions in an | |
| 32 | −observe--think--act loop that has become the template for modern agents. Program-aided | |
| 33 | −approaches \citep{gao2023pal} delegate computation to a code interpreter, offloading exact | |
| 34 | −arithmetic from the language model to a deterministic runtime---a principle that VQuant adopts | |
| 35 | −as a first-class design constraint. Industrial function-calling protocols | |
| 36 | −\citep{anthropic2024tooluse} standardized the schema-driven invocation of tools, and the Model | |
| 37 | −Context Protocol generalized tool exposure across providers. VQuant operationalizes these ideas | |
| 38 | −at scale: rather than a handful of tools, it exposes a curated catalogue of more than two | |
| 39 | −hundred, and it contributes practical mechanisms---prompt-level routing, execution batching, | |
| 40 | −and a single-call computation paradigm---for managing the resulting orchestration complexity. | |
| 29 | +A model confined to its parameters cannot retrieve a current price or perform exact arithmetic. | |
| 30 | +Chain-of-thought prompting \citep{wei2022chain} improved multi-step reasoning but left | |
| 31 | +computation inside the model; program-aided language models \citep{gao2023pal} and | |
| 32 | +program-of-thoughts prompting \citep{chen2023pot} moved it out, having the model write code that a | |
| 33 | +deterministic interpreter executes, and showed large gains on numerical benchmarks including | |
| 34 | +financial question answering. Toolformer \citep{schick2023toolformer} taught models to insert API | |
| 35 | +calls into their own text, and ReAct \citep{yao2023react} interleaved reasoning traces with | |
| 36 | +actions in an observe--think--act loop that has become the template for agents. The survey of | |
| 37 | +\citet{mialon2023augmented} names this family \emph{augmented language models} and organises it | |
| 38 | +along the two axes---reasoning and tool use---that VQuant combines; \citet{wang2024agents} survey | |
| 39 | +the resulting agent architectures. Retrieval-augmented generation \citep{lewis2020retrieval} is the | |
| 40 | +special case in which the tool is a document retriever; VQuant's ``retrieval'' surface is | |
| 41 | +structured (market-data endpoints), textual (web search and extraction), and computational | |
| 42 | +(code), and the auditability it seeks is the financial analogue of citation grounding. | |
| 41 | 43 | |
| 42 | −\subsection{Retrieval augmentation and grounding} | |
| 43 | −\label{subsec:lit_rag} | |
| 44 | +Two practical problems arise when the tool surface grows. The first is selection: Gorilla | |
| 45 | +\citep{patil2024gorilla} and ToolLLM \citep{qin2024toolllm} fine-tune models to choose among | |
| 46 | +thousands of APIs and introduce retrievers over tool documentation, whereas VQuant transmits its | |
| 47 | +entire 245-tool catalogue on every call and relies on schema descriptions and a routing prompt. | |
| 48 | +The second is context: tool results are verbose, and \citet{liu2024lost} show that models use | |
| 49 | +information in the middle of long contexts poorly even when it fits. Provider-level | |
| 50 | +function-calling protocols \citep{anthropic2026tooluse} and the Model Context Protocol | |
| 51 | +\citep{mcp2025spec} standardise how tools are declared and invoked but leave both problems to the | |
| 52 | +application. VQuant's prompt-level routing (Section~\ref{subsec:routing}) and three-stage | |
| 53 | +context management (Section~\ref{subsec:context}) are its answers; neither is claimed to be | |
| 54 | +optimal, and the evaluation protocol of Section~\ref{subsec:protocol} is designed to test them. | |
| 44 | 55 | |
| 45 | −Retrieval-augmented generation \citep{lewis2020retrieval} grounds model outputs in external | |
| 46 | −documents, mitigating hallucination and staleness. VQuant generalizes grounding beyond text | |
| 47 | −retrieval: its ``retrieval'' surface includes structured market-data endpoints, semantic and | |
| 48 | −keyword web search, and on-demand numerical computation. Every quantitative claim in a VQuant | |
| 49 | −report is traceable to a deterministic source, which we view as the financial-domain analogue | |
| 50 | −of citation-grounded generation. This emphasis on auditability connects to broader concerns | |
| 51 | −about reliability and provenance in machine learning for finance \citep{lopezdeprado2018advances}. | |
| 56 | +\subsection{Evaluating LLM agents} | |
| 57 | +\label{subsec:lit_eval} | |
| 52 | 58 | |
| 53 | −\subsection{Large language models in finance} | |
| 59 | +The agent literature has converged on benchmark suites with executable environments and | |
| 60 | +automatic scoring: AgentBench \citep{liu2024agentbench} spans eight environments, Reflexion | |
| 61 | +\citep{shinn2023reflexion} evaluates self-correction over repeated episodes, and WebGPT | |
| 62 | +\citep{nakano2021webgpt} pioneered human-preference evaluation of browser-assisted answers. For | |
| 63 | +open-ended outputs such as reports, model-based grading has become standard, with | |
| 64 | +\citet{zheng2023judge} documenting both its agreement with human raters and its biases. | |
| 65 | +\citet{chang2024survey} survey the resulting evaluation landscape. In finance specifically, | |
| 66 | +FinanceBench \citep{islam2023financebench} supplies questions over public filings with | |
| 67 | +human-verified answers and reports that unaided retrieval-augmented models answer a majority of | |
| 68 | +them incorrectly, and FinBen \citep{xie2024finben} assembles a multi-task financial benchmark that | |
| 69 | +includes agent and quantitative-reasoning tasks. These resources are the natural starting point | |
| 70 | +for an evaluation of VQuant; the protocol in Section~\ref{subsec:protocol} builds on them. | |
| 71 | + | |
| 72 | +\subsection{Large language models in finance and economics} | |
| 54 | 73 | \label{subsec:lit_finance} |
| 55 | 74 | |
| 56 | −Domain-adapted models such as BloombergGPT \citep{wu2023bloomberggpt} and open frameworks such | |
| 57 | −as FinGPT \citep{yang2023fingpt} demonstrated the value of finance-specific training data. | |
| 58 | −On the application side, \citet{lopezlira2023chatgpt} found that LLM-derived sentiment from | |
| 59 | −news headlines predicts subsequent returns, and \citet{kim2024financial} showed that LLMs can | |
| 60 | −analyze financial statements at a level competitive with human analysts. These studies largely | |
| 61 | −treat the LLM as a \emph{forecasting or classification} engine operating on text. VQuant takes | |
| 62 | −a different stance: it uses the LLM as an \emph{orchestrator} that assembles live data, | |
| 63 | −delegates numerical work to deterministic code, and composes the results into a report. The | |
| 64 | −classical quantitative methods it automates---option pricing \citep{black1973pricing, | |
| 65 | −merton1973theory}, conditional-volatility modeling \citep{engle1982autoregressive, | |
| 66 | −bollerslev1986generalized}, Monte Carlo valuation \citep{glasserman2004monte}, and | |
| 67 | −Value-at-Risk \citep{jorion2007value}---are well established; the contribution is the | |
| 68 | −\emph{architecture} that makes them accessible through natural language while preserving | |
| 69 | −reproducibility. | |
| 75 | +Text has long been a source of financial signals: \citet{loughran2016textual} survey | |
| 76 | +dictionary-based textual analysis, \citet{gentzkow2019text} review text-as-data methods for | |
| 77 | +economists, and \citet{li2021culture} show that embedding-based methods recover latent constructs | |
| 78 | +such as corporate culture from earnings calls. LLMs extend this line. \citet{lopezlira2026chatgpt} | |
| 79 | +find that ChatGPT-derived headline sentiment predicts subsequent returns; \citet{chen2023expected} | |
| 80 | +use LLM representations of news to forecast returns across sixteen markets; and | |
| 81 | +\citet{hansen2023fedspeak} show that GPT models classify the stance of FOMC communications more | |
| 82 | +accurately than dictionary and smaller supervised methods.\footnote{A widely circulated study of | |
| 83 | +LLM-based financial statement analysis \citep{kim2024financial} was withdrawn from arXiv by its | |
| 84 | +authors in February 2025 pending a review of data inconsistencies; we therefore do not rely on it.} | |
| 85 | +Domain-adapted models such as BloombergGPT \citep{wu2023bloomberggpt} and FinGPT | |
| 86 | +\citep{yang2023fingpt} demonstrate the value of finance-specific training data, and | |
| 87 | +\citet{li2023survey} survey the field. On the applied side, \citet{fatouros2025marketsenseai} | |
| 88 | +build an LLM-driven stock-selection framework from news, fundamentals, and prices and evaluate it | |
| 89 | +on realised performance, while \citet{korinek2023generative} and \citet{dell2025deep} assess | |
| 90 | +what generative and deep-learning methods offer to economic research. | |
| 91 | + | |
| 92 | +Most of this work treats the LLM as a \emph{forecasting or classification} engine operating on | |
| 93 | +text. VQuant takes a different stance: the model is an \emph{orchestrator} that assembles live | |
| 94 | +data, delegates numerical work to deterministic code, and composes the results into a document. | |
| 95 | +The classical methods it automates---option pricing \citep{black1973pricing,merton1973theory}, | |
| 96 | +conditional volatility \citep{engle1982autoregressive,bollerslev1986generalized}, Monte Carlo | |
| 97 | +valuation \citep{glasserman2004monte}, and Value-at-Risk \citep{jorion2007value}---are | |
| 98 | +established; the broader concern with reproducibility and provenance in financial machine | |
| 99 | +learning is articulated by \citet{lopezdeprado2018advances}. The point of contact with the | |
| 100 | +forecasting literature is the risk, documented there, that LLM outputs about numbers are | |
| 101 | +confidently wrong; VQuant's architecture is an attempt to remove numbers from the model's remit | |
| 102 | +altogether. | |
| 70 | 103 | |
| 71 | 104 | \subsection{Positioning} |
| 72 | 105 | \label{subsec:lit_positioning} |
| 73 | 106 | |
| 74 | −Relative to prior work, VQuant is distinctive in three respects. First, it integrates an | |
| 75 | −unusually broad and heterogeneous tool ecosystem under one protocol, and it contributes | |
| 76 | −concrete methodology for routing and rate-managing that ecosystem. Second, it enforces a strict | |
| 77 | −separation between reasoning (performed by the LLM) and computation (performed by deterministic | |
| 78 | −code), which we argue is the appropriate design for numerically sensitive domains. Third, it | |
| 79 | −treats the \emph{deliverable}---a citable, exportable, reproducible document---as a primary | |
| 80 | −artifact rather than an afterthought. The remainder of the paper develops each of these points. | |
| 107 | +Relative to this work, the artifact described here is distinctive in three respects, none of | |
| 108 | +which is an empirical claim. First, it exposes a broad and heterogeneous catalogue of tools under | |
| 109 | +one protocol and documents the practical mechanisms---routing, batching, truncation, | |
| 110 | +summarisation---needed to operate it. Second, it enforces a strict separation between reasoning | |
| 111 | +(performed by the model) and computation (performed by deterministic code), a separation that | |
| 112 | +\citet{gao2023pal} and \citet{chen2023pot} showed to be beneficial on benchmarks and that VQuant | |
| 113 | +carries into a production setting with live data. Third, it treats the deliverable---an | |
| 114 | +exportable, shareable document---as a primary artifact. What the paper does not establish is | |
| 115 | +whether these choices improve accuracy, latency, or cost relative to simpler designs; that is the | |
| 116 | +question Section~\ref{subsec:protocol} is written to answer. | |
modified
paper/sections/methodology.tex
+191 −144
@@ -1,56 +1,55 @@ | ||
| 1 | 1 | % ============================================================================ |
| 2 | −\section{Methodology: Orchestration Mechanisms} | |
| 2 | +\section{Orchestration Mechanisms} | |
| 3 | 3 | \label{sec:methodology} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | −This section is the technical core of the paper. We describe, mechanism by mechanism, how | |
| 7 | −VQuant drives a language model through a complete analysis: the streaming transport and its | |
| 8 | −event protocol, the recursive tool-calling loop, the batching policy, the context-management | |
| 9 | −machinery, and the token-accounting correction. Each mechanism is described as it is actually | |
| 10 | −implemented, so that the design can be reproduced. Throughout, the guiding principle is a strict | |
| 11 | −division of labor: the model \emph{plans and synthesizes}, while deterministic server code | |
| 12 | −\emph{transports, schedules, computes, and accounts}. | |
| 6 | +This section is the technical core of the paper. We describe, mechanism by mechanism, how VQuant | |
| 7 | +drives a language model through a complete analysis: the streaming transport and its event | |
| 8 | +protocol, the recursive tool-calling loop, the batching policy, the routing prompt, the | |
| 9 | +context-management procedure, the token-accounting correction, and the single-call computation | |
| 10 | +convention. Each mechanism is described as implemented at the audited commit, with its actual | |
| 11 | +constants, so that the design can be reproduced; Appendix~\ref{app:audit} gives the source | |
| 12 | +location of every statement. | |
| 13 | 13 | |
| 14 | −\subsection{The streaming transport and event protocol} | |
| 14 | +\subsection{Streaming transport and event protocol} | |
| 15 | 15 | \label{subsec:transport} |
| 16 | 16 | |
| 17 | −VQuant does not use a model-provider SDK. It opens a raw HTTP connection to the provider's | |
| 18 | −messages endpoint with a streaming response type, and parses the resulting Server-Sent Event | |
| 19 | −(SSE) byte stream itself. This choice gives the server full control over how partial output is | |
| 17 | +On the reference path VQuant does not use the provider's software development kit. It opens a | |
| 18 | +raw HTTP connection to the provider's messages endpoint with a streaming response and parses the | |
| 19 | +resulting SSE byte stream itself, which gives the server full control over how partial output is | |
| 20 | 20 | interpreted and re-emitted. |
| 21 | 21 | |
| 22 | 22 | The parser maintains a single growing string buffer. On each network chunk it appends the bytes, |
| 23 | −splits the buffer on newlines, and \emph{retains the final, possibly incomplete, line} in the | |
| 24 | −buffer for the next chunk---a detail that is essential for correctness, because SSE frames do not | |
| 25 | −align with TCP segment boundaries. Each complete line beginning with the \texttt{data:} prefix is | |
| 26 | −stripped and parsed as JSON into a typed event. The parser dispatches on the event's | |
| 27 | −\texttt{type} field; the eight relevant cases are summarized in Table~\ref{tab:events} and the | |
| 28 | −overall flow is shown in Figure~\ref{fig:streaming}. | |
| 23 | +splits the buffer on newlines, and \emph{retains the final, possibly incomplete, line} for the next | |
| 24 | +chunk---a detail that is essential for correctness because SSE frames do not align with TCP | |
| 25 | +segment boundaries. Each complete line beginning with the \texttt{data:} prefix is stripped and | |
| 26 | +parsed as JSON into a typed event, and the parser dispatches on the event's \texttt{type} field. | |
| 27 | +The eight relevant cases are summarised in Table~\ref{tab:events} and the flow is shown in | |
| 28 | +Figure~\ref{fig:streaming}. | |
| 29 | 29 | |
| 30 | 30 | \input{figures/streaming} |
| 31 | 31 | |
| 32 | 32 | \input{tables/events} |
| 33 | 33 | |
| 34 | −Three behaviors of this dispatcher deserve emphasis. First, the model's output travels on | |
| 35 | −\emph{two independent channels}: ordinary answer text arrives as \texttt{text\_delta} events and | |
| 36 | −is accumulated into the answer while being forwarded to the client, whereas the model's private | |
| 37 | −reasoning arrives as \texttt{thinking\_delta} events on a separate callback that the client | |
| 38 | −renders in a distinct panel. Second, a tool call is not delivered atomically: the tool's name | |
| 39 | −and identifier arrive in a \texttt{content\_block\_start}, but its arguments stream in as a | |
| 40 | −sequence of \texttt{input\_json\_delta} fragments that the parser concatenates into a partial | |
| 41 | −JSON string; only at \texttt{content\_block\_stop} is that string parsed into the structured | |
| 42 | −argument object. The loop must therefore wait for the block to close before a tool becomes | |
| 43 | −executable. Third, every forwarded event is flushed to the client immediately, so that the | |
| 44 | −user perceives output token by token rather than in batches. | |
| 34 | +Three behaviours of this dispatcher deserve emphasis. First, the model's output travels on two | |
| 35 | +independent channels: answer text arrives as \texttt{text\_delta} events and is accumulated into | |
| 36 | +the answer while being forwarded to the client, whereas the model's reasoning summary arrives as | |
| 37 | +\texttt{thinking\_delta} events on a separate callback that the client renders in a distinct | |
| 38 | +panel. Second, a tool call is not delivered atomically: the tool's name and identifier arrive in a | |
| 39 | +\texttt{content\_block\_start}, its arguments stream in as a sequence of | |
| 40 | +\texttt{input\_json\_delta} fragments that the parser concatenates into a partial JSON string, and | |
| 41 | +only at \texttt{content\_block\_stop} is that string parsed into the structured argument object. | |
| 42 | +The loop must therefore wait for the block to close before a tool becomes executable. Third, every | |
| 43 | +forwarded event is flushed to the client immediately, so the user perceives output as it is | |
| 44 | +generated rather than in batches. | |
| 45 | 45 | |
| 46 | 46 | \subsection{The recursive tool-calling loop} |
| 47 | 47 | \label{subsec:loop} |
| 48 | 48 | |
| 49 | −The agentic loop is implemented as \emph{recursion} rather than iteration. A single routine | |
| 50 | −issues one streaming model call, and when that call resolves it either terminates---if the model | |
| 51 | −requested no tools---or executes the requested tools, appends their results to the conversation, | |
| 52 | −and \emph{calls itself again}. Algorithm~\ref{alg:loop} states the procedure and | |
| 53 | −Figure~\ref{fig:loop} depicts it. | |
| 49 | +The agentic loop is implemented as recursion. A single routine issues one streaming model call; | |
| 50 | +when the call resolves it either terminates---if the model requested no tools---or executes the | |
| 51 | +requested tools, appends their results to the conversation, and calls itself again. | |
| 52 | +Algorithm~\ref{alg:loop} states the procedure and Figure~\ref{fig:loop} depicts it. | |
| 54 | 53 | |
| 55 | 54 | \input{figures/loop} |
| 56 | 55 | |
@@ -58,162 +57,207 @@ Figure~\ref{fig:loop} depicts it. | ||
| 58 | 57 | \caption{Recursive tool-calling loop (\textsc{ProcessResponse})} |
| 59 | 58 | \label{alg:loop} |
| 60 | 59 | \begin{algorithmic}[1] |
| 61 | −\Require message list $M$ (mutated in place), model $m$, tool catalogue $\mathcal{T}$ | |
| 62 | −\State $(\textit{text}, R, \textit{usage}) \gets \textsc{StreamModel}(m, M, \mathcal{T})$ | |
| 63 | − \Comment{Section~\ref{subsec:transport}} | |
| 64 | −\State accumulate \textit{usage}; stream \textit{text} and thinking to the client | |
| 60 | +\Require message list $M$ (mutated in place), model $m$, tool catalogue $\mathcal{T}$ ($|\mathcal{T}|=245$) | |
| 61 | +\State $M \gets \textsc{PrepareContext}(M, m)$ \Comment{Algorithm~\ref{alg:context}} | |
| 62 | +\State $(\textit{text}, R, \textit{usage}) \gets \textsc{StreamModel}(m, M, \mathcal{T})$ \Comment{Section~\ref{subsec:transport}} | |
| 63 | +\State accumulate \textit{usage}; stream \textit{text} and reasoning summary to the client | |
| 65 | 64 | \If{$R = \varnothing$} \Comment{no tool calls $\Rightarrow$ final answer} |
| 66 | 65 | \State \Return |
| 67 | 66 | \EndIf |
| 68 | −\State append $\langle\text{assistant}: \text{tool\_use blocks of } R\rangle$ to $M$ | |
| 67 | +\State append $\langle\text{assistant}: \text{tool\_use blocks of } R\rangle$ to $M$ \Comment{tool-use blocks only; no text or thinking blocks} | |
| 69 | 68 | \ForAll{batch $B$ in $\textsc{Chunk}(R, 5)$} \Comment{Section~\ref{subsec:batching}} |
| 69 | + \State emit a \texttt{status} event naming the tools in $B$ if more than one batch | |
| 70 | 70 | \ForAll{tool call $r \in B$} |
| 71 | 71 | \State $\textit{res} \gets \textsc{Execute}(r)$; stream a typed result event to the client |
| 72 | − \State collect $\textit{res}$ as a tool\_result block | |
| 72 | + \State $\textit{res} \gets \textsc{Truncate}(\textit{res}, c_1(r))$ \Comment{$c_1 = 3{,}000$ chars; $15{,}000$ for extraction and Python tools} | |
| 73 | + \State collect $\textit{res}$ as a tool\_result block keyed to $r$'s identifier | |
| 73 | 74 | \EndFor |
| 74 | − \State \textsc{Wait}(500\,\text{ms}) | |
| 75 | + \State \textsc{Wait}(500\,\text{ms}) if another batch follows | |
| 75 | 76 | \EndFor |
| 76 | 77 | \State append $\langle\text{user}: \text{all tool\_result blocks}\rangle$ to $M$ |
| 77 | 78 | \State \textsc{ProcessResponse}($M, m, \mathcal{T}$) \Comment{recurse with augmented context} |
| 78 | 79 | \end{algorithmic} |
| 79 | 80 | \end{algorithm} |
| 80 | 81 | |
| 81 | −The conversation is represented as a list of messages that is mutated as the loop proceeds. When | |
| 82 | −the model requests tools, the server first appends an \emph{assistant} message containing the | |
| 83 | −model's tool-use blocks, then---after execution---appends a \emph{user} message whose content is | |
| 84 | −the corresponding array of tool-result blocks, each keyed to its call identifier. This | |
| 85 | −strict pairing of tool-use and tool-result blocks is what the provider's protocol requires, and | |
| 86 | −maintaining it correctly across the recursion is the loop's central invariant. Recursion | |
| 87 | −terminates naturally when a model call returns no tool requests, at which point the accumulated | |
| 88 | −text is the report. Multimodal inputs are handled at the entry point: an uploaded image is | |
| 89 | −attached to the first user message as a base64 block alongside the text query. | |
| 82 | +The conversation is represented as a list of messages mutated as the loop proceeds. When the model | |
| 83 | +requests tools, the server first appends an \emph{assistant} message containing the model's | |
| 84 | +tool-use blocks, then---after execution---appends a \emph{user} message whose content is the array | |
| 85 | +of tool-result blocks, each keyed to its call identifier. This pairing of tool-use and tool-result | |
| 86 | +blocks is what the provider's protocol requires, and maintaining it across the recursion is the | |
| 87 | +loop's central invariant. Two consequences of the implementation should be noted. The assistant | |
| 88 | +message carries only the tool-use blocks: any answer text the model emitted in the same turn is | |
| 89 | +streamed to the user but not re-sent to the model, and reasoning blocks are not replayed, so the | |
| 90 | +model re-derives its plan from the tool results on the next turn rather than from its own prior | |
| 91 | +deliberation. And because the routine recurses without a depth bound, termination relies on the | |
| 92 | +model eventually returning no tool requests; the first version of this paper did not state this, | |
| 93 | +and a maximum recursion depth is a reasonable hardening (Section~\ref{subsec:threats}). Recursion | |
| 94 | +terminates when a call returns no tool requests, at which point the accumulated text is the | |
| 95 | +report. Multimodal input is handled at the entry point: an uploaded image is attached to the | |
| 96 | +first user message as a base64 block alongside the query. | |
| 90 | 97 | |
| 91 | 98 | \subsection{Batched tool execution} |
| 92 | 99 | \label{subsec:batching} |
| 93 | 100 | |
| 94 | −Within a single turn the model frequently requests many tools at once---a comprehensive report | |
| 95 | −may trigger a dozen or more. Executing all of them simultaneously would risk provider rate | |
| 96 | −limits and connection timeouts. VQuant therefore partitions the requested calls into | |
| 97 | −\emph{batches of at most five} and executes the batches \emph{sequentially}, inserting a | |
| 98 | −500-millisecond pause between consecutive batches. Results from all batches are accumulated and | |
| 99 | −returned to the model together in the single tool-result message of Algorithm~\ref{alg:loop}, so | |
| 100 | −that the model sees a complete result set on the next turn rather than a fragmented one. The | |
| 101 | −batch boundary thus serves purely as a rate-limiting throttle; it does not change what the model | |
| 102 | −observes. When more than one batch is required the server emits a progress event naming the | |
| 103 | −tools in flight, so the throttling is visible to the user rather than appearing as a stall. | |
| 101 | +Within a single turn the model frequently requests many tools at once; a comprehensive report may | |
| 102 | +trigger a dozen or more. Executing all of them simultaneously would risk provider rate limits and | |
| 103 | +connection timeouts. VQuant therefore partitions the requested calls into batches of at most | |
| 104 | +five, executes the batches sequentially, and inserts a 500-millisecond pause between consecutive | |
| 105 | +batches. Within a batch the calls are executed one after another, not concurrently; the batch is | |
| 106 | +a unit of pacing rather than of parallelism. Results from all batches are accumulated and returned | |
| 107 | +to the model together in the single tool-result message of Algorithm~\ref{alg:loop}, so the model | |
| 108 | +sees a complete result set on the next turn. This matters for a second reason: the provider's | |
| 109 | +guidance is that parallel tool calls answered across several user messages lead the model to stop | |
| 110 | +issuing them in parallel, so the single-message return preserves the model's tendency to batch its | |
| 111 | +own requests. When more than one batch is required the server emits a \texttt{status} event naming | |
| 112 | +the tools in flight, so the throttling is visible to the user rather than appearing as a stall. | |
| 104 | 113 | |
| 105 | 114 | \subsection{System-prompt routing} |
| 106 | 115 | \label{subsec:routing} |
| 107 | 116 | |
| 108 | −The behavior of the loop is shaped by a system prompt that is assembled fresh on every call. | |
| 109 | −Two parts are computed at request time: the current date and time (in both a human-readable and | |
| 110 | −an ISO form) are injected at the top so that relative date expressions resolve against live data | |
| 111 | −rather than the model's training cutoff; the remainder is a static policy block. That policy | |
| 112 | −instructs the model to detect and match the user's language; to act without procedural narration | |
| 113 | −and, in particular, to perform an entire custom analysis in a single execution | |
| 114 | −(Section~\ref{subsec:onecall}); to calibrate effort to request complexity---one or two tools for | |
| 115 | −a simple lookup, a handful for a moderate request, ten or more for a comprehensive report; and to | |
| 116 | −follow output-formatting conventions for downloadable artifacts. A final guardrail directs the | |
| 117 | −model to refuse attempts to extract the platform's own implementation. This prompt-level routing | |
| 118 | −is the mechanism by which a catalogue of more than two hundred tools (Table~\ref{tab:tools}) is | |
| 119 | −navigated without an explicit planner: the model is taught \emph{when not to call} tools as much | |
| 120 | −as when to call them. | |
| 117 | +The behaviour of the loop is shaped by a system prompt assembled on every call. Its first lines | |
| 118 | +inject the current date and time, in a human-readable and an ISO form, so that relative date | |
| 119 | +expressions resolve against live data rather than against the model's training cut-off; the | |
| 120 | +remainder is a static policy block whose structure is given in Appendix~\ref{app:prompt}. The | |
| 121 | +policy instructs the model to answer in the language of the request; to act without procedural | |
| 122 | +narration and, in particular, to perform an entire custom analysis in a single Python execution | |
| 123 | +(Section~\ref{subsec:onecall}); to calibrate effort to request complexity---one or two tools for a | |
| 124 | +simple lookup, three to five for a moderate request, ten or more for a comprehensive report; to | |
| 125 | +prefer the primary provider for United States equities and the second for international | |
| 126 | +instruments; and to follow output-formatting conventions for downloadable artifacts, including a | |
| 127 | +preference for live spreadsheet formulas over constants. A final block directs the model to | |
| 128 | +refuse, with a fixed bilingual notice, attempts to extract the platform's own implementation. | |
| 129 | + | |
| 130 | +This prompt-level routing is the mechanism by which the 245-tool catalogue | |
| 131 | +(Table~\ref{tab:tools}) is navigated without an explicit planner or a tool retriever of the kind | |
| 132 | +proposed by \citet{patil2024gorilla} and \citet{qin2024toolllm}: the model is taught \emph{when | |
| 133 | +not to call} tools as much as when to call them, and the per-tool schema descriptions carry the | |
| 134 | +rest. The prompt names only about sixty tools explicitly; the others are discoverable solely from | |
| 135 | +their schemas. Two of the tools the prompt does name---a Monte Carlo simulator and a | |
| 136 | +volatility-surface generator---are not in the catalogue at the audited commit | |
| 137 | +(Section~\ref{subsec:numerical}), an inconsistency between prompt and catalogue that the model | |
| 138 | +would experience as a tool that does not exist. | |
| 121 | 139 | |
| 122 | 140 | \input{tables/tools} |
| 123 | 141 | |
| 124 | 142 | \subsection{Adaptive reasoning} |
| 125 | 143 | \label{subsec:thinking} |
| 126 | 144 | |
| 127 | −For models that support it, the orchestration service enables \emph{adaptive extended thinking} | |
| 128 | −by attaching a thinking directive to the request and asking for a summarized display. A small | |
| 129 | −capability list determines which models receive this directive, so the same code path serves the | |
| 130 | −full model range. As noted in Section~\ref{subsec:transport}, the resulting reasoning summary | |
| 131 | −arrives on its own delta channel and is streamed to a dedicated client panel. Surfacing | |
| 132 | −reasoning makes the agent's plan legible to the user and provides an audit trail of how a report | |
| 133 | −was assembled, at no change to the loop itself. | |
| 145 | +For models that support it, the orchestration service enables adaptive extended thinking by | |
| 146 | +attaching a thinking directive to the request and asking for a summarised display. A short | |
| 147 | +capability list determines which models receive the directive, so that the same code path serves | |
| 148 | +the full model range. As noted in Section~\ref{subsec:transport}, the resulting reasoning summary | |
| 149 | +arrives on its own delta channel and is streamed to a dedicated client panel. Surfacing the | |
| 150 | +summary makes the agent's plan legible to the user and provides a partial audit trail of how a | |
| 151 | +report was assembled; it does not alter the loop, and nothing downstream parses or depends on the | |
| 152 | +summary's content. | |
| 134 | 153 | |
| 135 | 154 | \subsection{Context management under a token budget} |
| 136 | 155 | \label{subsec:context} |
| 137 | 156 | |
| 138 | 157 | A persistent challenge for conversational agents is the bounded context window: accumulated |
| 139 | −history---especially verbose tool results---eventually exceeds what the model can attend to. | |
| 140 | −VQuant addresses this with a two-stage mechanism applied before every model call. | |
| 141 | − | |
| 142 | −\paragraph{Result truncation.} First, the server walks every message and caps any individual | |
| 143 | −tool-result block at a fixed character budget (5{,}000 characters), appending a truncation | |
| 144 | −marker. Raw data payloads are frequently far larger than the analysis requires, and this step | |
| 145 | −removes that bloat before it is ever re-sent on a subsequent turn. | |
| 146 | − | |
| 147 | −\paragraph{Adaptive summarization.} Second, the server estimates the total token count of the | |
| 148 | −prepared messages. The estimate uses a deliberately cheap heuristic---approximately one token per | |
| 149 | −four characters, summed over text and tool-result blocks---because it is only a trigger, not an | |
| 150 | −accounting figure. If the estimate exceeds a conservative threshold (set at $10^{5}$ tokens, well | |
| 151 | −below the hard context limit to leave room for the response and new tool results), the server | |
| 152 | −retains the most recent five messages verbatim and replaces the older history with a | |
| 153 | −model-generated summary, reinserted as a single synthetic user message. Algorithm~\ref{alg:context} | |
| 154 | −states the procedure and Figure~\ref{fig:context} illustrates the transformation. | |
| 158 | +history---especially verbose tool results---eventually exceeds what the model can attend to, and | |
| 159 | +attention over long contexts degrades before the hard limit is reached \citep{liu2024lost}. | |
| 160 | +VQuant addresses this with a three-stage procedure. The first stage operates at execution time | |
| 161 | +inside Algorithm~\ref{alg:loop}; the other two are applied immediately before every model call | |
| 162 | +and are stated as Algorithm~\ref{alg:context}. | |
| 163 | + | |
| 164 | +\paragraph{Stage 1: per-result truncation at execution.} When a tool result is serialised for the | |
| 165 | +model, it is cut at 3{,}000 characters, or 15{,}000 characters for the fourteen web-extraction | |
| 166 | +tools and the Python tool, whose outputs carry extracted text or figure references that must not | |
| 167 | +be lost; a marker recording the original length is appended. The full result is retained for | |
| 168 | +session persistence and for the client. | |
| 169 | + | |
| 170 | +\paragraph{Stage 2: re-send cap.} Before each call the server walks every message and caps any | |
| 171 | +individual tool-result block at 5{,}000 characters. This second cap is reached only by results | |
| 172 | +that were admitted under the higher 15{,}000-character limit at Stage~1 and are now being re-sent | |
| 173 | +on a later turn; it removes bulk that the analysis no longer needs. | |
| 174 | + | |
| 175 | +\paragraph{Stage 3: adaptive summarisation.} The server then estimates the token count of the | |
| 176 | +prepared messages with a deliberately cheap heuristic---one token per four characters, summed over | |
| 177 | +text and tool-result blocks---because the estimate is a trigger, not an accounting figure. If it | |
| 178 | +exceeds a threshold of $10^{5}$ tokens, the server retains the most recent five messages verbatim | |
| 179 | +and replaces the older history with a model-generated summary, reinserted as a single synthetic | |
| 180 | +user message. The threshold was chosen as a conservative fraction of a 200{,}000-token window; the | |
| 181 | +reference models now offer windows five times larger, so the constant is tunable and its effect | |
| 182 | +is one of the ablations proposed in Section~\ref{subsec:protocol}. Figure~\ref{fig:context} | |
| 183 | +illustrates the transformation. | |
| 155 | 184 | |
| 156 | 185 | \input{figures/context} |
| 157 | 186 | |
| 158 | 187 | \begin{algorithm}[htbp] |
| 159 | −\caption{Context management via truncation and adaptive summarization} | |
| 188 | +\caption{Context preparation before each model call (\textsc{PrepareContext})} | |
| 160 | 189 | \label{alg:context} |
| 161 | 190 | \begin{algorithmic}[1] |
| 162 | −\Require message list $M$, model $m$, threshold $\tau = 10^{5}$, recency $k = 5$, cap $c = 5000$ chars | |
| 163 | −\State cap every tool-result block in $M$ at $c$ characters | |
| 164 | −\State $t \gets \textsc{EstimateTokens}(M)$ \Comment{cheap $\approx$ chars$/4$ heuristic} | |
| 165 | −\If{$t > \tau$} | |
| 191 | +\Require message list $M$, model $m$, threshold $\tau = 10^{5}$ tokens, recency $k = 5$, cap $c_2 = 5{,}000$ chars, summary input cap $c_3 = 10{,}000$ chars | |
| 192 | +\State cap every tool-result block in $M$ at $c_2$ characters \Comment{Stage 2} | |
| 193 | +\State $t \gets \textsc{EstimateTokens}(M)$ \Comment{$\lceil \text{chars}/4 \rceil$ over text and tool-result blocks} | |
| 194 | +\If{$t > \tau$} \Comment{Stage 3} | |
| 166 | 195 | \State $M_{\text{recent}} \gets$ last $k$ messages of $M$;\quad $M_{\text{old}} \gets$ the rest |
| 167 | 196 | \If{$M_{\text{old}} \neq \varnothing$} |
| 168 | − \State $T \gets \textsc{ExtractText}(M_{\text{old}})$ \Comment{drop tool-use blocks; keep last 10k chars} | |
| 169 | − \State $s \gets \textsc{Summarize}(T, m)$ \Comment{separate non-streaming call} | |
| 170 | − \State $M \gets [\,\langle\text{user: ``[summary]: ''}+s\rangle\,] \mathbin{\Vert} M_{\text{recent}}$ | |
| 197 | + \State $T \gets \textsc{ExtractText}(M_{\text{old}})$ \Comment{natural-language turns only; last $c_3$ characters} | |
| 198 | + \State $s \gets \textsc{Summarize}(T, m)$ \Comment{non-streaming call; 2{,}000-token cap; temperature 0.5} | |
| 199 | + \If{the call fails} $s \gets$ first 500 characters of $T$ \Comment{graceful degradation} | |
| 200 | + \EndIf | |
| 201 | + \State $M \gets [\,\langle\text{user: ``[Previous conversation summary]: ''}+s\rangle\,] \mathbin{\Vert} M_{\text{recent}}$ | |
| 171 | 202 | \EndIf |
| 172 | 203 | \EndIf |
| 173 | 204 | \State \Return $M$ |
| 174 | 205 | \end{algorithmic} |
| 175 | 206 | \end{algorithm} |
| 176 | 207 | |
| 177 | −The summary is produced by a dedicated, \emph{non-streaming} model call with its own system | |
| 178 | −prompt, a low temperature, and a tight output cap, instructed to preserve the analytically | |
| 179 | −relevant context---the instruments under discussion, prior conclusions, and user preferences. | |
| 180 | −Before summarizing, a helper extracts only the natural-language turns (discarding tool-use | |
| 181 | −blocks) and keeps at most the last ten thousand characters, bounding the cost of summarization | |
| 182 | −itself. Should the summarization call fail, the mechanism degrades gracefully to a truncated | |
| 183 | −literal excerpt rather than aborting the request. The net effect is that conversation length is, | |
| 184 | −for practical purposes, unbounded, at the cost of one additional model call whenever the | |
| 185 | −threshold is crossed. | |
| 208 | +The summary is produced by a dedicated non-streaming call to the same model with its own system | |
| 209 | +prompt, a temperature of 0.5, and a 2{,}000-token output cap, instructed to preserve the | |
| 210 | +analytically relevant context---instruments under discussion, prior conclusions, and user | |
| 211 | +preferences. Before summarising, a helper extracts only the natural-language turns (discarding | |
| 212 | +tool-use and tool-result blocks) and keeps at most the last 10{,}000 characters, bounding the cost | |
| 213 | +of summarisation itself. Should the call fail, the mechanism degrades to a literal excerpt rather | |
| 214 | +than aborting the request. The net effect is that conversation length is, for practical purposes, | |
| 215 | +unbounded, at the cost of one additional model call whenever the threshold is crossed and of | |
| 216 | +whatever the summary omits. The procedure is lossy by construction, and the paper makes no claim | |
| 217 | +about how much analytically relevant information survives it; that is a measurable quantity and | |
| 218 | +is included in the evaluation protocol. | |
| 186 | 219 | |
| 187 | 220 | \subsection{Token accounting and its correction} |
| 188 | 221 | \label{subsec:accounting} |
| 189 | 222 | |
| 190 | −Accurate token accounting matters both for the budget trigger above and for per-session cost | |
| 191 | −reporting, yet the streaming protocol does not reliably report output-token counts. VQuant | |
| 192 | −therefore applies a correction mechanism. Input tokens are read from the provider's | |
| 193 | −\texttt{message\_start} event; output tokens are taken from streaming usage updates \emph{but | |
| 194 | −reconciled} against a local count obtained by running the accumulated answer text through a | |
| 195 | −tokenizer at the end of the stream. The system records the \emph{maximum} of the provider's | |
| 196 | −figure and the local count, guaranteeing that cost is never understated, and falls back to the | |
| 197 | −provider's figure only if local encoding fails. Cost is then computed from a simple linear | |
| 198 | −schedule (a fixed price per million input tokens and a higher price per million output tokens) | |
| 199 | −and accumulated across all calls in a session, including the recursive tool-driven turns and any | |
| 200 | −summarization calls. This separation---a cheap heuristic for the budget trigger, an exact | |
| 201 | −tokenizer for billing---keeps the hot path inexpensive while keeping the ledger accurate. | |
| 202 | − | |
| 203 | −\subsection{The single-call computation paradigm} | |
| 223 | +Token accounting matters for per-session cost reporting, and the streaming protocol does not | |
| 224 | +always report final output-token counts reliably. VQuant therefore applies a correction. Input | |
| 225 | +tokens are read from the provider's \texttt{message\_start} event; output tokens are taken from | |
| 226 | +streaming usage updates but reconciled, at \texttt{message\_stop}, against a local count obtained | |
| 227 | +by running the accumulated answer text through a tokenizer. The system records the \emph{maximum} | |
| 228 | +of the provider's figure and the local count, so that cost is never understated, and falls back to | |
| 229 | +the provider's figure if local encoding fails. | |
| 230 | + | |
| 231 | +Two qualifications correct the first version of this paper. First, the local tokenizer is a | |
| 232 | +general-purpose byte-pair encoder for OpenAI models (the \texttt{gpt-tokenizer} package), not the | |
| 233 | +provider's tokenizer; its count is an approximation whose direction of error is not fixed, so the | |
| 234 | +``exact tokenizer for billing'' of the earlier description overstated what the mechanism | |
| 235 | +achieves. Second, the local count covers answer text only, not the reasoning tokens that the | |
| 236 | +provider bills, so the maximum rule guards against under-reporting of text but not of thinking. | |
| 237 | +Cost is then computed from a single linear schedule---\$3 per million input tokens and \$15 per | |
| 238 | +million output tokens---and accumulated across all calls in a session, including recursive turns | |
| 239 | +and summarisation calls. The schedule is the same for every selectable model, so the ledger | |
| 240 | +mis-states cost whenever a model with different list prices is selected; a per-model price table | |
| 241 | +is a straightforward correction. The separation of a cheap heuristic for the context trigger from a | |
| 242 | +tokenizer-based count for the ledger is sound; the earlier description's statement that the | |
| 243 | +tokenizer also drives the context trigger was incorrect. | |
| 244 | + | |
| 245 | +\subsection{The single-call computation convention} | |
| 204 | 246 | \label{subsec:onecall} |
| 205 | 247 | |
| 206 | −The final orchestration mechanism concerns \emph{how} numerical work is delegated. A naive agent | |
| 207 | −decomposes a quantitative task into a sequence of tool calls---fetch data, then in a separate | |
| 208 | −turn analyze it, then in a third turn plot it---each of which incurs a full recursion through | |
| 248 | +The final mechanism concerns \emph{how} numerical work is delegated. A naive agent decomposes a | |
| 249 | +quantitative task into a sequence of tool calls---fetch data, then in a separate turn analyse it, | |
| 250 | +then in a third turn plot it---each of which incurs a full recursion through | |
| 209 | 251 | Algorithm~\ref{alg:loop} and therefore a full model round trip. VQuant instead instructs the |
| 210 | −model, through the system prompt, to perform an entire analysis in a \emph{single} execution of | |
| 211 | −the Python tool: acquire data inside the sandbox, compute, and render all figures in one call | |
| 212 | −(Listing~\ref{lst:onecall}). | |
| 252 | +model, through the system prompt and the Python tool's own description, to perform an entire | |
| 253 | +analysis in a single execution of the Python tool: acquire data inside the sandbox, compute, and | |
| 254 | +render all figures in one call (Listing~\ref{lst:onecall}). | |
| 213 | 255 | |
| 214 | 256 | \begin{lstlisting}[language=Python,caption={Single-call execution: data acquisition, |
| 215 | −computation, and visualization are consolidated into one sandboxed run, collapsing what would | |
| 216 | −otherwise be three recursive model round trips into one.},label={lst:onecall}] | |
| 257 | +computation, and visualisation are consolidated into one sandboxed run, so that what would | |
| 258 | +otherwise be three recursive model round trips becomes one. The \texttt{fmp} client, | |
| 259 | +\texttt{pd}, \texttt{plt}, and \texttt{save\_excel} are injected by the sandbox | |
| 260 | +(Section~\ref{subsec:sandbox}).},label={lst:onecall}] | |
| 217 | 261 | # One tool call performs the whole analysis: |
| 218 | 262 | data = fmp.get_historical_prices("NVDA") # live fetch inside the sandbox |
| 219 | 263 | df = pd.DataFrame(data["historical"]).sort_values("date") |
@@ -228,12 +272,15 @@ plt.hist(df["ret"].dropna(), bins=50); plt.tight_layout() | ||
| 228 | 272 | save_excel(df, "nvda.xlsx") # spreadsheet export in the same run |
| 229 | 273 | \end{lstlisting} |
| 230 | 274 | |
| 231 | −Three rules, enforced through the prompt, make this paradigm effective. First, the model must | |
| 232 | −\emph{never} hard-code data arrays: inlining hundreds of values both bloats the generated tokens | |
| 233 | −(which must be streamed and accounted) and defeats reproducibility; data must be fetched | |
| 234 | −programmatically through the in-process client. Second, each visualization must be a separate | |
| 235 | −figure rather than a subplot grid, which yields cleanly captionable, individually referenceable | |
| 236 | −images. Third, all artifacts---figures and spreadsheets---are produced within the same execution. | |
| 237 | −By collapsing the recursion depth for an analytical task from three or more to one, this paradigm | |
| 238 | −removes the dominant source of latency in the loop. The substrate that executes this code is the | |
| 239 | −subject of the next section. | |
| 275 | +Three rules, enforced through the prompt, make the convention effective. First, the model must not | |
| 276 | +hard-code data arrays: inlining hundreds of values bloats the generated tokens, which must be | |
| 277 | +streamed and paid for, and defeats reproducibility, since the provenance of the numbers is lost; | |
| 278 | +data must be fetched programmatically through the injected client. Second, each visualisation | |
| 279 | +must be a separate figure rather than a subplot grid, which yields individually captionable | |
| 280 | +images under the capture sweep of Section~\ref{subsec:sandbox}. Third, all artifacts---figures | |
| 281 | +and spreadsheets---are produced within the same execution. The convention reduces the recursion | |
| 282 | +depth for an analytical task from three or more to one. We call it a convention rather than a | |
| 283 | +mechanism because it is enforced by instruction, not by code: the model can disobey it, and the | |
| 284 | +rate at which it does so is one of the quantities the evaluation protocol is designed to measure. | |
| 285 | +Its cost is a loss of granularity---a single failed execution forfeits the whole analysis, whereas | |
| 286 | +a decomposed agent can recover at a finer level---which Section~\ref{subsec:threats} discusses. | |
modified
paper/sections/results.tex
+134 −80
@@ -1,71 +1,84 @@ | ||
| 1 | 1 | % ============================================================================ |
| 2 | −\section{Execution Substrate and Document Generation} | |
| 2 | +\section{Execution Substrate, Document Generation, and an Illustrative Walk-Through} | |
| 3 | 3 | \label{sec:capabilities} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | 6 | Having described how the agent is orchestrated, we now detail the two subsystems that turn its |
| 7 | −plans into artifacts: the sandboxed Python substrate that executes arbitrary model-authored code, | |
| 8 | −and the pipeline that renders the resulting report into multiple document formats. Both are | |
| 9 | −described at the mechanism level. | |
| 7 | +plans into artifacts---the sandboxed Python substrate that executes model-authored code and the | |
| 8 | +pipeline that renders the resulting report into several document formats---and then walk through | |
| 9 | +one request end to end. The walk-through is a \emph{demonstration} in the design-science sense | |
| 10 | +\citep{peffers2007design}: it shows that the mechanisms compose, and it reports no measurements. | |
| 10 | 11 | |
| 11 | 12 | \subsection{The Python execution sandbox} |
| 12 | 13 | \label{subsec:sandbox} |
| 13 | 14 | |
| 14 | −When the model invokes the custom-analysis tool, the server does not evaluate the code in | |
| 15 | −process. It spawns a separate Python interpreter (resolved to a project virtual environment) as | |
| 16 | −a child process and communicates with it over standard streams, an isolation boundary that | |
| 17 | −protects the server from faults in the executed code and bounds its blast radius | |
| 18 | −(Figure~\ref{fig:sandbox}). | |
| 15 | +When the model invokes the custom-analysis tool, the server does not evaluate the code in process. | |
| 16 | +It spawns a separate Python interpreter---the project's virtual environment if present, otherwise | |
| 17 | +the system interpreter---as a child process and communicates with it over standard streams. The | |
| 18 | +process boundary protects the server from faults in the executed code and bounds their effect | |
| 19 | +(Figure~\ref{fig:sandbox}); it is isolation by process, not by container, and | |
| 20 | +Section~\ref{subsec:threats} returns to what that does and does not guarantee. | |
| 19 | 21 | |
| 20 | 22 | \input{figures/sandbox} |
| 21 | 23 | |
| 22 | −\paragraph{Inter-process protocol.} The server serializes a single JSON object---the | |
| 24 | +\paragraph{Inter-process protocol.} The server serialises a single JSON object---the | |
| 23 | 25 | model-authored code, an optional context dictionary, and the market-data credential---and writes |
| 24 | 26 | it to the child's standard input, then closes the stream. The child reads the entire input, |
| 25 | −executes, and writes exactly one JSON object to standard output: a success flag, captured | |
| 26 | −textual output, a list of base64-encoded figures, a list of generated files, and any error. The | |
| 27 | −child is launched with output buffering disabled so that nothing is lost, and with a hard | |
| 28 | −90-second wall-clock timeout. The parent collects standard output and standard error separately; | |
| 29 | −a non-zero exit code, or error output with no standard output, is treated as failure and the | |
| 30 | −error is surfaced to the model so that it can revise its code on the next turn. This single | |
| 31 | −request / single response discipline keeps the boundary simple and makes failures explicit. | |
| 27 | +executes, and writes exactly one JSON object to standard output: a success flag, captured textual | |
| 28 | +output, a list of base64-encoded figures, a list of generated files, and any error. The child is | |
| 29 | +launched with output buffering disabled and a hard 90-second wall-clock timeout. The parent | |
| 30 | +collects standard output and standard error separately; a non-zero exit code, or error output with | |
| 31 | +no standard output, is treated as failure, and the error text is returned to the model as the tool | |
| 32 | +result so that it can revise its code on the next turn. This single-request, single-response | |
| 33 | +discipline keeps the boundary simple and makes failures explicit. | |
| 32 | 34 | |
| 33 | 35 | \paragraph{Namespace construction.} Inside the child, execution is performed by building an |
| 34 | −\emph{execution namespace}---a dictionary---and calling the interpreter's \texttt{exec} against | |
| 35 | −it. Into this namespace the runtime injects the scientific libraries (NumPy, pandas, matplotlib, | |
| 36 | −and the broader set of seventeen), the two artifact helpers (\texttt{save\_excel}, | |
| 37 | −\texttt{save\_word}), and a market-data client constructed from the supplied credential; any | |
| 38 | −context variables passed by the model are merged in last, so that the model can parameterize a | |
| 39 | −reusable script without string interpolation. Matplotlib is configured for a non-interactive | |
| 40 | −backend before any plotting occurs, so that figure rendering requires no display. As a | |
| 41 | −convenience, if the executed code defines a callable named \texttt{main}, the runtime invokes it | |
| 42 | −after execution and captures its return value. | |
| 43 | − | |
| 44 | −\paragraph{Output and figure capture.} Standard output and standard error produced by the code | |
| 45 | −are redirected into in-memory string buffers for the duration of execution, so that the model's | |
| 46 | −\texttt{print} statements become the textual result rather than corrupting the JSON protocol. | |
| 47 | −Figures are captured \emph{after} execution by a deterministic sweep: the runtime enumerates all | |
| 48 | −live matplotlib figure numbers, and for each, renders the figure to an in-memory buffer as a | |
| 49 | −PNG at fixed resolution with tight bounding boxes, then base64-encodes the bytes. This is exactly | |
| 50 | −why the single-call paradigm of Section~\ref{subsec:onecall} asks the model to emit each chart as | |
| 51 | −a \emph{separate} figure: the capture sweep turns each one into an individually addressable image | |
| 52 | −that the report can caption and reference. The encoded figures travel back through the JSON | |
| 53 | −response, are written to a served directory by the server, and are streamed to the client as | |
| 54 | −figure events. | |
| 55 | − | |
| 56 | −\subsection{Embedded numerical tools} | |
| 36 | +execution namespace---a dictionary---and calling the interpreter's \texttt{exec} against it. The | |
| 37 | +runtime attempts to import, and injects when available, 29 packages: the core scientific stack | |
| 38 | +(NumPy, pandas, SciPy, Matplotlib, seaborn, Plotly), statistics and econometrics (statsmodels, | |
| 39 | +\texttt{arch}, pmdarima, Prophet, hmmlearn), machine learning (scikit-learn, XGBoost, LightGBM), | |
| 40 | +optimisation and portfolio construction (CVXPY, PyPortfolioOpt, Riskfolio-Lib), market and | |
| 41 | +technical-analysis utilities (yfinance, \texttt{ta}, mplfinance, vectorbt), data engines (DuckDB, | |
| 42 | +Polars), and symbolic and graph libraries (SymPy, NetworkX, Numba), together with the | |
| 43 | +spreadsheet and word-processing writers. Each import is wrapped so that a missing package degrades | |
| 44 | +to an absent name rather than a failed execution; the platform's own documentation advertises | |
| 45 | +``17 libraries'', which undercounts what the executor attempts to load. The runtime also injects | |
| 46 | +two artifact helpers (\texttt{save\_excel}, \texttt{save\_word}) and a market-data client | |
| 47 | +constructed from the supplied credential; any context variables passed by the model are merged | |
| 48 | +in last, so that the model can parameterise a reusable script without string interpolation. | |
| 49 | +Matplotlib is configured for a non-interactive backend before any plotting occurs. If the executed | |
| 50 | +code defines a callable named \texttt{main}, the runtime invokes it after execution and captures | |
| 51 | +its return value. | |
| 52 | + | |
| 53 | +\paragraph{Output and figure capture.} Standard output and standard error produced by the code are | |
| 54 | +redirected into in-memory buffers for the duration of execution, so that \texttt{print} statements | |
| 55 | +become the textual result rather than corrupting the JSON protocol. Figures are captured after | |
| 56 | +execution by a deterministic sweep: the runtime enumerates all live Matplotlib figure numbers and, | |
| 57 | +for each, renders the figure to an in-memory PNG at 150 dots per inch with a tight bounding box | |
| 58 | +and base64-encodes the bytes. This is why the single-call convention asks the model to emit each | |
| 59 | +chart as a separate figure: the sweep turns each one into an individually addressable image. The | |
| 60 | +encoded figures travel back through the JSON response, are written to a served directory, and are | |
| 61 | +streamed to the client as figure events. Files written by the artifact helpers are returned as | |
| 62 | +download links in the same way. | |
| 63 | + | |
| 64 | +\subsection{Pre-built numerical routines} | |
| 57 | 65 | \label{subsec:numerical} |
| 58 | 66 | |
| 59 | −Alongside the open-ended sandbox, the platform exposes a small set of pre-built numerical tools | |
| 60 | −for common tasks, so that routine requests need not regenerate code: a Monte Carlo path simulator | |
| 61 | −under a standard log-normal price model, a closed-form European option pricer that returns prices | |
| 62 | −together with the full set of risk sensitivities, a GARCH(1,1) conditional-volatility estimator, | |
| 63 | −and a Value-at-Risk calculator offering historical, parametric, and simulation-based variants | |
| 64 | −with companion risk ratios. These tools are conventional in quantitative finance and we do not | |
| 65 | −elaborate their formulae here; what matters for the architecture is that they share the sandbox's | |
| 66 | −contract---deterministic computation over live data, returning structured results and figures | |
| 67 | −through the same channels---so the model can mix them freely with custom code inside a single | |
| 68 | −analysis. Their detailed inputs and outputs are summarized in Appendix~\ref{app:numerical}. | |
| 67 | +Alongside the open-ended sandbox, the server contains Python implementations of several routine | |
| 68 | +computations---a Monte Carlo path simulator under geometric Brownian motion, a Black--Scholes | |
| 69 | +pricer returning prices and Greeks, a GARCH(1,1) estimator, historical, parametric, and simulated | |
| 70 | +Value-at-Risk with expected shortfall and companion ratios, a mean--variance portfolio optimiser, | |
| 71 | +a risk-metrics module, a plotting module, and a volatility-surface renderer---each exposed through | |
| 72 | +the same child-process contract as the sandbox. Their closed forms are recorded in | |
| 73 | +Appendix~\ref{app:numerical}. At the audited commit, however, only the option pricer is declared | |
| 74 | +in the tool catalogue; the handlers for the Monte Carlo, GARCH, VaR, portfolio-optimisation, | |
| 75 | +risk-metrics, and plotting routines exist in the route module but have no corresponding tool | |
| 76 | +definition, so the model cannot invoke them, even though the system prompt still describes the | |
| 77 | +Monte Carlo and volatility-surface tools. The practical consequence is that, at this commit, such | |
| 78 | +analyses are performed through the custom-Python path of Listing~\ref{lst:onecall}, with the | |
| 79 | +model writing the code, rather than through a fixed implementation. The first version of this | |
| 80 | +paper presented the four routines as model-callable tools; we correct that here and note that | |
| 81 | +restoring the definitions is a small change. | |
| 69 | 82 | |
| 70 | 83 | \subsection{The document-generation pipeline} |
| 71 | 84 | \label{subsec:docs} |
@@ -76,37 +89,78 @@ output formats, each through a distinct mechanism (Figure~\ref{fig:docpipeline}) | ||
| 76 | 89 | |
| 77 | 90 | \input{figures/docpipeline} |
| 78 | 91 | |
| 79 | −\paragraph{PDF via headless rendering.} The challenge in rendering Markdown that contains | |
| 80 | −mathematics is that a Markdown parser will mangle mathematical syntax. The pipeline solves this | |
| 81 | −with a \emph{protect--parse--restore} mechanism: before parsing, every block- and inline-math | |
| 82 | −span is extracted and replaced by a unique placeholder token; the now math-free Markdown is | |
| 83 | −parsed to HTML; the placeholders are then restored as spans destined for a client-side math | |
| 84 | −renderer. The assembled HTML is loaded into a headless browser, which executes the math renderer; | |
| 85 | −the server explicitly \emph{waits for the rendered output to appear} in the DOM before capturing | |
| 86 | −the page to PDF with page furniture (headers, footers, pagination). Rendering in a real browser | |
| 87 | −engine is what lets complex notation and styled tables reproduce faithfully. | |
| 88 | − | |
| 89 | −\paragraph{Slides via model restructuring and two-pass \LaTeX.} Presentation output is a | |
| 90 | −two-phase mechanism. First, the platform issues a \emph{second} model call whose sole task is to | |
| 91 | −restructure the report into slide content---one idea per slide, special characters escaped, key | |
| 92 | −quantities emphasized---returning only body \LaTeX{}, not a full document. The server then wraps | |
| 93 | −that body in a fixed, branded Beamer preamble and compiles it with two sequential passes of the | |
| 94 | −\LaTeX{} engine, the second pass being required for cross-references and the table of contents to | |
| 95 | −resolve. When the analysis produced figures, the server additionally synthesizes one slide per | |
| 96 | −figure, integrating the visual output into the deck without further model involvement. | |
| 92 | +\paragraph{PDF via headless rendering.} Rendering Markdown that contains mathematics is delicate | |
| 93 | +because a Markdown parser will mangle mathematical syntax. The pipeline solves this with a | |
| 94 | +protect--parse--restore step: before parsing, every display and inline mathematics span is | |
| 95 | +extracted and replaced by a unique placeholder; the now mathematics-free Markdown is parsed to | |
| 96 | +HTML (with \texttt{marked}); the placeholders are then restored as spans destined for a client-side | |
| 97 | +renderer (KaTeX). The assembled HTML is loaded into a headless Chromium instance (Puppeteer), which | |
| 98 | +executes the renderer; the server waits until rendered output appears in the document before | |
| 99 | +printing the page to PDF with headers, footers, and pagination. Rendering in a real browser engine | |
| 100 | +is what lets complex notation and styled tables reproduce faithfully; it also makes PDF generation | |
| 101 | +depend on a content-delivery network for the renderer's assets, a deployment constraint noted in | |
| 102 | +Section~\ref{subsec:threats}. | |
| 103 | + | |
| 104 | +\paragraph{Slides via model restructuring and two-pass \LaTeX.} Presentation output is a two-phase | |
| 105 | +mechanism. First, the platform issues a second model call---pinned to \texttt{claude-opus-4-8} | |
| 106 | +irrespective of the model that produced the report---whose sole task is to restructure the report | |
| 107 | +into slide content, one idea per slide, with special characters escaped and key quantities | |
| 108 | +emphasised, returning only body \LaTeX. The server wraps that body in a fixed Beamer preamble and | |
| 109 | +compiles it with two sequential passes of \texttt{pdflatex}, the second being required for | |
| 110 | +cross-references and the table of contents to resolve; a non-zero exit code is tolerated when a | |
| 111 | +PDF was nonetheless produced, since \LaTeX{} returns one on warnings. When the analysis produced | |
| 112 | +figures, the server synthesises one slide per figure without further model involvement. | |
| 97 | 113 | |
| 98 | 114 | \paragraph{Word via document conversion.} For an editable office format, the same Markdown is |
| 99 | −handed to a document converter that emits a word-processor file, preserving tables, lists, and | |
| 100 | −heading structure. | |
| 115 | +written to a temporary file and converted with Pandoc, which preserves tables, lists, and heading | |
| 116 | +structure. | |
| 101 | 117 | |
| 102 | 118 | \paragraph{Spreadsheets with live formulas.} Within the sandbox, the spreadsheet helper writes |
| 103 | −multi-sheet workbooks containing \emph{live} formulas---sums, ratios, conditional formats, data | |
| 104 | −bars---rather than pre-computed constants, so the recipient can audit and modify the calculations. | |
| 105 | −This mirrors, at the spreadsheet level, the platform's broader commitment to auditable output: | |
| 106 | −the deliverable carries its own derivation. | |
| 107 | − | |
| 108 | −\paragraph{Sharing and persistence.} Finally, any report can be published to a stable, unique URL; | |
| 109 | −the server stores the report content and its figure references and serves them through a public | |
| 110 | −viewer, so an analysis can be revisited or cited without re-running the computation. Sessions, | |
| 111 | −token ledgers, and cost estimates are persisted per user, supporting both continuity and the | |
| 112 | −operational analytics discussed next. | |
| 119 | +multi-sheet workbooks that contain live formulas---column sums, averages, extrema, and counts, | |
| 120 | +together with optional per-column formulas supplied by the model---and conditional formats, rather | |
| 121 | +than pre-computed constants, so that the recipient can audit and modify the calculations. This | |
| 122 | +mirrors, at the spreadsheet level, the platform's commitment to auditable output: the deliverable | |
| 123 | +carries its own derivation. | |
| 124 | + | |
| 125 | +\paragraph{Sharing and persistence.} Any report can be published to a stable URL under an | |
| 126 | +eight-character identifier; the server stores the report content and its figure references and | |
| 127 | +serves them through a public viewer, so an analysis can be revisited or cited without re-running | |
| 128 | +the computation. Figure files themselves live on the server's disk and are lost on redeployment, a | |
| 129 | +limitation the code acknowledges. Sessions, token ledgers, and cost estimates are persisted per | |
| 130 | +user. | |
| 131 | + | |
| 132 | +\subsection{An illustrative walk-through} | |
| 133 | +\label{subsec:walkthrough} | |
| 134 | + | |
| 135 | +To show how the mechanisms compose, we trace the request ``analyse NVDA's fundamentals, | |
| 136 | +technicals, and run a Monte Carlo simulation'' through the system as implemented. No numbers are | |
| 137 | +reported, because none were measured; the trace describes control flow. | |
| 138 | + | |
| 139 | +The route handler appends the query to an empty message list and calls | |
| 140 | +\textsc{ProcessResponse}. \textsc{PrepareContext} finds nothing to truncate or summarise. The | |
| 141 | +streaming call opens with the date-stamped system prompt, the 245 tool schemas, and the single | |
| 142 | +user message; the model's reasoning summary begins to arrive on the thinking channel and is | |
| 143 | +rendered in the collapsible panel. Under the routing policy the request is ``comprehensive'', so | |
| 144 | +the model requests on the order of ten tools in one turn---profile, income statement, balance | |
| 145 | +sheet, cash flow, key metrics, quote, historical prices, RSI, MACD, peers, news---plus one call to | |
| 146 | +the custom-Python tool whose code fetches the price history inside the sandbox, simulates | |
| 147 | +geometric-Brownian paths, and emits a fan chart and a terminal-value histogram as separate | |
| 148 | +figures. The server emits a \texttt{tools} event listing the requests, then executes them in three | |
| 149 | +batches of at most five with 500-millisecond pauses, emitting \texttt{tool\_start}, | |
| 150 | +\texttt{tool\_complete}, and per-batch \texttt{status} events. The Python call spawns the child | |
| 151 | +process, which returns captured output and two base64 figures; the server writes the images to the | |
| 152 | +served directory, emits \texttt{python\_code} and \texttt{custom\_python\_figures} events, and | |
| 153 | +returns the textual output---capped at 15{,}000 characters---as the tool result. All other results | |
| 154 | +are capped at 3{,}000 characters. The assistant message with the tool-use blocks and the user | |
| 155 | +message with the tool-result blocks are appended, and the routine recurses. | |
| 156 | + | |
| 157 | +On the second call the model has every result in context and, in the typical case, requests no | |
| 158 | +further tools: it streams the report section by section, following the template in | |
| 159 | +Appendix~\ref{app:prompt}, with Markdown tables for the financial statements and image references | |
| 160 | +for the two figures. The accumulated text, figures, token totals, and cost are persisted with the | |
| 161 | +session and a \texttt{done} event closes the stream. From the rendered report the user may request | |
| 162 | +a PDF (headless rendering), a DOCX (Pandoc), a Beamer deck (a second model call, pinned to Opus | |
| 163 | +4.8, then two \texttt{pdflatex} passes, with one synthesised slide per figure), or a share link. | |
| 164 | +Had the model instead decomposed the analysis---fetching prices in one turn and simulating in | |
| 165 | +another---the trace would contain one additional recursion, which is the round trip the | |
| 166 | +single-call convention is designed to remove. | |
modified
paper/sections/robustness.tex
+152 −74
@@ -1,87 +1,165 @@ | ||
| 1 | 1 | % ============================================================================ |
| 2 | −\section{Performance, Reliability, and Security} | |
| 2 | +\section{Design Rationale, Threats to Validity, and a Proposed Evaluation} | |
| 3 | 3 | \label{sec:evaluation} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | −This section discusses the engineering properties that make VQuant usable in production: | |
| 7 | −its performance characteristics, cost discipline, reliability and security measures, and the | |
| 8 | −limitations that bound the contribution. We frame these as the practical counterparts to the | |
| 9 | −methodology of Section~\ref{sec:methodology}. | |
| 10 | − | |
| 11 | −\subsection{Performance and the streaming experience} | |
| 12 | −\label{subsec:performance} | |
| 13 | − | |
| 14 | −The dominant cost in an agentic system is not raw computation but \emph{round trips}: every | |
| 15 | −model invocation and every external request adds latency. VQuant's design attacks this on three | |
| 16 | −fronts (Table~\ref{tab:robustness}). The single-call paradigm of Section~\ref{subsec:onecall} | |
| 17 | −collapses what would be three or more model round trips---fetch, analyze, plot---into one, | |
| 18 | −which is the platform's largest latency saving for analytically intensive queries. Execution | |
| 19 | −batching overlaps independent tool calls within a turn while bounding instantaneous provider | |
| 20 | −load. And end-to-end streaming decouples \emph{perceived} latency from \emph{total} latency: the | |
| 21 | −user sees reasoning, text, tool progress, and figures appear incrementally, so a report that | |
| 22 | −takes tens of seconds to complete begins responding within a second. This last property is why | |
| 23 | −the streaming architecture of Section~\ref{subsec:frontend} is a performance feature and not | |
| 24 | −merely a cosmetic one. | |
| 6 | +This section replaces what the first version of this paper called ``Performance, Reliability, | |
| 7 | +and Security''. It states the rationale for each design decision as a hypothesis about the | |
| 8 | +property the decision is meant to secure and the measurement that would test it | |
| 9 | +(Table~\ref{tab:rationale}); it enumerates threats to the validity of the design and of this | |
| 10 | +description; it records what is and is not fixed for reproducibility; and it specifies the | |
| 11 | +evaluation that has not yet been executed. | |
| 25 | 12 | |
| 26 | −\input{tables/robustness} | |
| 13 | +\subsection{Design rationale} | |
| 14 | +\label{subsec:rationale} | |
| 27 | 15 | |
| 28 | −\subsection{Cost discipline} | |
| 29 | −\label{subsec:cost} | |
| 16 | +The dominant cost in an agentic system is not raw computation but round trips: every model | |
| 17 | +invocation and every external request adds latency and, for model calls, tokens. Three decisions | |
| 18 | +address this. The single-call convention (Section~\ref{subsec:onecall}) is intended to collapse | |
| 19 | +the fetch--analyse--plot sequence into one recursion level; batching | |
| 20 | +(Section~\ref{subsec:batching}) bounds instantaneous provider load without changing what the | |
| 21 | +model observes; and end-to-end streaming decouples perceived from total latency, so that the user | |
| 22 | +sees reasoning, text, and progress while the report is still being assembled. Three further | |
| 23 | +decisions address correctness and auditability: the process-isolated sandbox, the rule that data | |
| 24 | +are fetched programmatically rather than inlined, and the live-formula spreadsheets. Two address | |
| 25 | +scale: the three-stage context procedure and the tokenizer-based ledger. Table~\ref{tab:rationale} | |
| 26 | +lists each with the property it targets and the measurement that would confirm it. None of these | |
| 27 | +measurements has been made; the table is a statement of intent, and the first version's | |
| 28 | +``indicative'' latency figures, which had no measurement behind them, have been removed. | |
| 30 | 29 | |
| 31 | −Because model usage is metered by token, cost control is a first-order concern. VQuant estimates | |
| 32 | −token counts locally with a tokenizer before each call, which both drives the | |
| 33 | −context-management trigger of Algorithm~\ref{alg:context} and yields accurate per-session | |
| 34 | −accounting. The adaptive-summarization mechanism directly limits cost growth in long sessions by | |
| 35 | −preventing the unbounded accumulation of history, and truncating oversized tool results removes | |
| 36 | −payload bloat that would otherwise be re-sent on every turn. The user-facing model selector | |
| 37 | −(Table~\ref{tab:models}) lets users match model capability to query difficulty, routing simple | |
| 38 | −lookups to a fast, inexpensive tier and reserving the flagship model for the hardest analyses. | |
| 30 | +\input{tables/robustness} | |
| 39 | 31 | |
| 40 | −\subsection{Authentication, limits, and bring-your-own-keys} | |
| 32 | +\subsection{Authentication, usage limits, and observability} | |
| 41 | 33 | \label{subsec:auth} |
| 42 | 34 | |
| 43 | −VQuant supports both local accounts and third-party single sign-on, with sessions persisted in | |
| 44 | −the same store used in either deployment environment. Usage is governed by daily limits that | |
| 45 | −differ for anonymous and authenticated users, enforced through per-user counters in the data | |
| 46 | −layer. A notable feature is \emph{bring-your-own-keys}: a user may supply personal API | |
| 47 | −credentials for the model provider, the market-data provider, and the web-research services; | |
| 48 | −when present, these are used in place of the platform defaults and exempt the user from the | |
| 49 | −daily cap. This design cleanly separates the platform's orchestration value from the cost of the | |
| 50 | −underlying APIs, and it lets power users operate at their own expense and rate limits. | |
| 35 | +At the audited commit the platform supports local accounts with e-mail and password, e-mail | |
| 36 | +verification by one-time code, trusted devices that skip the code on subsequent logins, rate | |
| 37 | +limiting of authentication attempts per account and per connection, and a security event log. | |
| 38 | +Anonymous use is permitted and, for anonymous users only, each completed analysis is | |
| 39 | +automatically published as a shared report so that it remains retrievable. The platform records | |
| 40 | +request logs and aggregated analytics (request counts, failures, active and unique users, response | |
| 41 | +times) for operators. Three features described in the first version of this paper do not exist in | |
| 42 | +any committed version of the code: third-party single sign-on, daily usage caps that differ for | |
| 43 | +anonymous and authenticated users, and the ``bring-your-own-keys'' mechanism by which users | |
| 44 | +would supply personal provider credentials. They may have been planned or deployed through | |
| 45 | +configuration outside the repository, but they are not implemented in it, and we withdraw the | |
| 46 | +corresponding claims. | |
| 51 | 47 | |
| 52 | −\subsection{Reliability and security} | |
| 48 | +\subsection{Security measures} | |
| 53 | 49 | \label{subsec:security} |
| 54 | 50 | |
| 55 | −Several measures harden the system. All request bodies are validated against schemas at the | |
| 56 | −boundary, so malformed or untyped input is rejected uniformly before reaching business logic. | |
| 57 | −Database access is mediated by an object-relational mapper that parameterizes queries, | |
| 58 | −mitigating injection. The front end escapes rendered content and parses Markdown through a safe | |
| 59 | −pipeline, limiting cross-site scripting. Secrets are injected at runtime rather than committed, | |
| 60 | −and the bring-your-own-keys path keeps user credentials out of shared configuration. At the | |
| 61 | −model layer, the system prompt includes a guardrail that responds to attempts to extract the | |
| 62 | −platform's own implementation with a refusal rather than disclosure, providing a measure of | |
| 63 | −protection for the orchestration logic itself. Finally, the platform records analytics | |
| 64 | −events---active users, query rates, tool-usage frequency, model selection, and | |
| 65 | −document-generation breakdowns---giving operators the observability needed to detect anomalies | |
| 66 | −and capacity-plan. | |
| 67 | − | |
| 68 | −\subsection{Limitations and threats to validity} | |
| 69 | −\label{subsec:limitations} | |
| 70 | − | |
| 71 | −We close with an honest accounting of what this paper does and does not establish. First, the | |
| 72 | −contribution is \emph{architectural and methodological}; we do not provide a controlled | |
| 73 | −empirical evaluation of report quality, latency, or cost against baseline agents, and the | |
| 74 | −operational figures in Table~\ref{tab:robustness} are indicative rather than benchmarked. | |
| 75 | −Second, the platform inherits the limitations of its dependencies: the accuracy of any report is | |
| 76 | −bounded by the correctness and timeliness of the upstream market-data provider, and the model's | |
| 77 | −synthesis can still contain interpretive errors even when every number is computed | |
| 78 | −deterministically. The strict separation of reasoning from computation contains numerical | |
| 79 | −hallucination but does not eliminate the risk of a flawed \emph{narrative} around correct | |
| 80 | −numbers. Third, the quantitative methods rest on classical modeling assumptions---log-normal | |
| 81 | −prices, constant parameters over the estimation window, normally distributed returns in the | |
| 82 | −parametric VaR---that may be violated in practice; the platform exposes these methods as tools | |
| 83 | −and does not, by itself, certify their appropriateness for a given asset. Fourth, the | |
| 84 | −single-call paradigm trades some robustness for speed: a single failed execution forfeits an | |
| 85 | −entire analysis, whereas a decomposed agent can recover at a finer granularity. We regard the | |
| 86 | −design as the right default for interactive use but note the trade-off. These limitations | |
| 87 | −delineate a clear agenda for evaluation, which we sketch in the conclusion. | |
| 51 | +Several measures harden the system. Request bodies are validated against schemas at the | |
| 52 | +boundary. Database access is mediated by the object-relational mapper, which parameterises | |
| 53 | +queries. The front end parses Markdown through a sanitising pipeline, limiting cross-site | |
| 54 | +scripting from model output. Secrets are injected from the environment rather than committed. | |
| 55 | +Model-authored code runs in a child process with a wall-clock timeout, so that an infinite loop or a | |
| 56 | +crash cannot take the server down with it. The system prompt includes a guardrail that answers | |
| 57 | +attempts to extract the platform's implementation with a fixed refusal notice; this is a | |
| 58 | +prompt-level measure and, like all such measures, provides no guarantee against a determined | |
| 59 | +adversary. We do not claim that the sandbox is a security boundary against malicious code: the | |
| 60 | +child process runs with the server's privileges and network access, and the model is not an | |
| 61 | +adversary in the threat model, but a user who can steer the model into writing arbitrary code | |
| 62 | +is. Containerisation or a seccomp-style policy would be the appropriate hardening. | |
| 63 | + | |
| 64 | +\subsection{Threats to validity} | |
| 65 | +\label{subsec:threats} | |
| 66 | + | |
| 67 | +We distinguish threats to the validity of the design from threats to the validity of this | |
| 68 | +description. | |
| 69 | + | |
| 70 | +\paragraph{Design.} First, the separation of reasoning from computation contains \emph{numerical} | |
| 71 | +hallucination but not \emph{interpretive} error: the model can still write a wrong narrative | |
| 72 | +around correct numbers, select an inappropriate method, or mis-specify the code it writes, and | |
| 73 | +nothing in the loop checks the narrative against the numbers. Second, the single-call convention | |
| 74 | +trades granularity for speed; a failed execution forfeits the analysis, and the model's only | |
| 75 | +recovery path is to rewrite the code on the next turn. Third, the recursion has no depth bound, so | |
| 76 | +termination depends on the model; a bound is cheap and should be added. Fourth, the context | |
| 77 | +procedure is lossy, and the threshold and recency constants were set by judgement rather than | |
| 78 | +measurement. Fifth, the accuracy of every report is bounded by the correctness and timeliness of | |
| 79 | +the upstream data providers, and the platform does not cross-check providers against each other. | |
| 80 | +Sixth, the classical methods rest on standard assumptions---log-normal prices, constant parameters | |
| 81 | +over the estimation window, normal returns for parametric VaR---that the platform exposes but | |
| 82 | +does not certify for a given asset. Seventh, PDF rendering depends on externally hosted renderer | |
| 83 | +assets, and the Beamer path on a local \TeX{} installation; both are deployment dependencies that | |
| 84 | +the code does not verify at start-up. | |
| 85 | + | |
| 86 | +\paragraph{Description.} The paper describes one commit of a system that continues to change; | |
| 87 | +the model identifiers, tool counts, and constants reported here are facts about that commit, and | |
| 88 | +three of them (the tool count, the tokenizer, and the reachability of the numerical routines) | |
| 89 | +already differed from the platform's own documentation at the time of the audit. Appendix~\ref{app:audit} | |
| 90 | +lists the source of every statement so that a reader with access to the repository can re-check | |
| 91 | +them, and the audit script that produced the counts is distributed with the paper. | |
| 92 | + | |
| 93 | +\subsection{Reproducibility} | |
| 94 | +\label{subsec:repro} | |
| 95 | + | |
| 96 | +Reproducibility of a system of this kind has two layers. The \emph{design} is reproducible from | |
| 97 | +this paper: Algorithms~\ref{alg:loop} and~\ref{alg:context}, the constants in | |
| 98 | +Table~\ref{tab:rationale}, the prompt structure in Appendix~\ref{app:prompt}, and the | |
| 99 | +inter-process contract of Section~\ref{subsec:sandbox} are sufficient to re-implement it. The | |
| 100 | +\emph{outputs} are not reproducible in the strict sense, for four reasons that we record rather | |
| 101 | +than conceal. The main model call sets the sampling temperature to~1 and the summarisation call | |
| 102 | +to~0.5; the reference models are not seedable through the provider interface; the Python code is | |
| 103 | +authored by the model and therefore differs across runs even for an identical request; and the | |
| 104 | +pre-built Monte Carlo routine draws pseudo-random numbers without a fixed seed. What \emph{is} | |
| 105 | +reproducible, given a report, is every number in it: the tool calls and the executed code are | |
| 106 | +persisted with the session and displayed to the user, so any figure can be recomputed from its | |
| 107 | +recorded inputs. The system prompt is reproduced structurally in Appendix~\ref{app:prompt}; its | |
| 108 | +full text is in the repository. | |
| 109 | + | |
| 110 | +\subsection{A proposed evaluation protocol (not executed)} | |
| 111 | +\label{subsec:protocol} | |
| 112 | + | |
| 113 | +The following protocol is the evaluation step that the design-science process requires | |
| 114 | +\citep{peffers2007design} and that this paper does not perform. It is stated in enough detail to | |
| 115 | +be pre-registered. | |
| 116 | + | |
| 117 | +\paragraph{Task suite.} Three task families, each with ground truth that does not depend on a | |
| 118 | +model. (a)~\emph{Retrieval tasks}: 200 questions whose answers are single values obtainable from | |
| 119 | +the market-data endpoints at a frozen date (``What was NVDA's trailing twelve-month revenue as | |
| 120 | +of 30~June~2026?''), with the endpoint's value as ground truth; FinanceBench | |
| 121 | +\citep{islam2023financebench} supplies a complementary set over public filings. | |
| 122 | +(b)~\emph{Computation tasks}: 100 requests for standard quantities---Black--Scholes prices and | |
| 123 | +Greeks, GARCH(1,1) parameters, historical and parametric VaR, Monte Carlo terminal-value | |
| 124 | +quantiles---on frozen price histories, with ground truth from independent reference | |
| 125 | +implementations and seeded simulation; the quantitative-reasoning tasks of FinBen | |
| 126 | +\citep{xie2024finben} can be added. (c)~\emph{Report tasks}: 50 comprehensive requests graded by | |
| 127 | +two human analysts on a fixed rubric (coverage, correctness of every stated number against the | |
| 128 | +tool results, soundness of narrative, absence of unsupported claims), with an LLM judge | |
| 129 | +\citep{zheng2023judge} calibrated against the human grades on a held-out subset before being used | |
| 130 | +at scale. | |
| 131 | + | |
| 132 | +\paragraph{Metrics.} For (a) and (b): exact-match or tolerance-based accuracy; the | |
| 133 | +\emph{unsupported-number rate}, defined as the share of numbers in the response that do not appear | |
| 134 | +in any tool result or executed-code output, which operationalises numerical hallucination; and | |
| 135 | +tool-selection precision and recall against a minimal correct tool set. For (c): rubric scores, | |
| 136 | +inter-rater agreement, and the unsupported-claim rate. For all families: end-to-end latency | |
| 137 | +(median and 95th percentile), time to first token, number of model round trips, input and output | |
| 138 | +tokens (reasoning tokens reported separately), dollar cost from per-model list prices, and the | |
| 139 | +sandbox failure rate with its causes. | |
| 140 | + | |
| 141 | +\paragraph{Ablations.} Each mechanism is removed or varied while the rest is held fixed: | |
| 142 | +(i)~tools disabled (the model answers from parameters), which measures what grounding adds; | |
| 143 | +(ii)~adaptive thinking disabled; (iii)~the single-call instruction removed, so the model is free | |
| 144 | +to decompose, which measures the round trips and the failure rate the convention trades off; | |
| 145 | +(iv)~the context procedure varied over thresholds of $5\times10^{4}$, $10^{5}$, and $2\times10^{5}$ | |
| 146 | +tokens and recency of 3, 5, and 10 messages on 20-turn sessions, scoring the retention of | |
| 147 | +analytically relevant facts planted early in the session; (v)~batch size varied over 1, 5, and | |
| 148 | +unbounded, measuring rate-limit errors and latency; and (vi)~model tier varied across the selector | |
| 149 | +of Table~\ref{tab:models}. | |
| 150 | + | |
| 151 | +\paragraph{Baselines.} A plain model without tools; a ReAct-style loop \citep{yao2023react} with | |
| 152 | +one tool per turn; a code-interpreter-only agent in the spirit of program-aided language models | |
| 153 | +\citep{gao2023pal} with the same sandbox but no structured endpoints; and, as an upper reference | |
| 154 | +on the computation tasks, the reference implementations themselves. | |
| 155 | + | |
| 156 | +\paragraph{Controls.} All runs at a frozen data snapshot (recorded endpoint responses replayed | |
| 157 | +through a cache), three repetitions per task to estimate variance under temperature~1, and the | |
| 158 | +same prompts and constants as the audited commit unless the ablation varies them. Reported | |
| 159 | +outcomes would be accompanied by confidence intervals from the repetitions and by the full | |
| 160 | +transcripts. | |
| 161 | + | |
| 162 | +The protocol would answer the questions the first version of this paper left as assertions: | |
| 163 | +whether grounding reduces unsupported numbers to near zero, by how much the single-call | |
| 164 | +convention reduces round trips and at what cost in failures, how much the context procedure | |
| 165 | +loses, and what the architecture costs relative to simpler baselines. | |
modified
paper/tables/events.tex
+12 −12
@@ -1,31 +1,31 @@ | ||
| 1 | 1 | \begin{table}[htbp] |
| 2 | 2 | \centering |
| 3 | −\caption{The streaming event protocol. The server parses the provider's Server-Sent Event stream | |
| 4 | −and dispatches on each event's type; it then re-emits its own typed events to the client. This is | |
| 5 | −the mechanism by which reasoning, text, tool calls, and computed artifacts are surfaced | |
| 6 | −incrementally.} | |
| 3 | +\caption{Provider-side streaming event protocol. The server parses the provider's Server-Sent | |
| 4 | +Event stream and dispatches on each event's type; it then re-emits its own typed events to the | |
| 5 | +client (Appendix~\ref{app:events}). This is the mechanism by which reasoning, text, tool calls, and | |
| 6 | +computed artifacts are surfaced incrementally.} | |
| 7 | 7 | \label{tab:events} |
| 8 | 8 | \begin{threeparttable} |
| 9 | +\small | |
| 9 | 10 | \begin{tabular}{@{}lll@{}} |
| 10 | 11 | \toprule |
| 11 | 12 | Provider event & Sub-type & Server action \\ |
| 12 | 13 | \midrule |
| 13 | −\texttt{message\_start} & --- & read input/output token usage \\ | |
| 14 | +\texttt{message\_start} & --- & read input and output token usage \\ | |
| 14 | 15 | \texttt{message\_delta} & --- & update running output-token count \\ |
| 15 | −\texttt{content\_block\_start}& \texttt{tool\_use} & open a new tool call (name, id) \\ | |
| 16 | +\texttt{content\_block\_start}& \texttt{tool\_use} & open a new tool call (name, identifier) \\ | |
| 16 | 17 | \texttt{content\_block\_delta}& \texttt{text\_delta} & append to answer; forward to client \\ |
| 17 | −\texttt{content\_block\_delta}& \texttt{thinking\_delta} & forward reasoning on a separate channel \\ | |
| 18 | +\texttt{content\_block\_delta}& \texttt{thinking\_delta} & forward reasoning summary on a separate channel \\ | |
| 18 | 19 | \texttt{content\_block\_delta}& \texttt{input\_json\_delta} & concatenate partial tool-argument JSON \\ |
| 19 | 20 | \texttt{content\_block\_stop} & --- & parse accumulated JSON into tool arguments \\ |
| 20 | −\texttt{message\_stop} & --- & reconcile tokens; resolve the call \\ | |
| 21 | +\texttt{message\_stop} & --- & reconcile output tokens; resolve the call \\ | |
| 21 | 22 | \bottomrule |
| 22 | 23 | \end{tabular} |
| 23 | 24 | \begin{tablenotes}[flushleft] |
| 24 | 25 | \footnotesize |
| 25 | −\item \textit{Notes.} The client (Section~\ref{subsec:frontend}) performs the symmetric | |
| 26 | −operation: it reads the server's stream, splits on newlines retaining the trailing partial line, | |
| 27 | −and dispatches the server's own event types (text, thinking, tools, tool results, sources, | |
| 28 | −figures, specialized results, done) to dedicated renderers. | |
| 26 | +\item \textit{Notes.} Source: \path{server/services/claudeService.ts}. The client performs the | |
| 27 | +symmetric operation on the server's own stream: it reads bytes, splits on newlines retaining the | |
| 28 | +trailing partial line, and dispatches the server's event types to dedicated renderers. | |
| 29 | 29 | \end{tablenotes} |
| 30 | 30 | \end{threeparttable} |
| 31 | 31 | \end{table} |
modified
paper/tables/models.tex
+24 −14
@@ -1,27 +1,37 @@ | ||
| 1 | 1 | \begin{table}[htbp] |
| 2 | 2 | \centering |
| 3 | −\caption{User-selectable model tier. The orchestration service enables adaptive extended | |
| 4 | −thinking only for models that support it, and applies a uniform per-response generation cap. | |
| 5 | −The default is a reasoning-augmented model with a very large context window; alternatives let | |
| 6 | −users trade off capability, latency, and cost per query.} | |
| 3 | +\caption{Model layer at the audited commit. The reference path targets the Anthropic Messages API; | |
| 4 | +adaptive extended thinking is enabled only for the models listed as supporting it. OpenAI and | |
| 5 | +Google models are served through an OpenAI-compatible adapter that receives the first 128 tools of | |
| 6 | +the 245-tool catalogue. Model identifiers are reproduced verbatim from the client configuration | |
| 7 | +(\texttt{client/src/lib/models.ts}); the Anthropic identifiers were checked against the provider's | |
| 8 | +current model list, the others were not audited.} | |
| 7 | 9 | \label{tab:models} |
| 8 | 10 | \begin{threeparttable} |
| 9 | −\begin{tabular}{@{}llcc@{}} | |
| 11 | +\footnotesize | |
| 12 | +\begin{tabular}{@{}llccl@{}} | |
| 10 | 13 | \toprule |
| 11 | −Role in platform & Model family & Adaptive thinking & Typical use \\ | |
| 14 | +Provider path & Model identifier & Adaptive thinking & Context & Role in selector \\ | |
| 12 | 15 | \midrule |
| 13 | −Default & Reasoning-augmented (1M ctx) & Yes & Comprehensive reports \\ | |
| 14 | −High capability & Flagship reasoning & Yes & Hardest analyses \\ | |
| 15 | −Balanced & Mid-tier reasoning & Yes & Moderate queries \\ | |
| 16 | −Low latency & Fast tier & No & Simple lookups \\ | |
| 16 | +Anthropic (reference) & \texttt{claude-fable-5} & yes & 1M & default \\ | |
| 17 | +Anthropic & \texttt{claude-opus-4-8} & yes & 1M & long-horizon agentic \\ | |
| 18 | +Anthropic & \texttt{claude-opus-4-7} & yes & 1M & balanced \\ | |
| 19 | +Anthropic & \texttt{claude-opus-4-6} & yes & 1M & fast and capable \\ | |
| 20 | +Anthropic & \texttt{claude-sonnet-4-6} & yes & 1M & general purpose \\ | |
| 21 | +Anthropic & \texttt{claude-haiku-4-5-20251001} & no & 200K & lowest latency \\ | |
| 22 | +OpenAI-compatible & twelve OpenAI identifiers & n/a & -- & not audited \\ | |
| 23 | +OpenAI-compatible & four Google identifiers & n/a & -- & not audited \\ | |
| 17 | 24 | \bottomrule |
| 18 | 25 | \end{tabular} |
| 19 | 26 | \begin{tablenotes}[flushleft] |
| 20 | 27 | \footnotesize |
| 21 | −\item \textit{Notes.} Per-response generation is capped at 64{,}000 tokens. Adaptive thinking | |
| 22 | −lets the model allocate a variable budget of private reasoning before responding; its summary is | |
| 23 | −streamed to the client and shown in a collapsible panel. Context-window sizes and per-token | |
| 24 | −prices are determined by the model provider and abstracted away from the orchestration logic. | |
| 28 | +\item \textit{Notes.} Per-response generation is capped at 64{,}000 tokens and the temperature is | |
| 29 | +set to~1 on the reference path; the summarisation call of Algorithm~\ref{alg:context} uses a cap | |
| 30 | +of 2{,}000 tokens and a temperature of 0.5. The Beamer restructuring call | |
| 31 | +(Section~\ref{subsec:docs}) is pinned to \texttt{claude-opus-4-8} irrespective of the selected | |
| 32 | +model. Cost is computed from a single fixed schedule (\$3 per million input tokens, \$15 per million | |
| 33 | +output tokens) for every model, so the ledger does not reflect per-model prices | |
| 34 | +(Section~\ref{subsec:accounting}). | |
| 25 | 35 | \end{tablenotes} |
| 26 | 36 | \end{threeparttable} |
| 27 | 37 | \end{table} |
modified
paper/tables/robustness.tex
+21 −18
@@ -1,30 +1,33 @@ | ||
| 1 | 1 | \begin{table}[htbp] |
| 2 | 2 | \centering |
| 3 | −\caption{Operational characteristics of the platform. Latencies are indicative order-of-magnitude | |
| 4 | −figures for the corresponding subsystems rather than benchmarked measurements; they motivate the | |
| 5 | −streaming and single-call design choices discussed in the text.} | |
| 6 | −\label{tab:robustness} | |
| 3 | +\caption{Design rationale. Each mechanism is listed with the constant it uses at the audited | |
| 4 | +commit, the property it is intended to secure, and the measurement in the protocol of | |
| 5 | +Section~\ref{subsec:protocol} that would test it. No measurement has been made.} | |
| 6 | +\label{tab:rationale} | |
| 7 | 7 | \begin{threeparttable} |
| 8 | −\begin{tabular}{@{}lll@{}} | |
| 8 | +\footnotesize | |
| 9 | +\begin{tabular}{@{}>{\raggedright\arraybackslash}p{3.4cm}>{\raggedright\arraybackslash}p{2.7cm}>{\raggedright\arraybackslash}p{4.3cm}>{\raggedright\arraybackslash}p{4.6cm}@{}} | |
| 9 | 10 | \toprule |
| 10 | −Dimension & Mechanism & Indicative characteristic \\ | |
| 11 | +Mechanism & Constant & Intended property & Would be measured by \\ | |
| 11 | 12 | \midrule |
| 12 | −First-token latency & SSE streaming & sub-second perceived response \\ | |
| 13 | −Tool concurrency & batched execution & $\leq 5$ tools / batch, 500\,ms spacing \\ | |
| 14 | −Context window & adaptive summarization & effectively unbounded history \\ | |
| 15 | −Generation cap & per-response limit & 64{,}000 tokens \\ | |
| 16 | −Python analysis & sandboxed subprocess & seconds per execution \\ | |
| 17 | −PDF rendering & headless browser & several seconds \\ | |
| 18 | −Slide compilation & two-pass \LaTeX{} & roughly ten seconds \\ | |
| 19 | −Cost control & local token estimation & per-session accounting \\ | |
| 20 | −Rate-limit safety & inter-batch delay & bounded provider load \\ | |
| 13 | +SSE streaming (\S\ref{subsec:transport}) & flush per event & perceived latency decoupled from total latency & time to first token vs.\ end-to-end latency \\ | |
| 14 | +Recursive loop (\S\ref{subsec:loop}) & no depth bound & tool-use/tool-result pairing preserved across turns & protocol errors per 1{,}000 calls; recursion depth distribution \\ | |
| 15 | +Batched execution (\S\ref{subsec:batching}) & 5 per batch; 500\,ms & bounded provider load without altering what the model sees & rate-limit errors and latency at batch sizes 1, 5, $\infty$ \\ | |
| 16 | +Prompt routing (\S\ref{subsec:routing}) & 1--2 / 3--5 / 10+ tools & effort proportional to request complexity & tool-selection precision and recall by request class \\ | |
| 17 | +Per-result truncation (\S\ref{subsec:context}) & 3{,}000 / 15{,}000 chars & verbose results do not crowd the window & accuracy loss on tasks whose answer lies past the cut \\ | |
| 18 | +Re-send cap & 5{,}000 chars & re-sent history stays compact & input tokens per turn over 20-turn sessions \\ | |
| 19 | +Adaptive summarisation & $\tau=10^{5}$; $k=5$ & coherence over long sessions & retention of planted facts after summarisation \\ | |
| 20 | +Token correction (\S\ref{subsec:accounting}) & max(provider, local) & cost never understated for text & ledger vs.\ provider invoice over a month \\ | |
| 21 | +Single-call convention (\S\ref{subsec:onecall}) & instruction only & one round trip per analysis & round trips and sandbox failure rate with vs.\ without the instruction \\ | |
| 22 | +Process sandbox (\S\ref{subsec:sandbox}) & 90\,s; 150\,dpi & server isolated from code faults & crash containment under fault injection \\ | |
| 23 | +Live-formula spreadsheets (\S\ref{subsec:docs}) & --- & deliverable carries its derivation & share of cells that are formulas \\ | |
| 21 | 24 | \bottomrule |
| 22 | 25 | \end{tabular} |
| 23 | 26 | \begin{tablenotes}[flushleft] |
| 24 | 27 | \footnotesize |
| 25 | −\item \textit{Notes.} Figures characterize the subsystems qualitatively to explain design | |
| 26 | −trade-offs; a controlled performance evaluation is left to future work | |
| 27 | −(Section~\ref{sec:conclusion}). | |
| 28 | +\item \textit{Notes.} Constants are those of \path{server/routes.ts}, | |
| 29 | +\path{server/services/claudeService.ts}, \path{server/services/claude/tokenManagement.ts}, | |
| 30 | +and \path{server/services/python/var.ts} at commit \texttt{e2a148a}. | |
| 28 | 31 | \end{tablenotes} |
| 29 | 32 | \end{threeparttable} |
| 30 | 33 | \end{table} |
modified
paper/tables/tools.tex
+25 −23
@@ -1,36 +1,38 @@ | ||
| 1 | +% Generated by docs/verify/audit_vquant_code.py from vquant.git commit e2a148a (2026-10-17). Do not edit by hand. | |
| 1 | 2 | \begin{table}[htbp] |
| 2 | 3 | \centering |
| 3 | −\caption{Taxonomy of the tool catalogue exposed to the model. VQuant defines more than two | |
| 4 | −hundred tools through a schema-driven function-calling protocol. Counts are approximate and | |
| 5 | −group conceptually related endpoints; the financial families are backed by a market-data | |
| 6 | −provider exposing over 265 endpoints, wrapped by roughly 230 typed server functions.} | |
| 4 | +\caption{Tool catalogue exposed to the model, by family. Counts are exact and were extracted programmatically from the tool-definition module of the audited code (vquant.git, commit e2a148a, 2 October 2026): 245 schema-defined tools. The financial families wrap two commercial market-data providers (249 typed wrapper functions over 233 distinct endpoint paths of the primary provider, plus the EODHD family); the web-research family wraps three services. Models served through the OpenAI-compatible adapter receive only the first 128 tools of the catalogue because of that interface's limit.} | |
| 7 | 5 | \label{tab:tools} |
| 8 | 6 | \begin{threeparttable} |
| 9 | −\begin{tabular}{@{}lll@{}} | |
| 7 | +\footnotesize | |
| 8 | +\begin{tabular}{@{}>{\raggedright\arraybackslash}p{5.0cm}r>{\raggedright\arraybackslash}p{8.6cm}@{}} | |
| 10 | 9 | \toprule |
| 11 | −Family & Count & Representative tools \\ | |
| 10 | +Family & Tools & Representative tools \\ | |
| 11 | +\midrule | |
| 12 | +Fundamentals, valuation and classification & 56 & profile, income statement, balance sheet, cash flow, key metrics, DCF, screener \\ | |
| 13 | +SEC filings, transcripts and ownership & 37 & filings by form/CIK/symbol, 8-K, call transcripts, 13F, institutional holders \\ | |
| 14 | +Events, calendars and corporate actions & 15 & earnings, dividends, splits, IPO calendars, M\&A, market hours \\ | |
| 15 | +Forex, crypto and commodities & 15 & FX and crypto quotes and lists, commodity quotes, batch quotes \\ | |
| 16 | +Web research (Firecrawl, Tavily, Exa) & 14 & scrape, crawl, map, extract, agent; search, research; neural search \\ | |
| 17 | +Insider and congressional trading & 14 & insider trades and statistics, House and Senate disclosures \\ | |
| 18 | +Indices, ETFs and funds & 14 & S\&P 500 / Nasdaq / Dow constituents, ETF holdings and weightings \\ | |
| 19 | +Quotes, prices and market movers & 14 & quote, historical and intraday prices, gainers, losers, actives \\ | |
| 20 | +Technical indicators & 12 & RSI, MACD, SMA/EMA/WMA/DEMA/TEMA, ADX, CCI, stochastic, Williams \%R \\ | |
| 21 | +Analysts, ratings and price targets & 11 & estimates, price targets, grades, ratings, upgrades/downgrades \\ | |
| 22 | +News and press releases & 9 & stock, forex, crypto and general news; press releases \\ | |
| 23 | +ESG, compensation and alternative data & 9 & ESG scores and benchmarks, social sentiment, headcount, executive pay \\ | |
| 24 | +Global market data (EODHD) & 8 & symbol search, EOD and intraday bars, fundamentals, news (70+ exchanges) \\ | |
| 25 | +Economic and macro & 6 & treasury rates, indicators, economic calendar, COT reports, risk premium \\ | |
| 26 | +Search and identifiers & 5 & company, symbol, CUSIP, ISIN and CIK lookup \\ | |
| 27 | +Options & 4 & option chain, contract prices, Greeks (EODHD); Black--Scholes pricer \\ | |
| 28 | +Advanced analysis & 2 & custom Python execution, bulk data download, SEC filing extraction \\ | |
| 12 | 29 | \midrule |
| 13 | −Company fundamentals & 40+ & profile, income statement, balance sheet, cash flow, ratios \\ | |
| 14 | −Market data & 30+ & quote, historical / intraday prices, market movers, batch quote \\ | |
| 15 | −Technical analysis & 8+ & RSI, MACD, EMA/SMA, ADX, CCI, stochastic, Williams \%R \\ | |
| 16 | −Analyst and ratings & 20+ & estimates, price targets, upgrades/downgrades, rating history \\ | |
| 17 | −Insider and institutional & 15+ & insider trades, 13F filings, congressional/senate trading \\ | |
| 18 | −Economic and macro & 15+ & treasury rates, indicators, calendar, COT reports \\ | |
| 19 | −Forex and crypto & 15+ & FX and crypto quotes, lists, historical series, commodities \\ | |
| 20 | −SEC and compliance & 25+ & filings by form type, company notes, call transcripts \\ | |
| 21 | −Events and calendars & 10+ & earnings, dividends, splits, IPO calendar and disclosures \\ | |
| 22 | −ESG and alternative & 20+ & ESG scores, social sentiment, headcount, executive pay \\ | |
| 23 | −Options & 4 & option chain, prices, Greeks, volatility surface \\ | |
| 24 | −Advanced analysis & 7 & Monte Carlo, Black--Scholes, custom Python, bulk download \\ | |
| 25 | −Web research & 6 & scrape, crawl, extract; AI / semantic / engine search \\ | |
| 30 | +Total & 245 & \\ | |
| 26 | 31 | \bottomrule |
| 27 | 32 | \end{tabular} |
| 28 | 33 | \begin{tablenotes}[flushleft] |
| 29 | 34 | \footnotesize |
| 30 | −\item \textit{Notes.} The system prompt instructs the model to select tools according to query | |
| 31 | −complexity (Section~\ref{subsec:routing}); the most powerful entries---Monte Carlo simulation, | |
| 32 | −option pricing, and arbitrary Python execution---are described in detail in | |
| 33 | −Section~\ref{sec:capabilities}. | |
| 35 | +\item \textit{Notes.} Family assignment follows keyword rules on tool names (\texttt{docs/verify/audit\_vquant\_code.py}); a tool belongs to exactly one family. The system prompt (Section~\ref{subsec:routing}) describes only a subset of these tools explicitly; the full catalogue is transmitted as JSON schemas with every model call. Six server-side handlers for pre-built numerical routines (Monte Carlo, GARCH, VaR, portfolio optimisation, risk metrics, plotting) exist in the route module but are not in the catalogue at the audited commit and are therefore unreachable by the model (Section~\ref{subsec:numerical}). | |
| 34 | 36 | \end{tablenotes} |
| 35 | 37 | \end{threeparttable} |
| 36 | 38 | \end{table} |
| 37 | 39 | |