Skip to content
learn

GA's AI: OPTIC-K, ML, agents and the chatbot — Mission

Guitar Alchemist (GA) has a chatbot for guitarists. Behind it sit a 240-number description of every guitar chord shape, called OPTIC-K, an index of 313,047 of those descriptions, a router that decides which piece of code answers a question, and a handful of agents that call a language model. The documentation around it is large and partly out of date, and the code moves every week.

I want to know what actually happens: which numbers a chord gets, why two chords come out as similar, what the index file contains, and what the chatbot does with a question when no model is reachable. The way to find out is to call GA’s own classes from a program, print what they return, and compare it with what the comments and the documents say. Where the two disagree, the difference goes into the journal.

You write C#. You know float[], LINQ, dependency injection and ASP.NET Core well enough to read a Program.cs. You don’t need any machine learning: the course uses three ideas, each explained where it first appears.

  1. An embedding is a fixed-length array of numbers that describes an object, so that similar objects get similar arrays.
  2. Cosine similarity measures how much two such arrays point the same way: 1 for the same direction, 0 for nothing in common.
  3. Nearest-neighbour search returns the stored arrays closest to a query array.

Three other courses on this site cover the background, and this one links to them instead of repeating them:

By the end of this course, I will be able to

Section titled “By the end of this course, I will be able to”
  • draw GA’s AI stack: which project computes embeddings, which writes the index, which routes a chat message, and what ix, Demerzel and TARS do around it;
  • read an OPTIC-K vector partition by partition, compute the weighted similarity of two voicings by hand, and say what the vector is and isn’t invariant to;
  • open an OPTK index file, explain its header, and predict what a search returns and why;
  • follow a chat message through GA’s hooks, deterministic guards, intent router and agents, and explain why some questions work without a model and others fail;
  • grade a deterministic skill’s musical answers with a small oracle of my own, and say where the oracle stops;
  • read a server-sent event stream as the HTML standard does, and check that the text a client rebuilds is the text the server computed;
  • run a fix that isn’t in the pinned commit next to the pinned code, and test a guard with input it wasn’t written for;
  • test a test suite: apply its checks to answers they weren’t written for and to answers that are wrong on purpose, and read what passes;
  • test a skill on every input it can be given, with a textbook’s arithmetic as the oracle, and run a skill’s own example prompts against it;
  • tell apart, in GA’s AI, what works today, what is being built, and what is only planned.
# Lesson In GA If you write C#
1 The map the five layers, the index pipeline, the chatbot host, the sibling repositories reading a DI container, WebApplicationFactory
2 OPTIC-K embeddings EmbeddingSchema, MusicalEmbeddingGenerator, VoicingAnalyzer positional records, TensorPrimitives
3 The index and search OptickIndexWriter, OptickIndexReader, OptickSearchStrategy, MusicalQueryEncoder binary formats, memory-mapped files, top-k heaps
4 The chatbot and its agents ProductionOrchestrator, SemanticIntentRouter, SemanticRouter, skills, hooks hosted services, fallbacks, testing a host in process
5 The improvisation skill ImprovisationSkill against chord–scale theory, issue #744 source-generated regexes, reading AgentResponse.Data, writing a test oracle
6 The answer on the wire SseChunker, the two WriteSseLineAsync, the page’s and ga-client’s readers, #743 and #746 server-sent events, Regex.Split and lookarounds, porting a client to test it
7 Chord names it can’t read InvalidChordNames (#749), the chord expressions of ImprovisationSkill, issue #745 extern alias and CS0436, word boundaries in regular expressions
8 The chatbot’s own exam prompts.yaml and PromptCorpusTests, DiatonicChordsSkill (Path B), ModesSkill YamlDotNet, StringComparison, testing a test suite with wrong answers
9 Every interval, every key IntervalSkill, ScaleInfoSkill, RelativeKeySkill, KeyNaming, the domain’s DetermineQuality exhaustive tests, \b and lookahead in regular expressions, switch default arms
10 What the model is told to trust ga_dsl_eval, the closures domain.diatonicChords, domain.transposeChord and domain.commonTones, the SKILL.md files of the three Path B skills calling a model’s tool without the model, one letter per degree, reusing an oracle across lessons
11 The chords the key skill reads KeyIdentificationService at the pin and on main, ga_key_identify, KeyIdentificationSkill, the key-identification SKILL.md reading symbols out of prose, a ranking and the selection built on it, calling private methods by reflection
12 What the progression skills answer ProgressionMoodSkill, ProgressionCompletionSkill, their SKILL.md files, KeyIdentificationService at the pin and on main a word test that picks a fixed answer, a model restricted to a computed list, keyword fallback routing
13 What the progression analysis answers the closure domain.analyzeProgression at the pin and on main, ga_dsl_list_closures, the progression-analysis draft, KeyIdentificationService.IsChordDiatonic compiling another commit’s F# file against the pinned project, a draft’s examples as a test, Roman numerals from the scale and from the chord
14 What the substitution skill answers ChordSubstitutionSkill, ga_chord_substitutions and ga_chord_compare, GrothendieckService.FindNearby, GrothendieckDelta, the closure domain.chordSubstitutions a distance under which a whole set class ties, a tie broken by storage order, optional inputs a tool requires
15 The notes of a chord ChordInfoSkill, ChordVocabulary, ChordSpelling, ga_chord_info and the chord-info SKILL.md the leftmost match of a regular expression, ToLowerInvariant beyond ASCII, a round trip as a test
16 The voicings of a chord ChordVoicingsSkill, TypedMusicalQueryExtractor, ChordPitchClasses, OptickSearchStrategy and ADR-0002, at the pin and on main a second clone of a dependency at another commit, checking an answer by playing it, a filter on names, a filter dropped without a word in the answer
17 The capo and the tunings CapoSkill, AlternateTuningsSkill and the offline fallback, at the pin and on main checking arithmetic against a textbook on every key and fret, a word boundary after an accidental, a direction read from the phrasing, spelling as part of the answer
18 Voice leading VoiceLeadingSkill and the offline fallback checking a claim of optimality against an exhaustive search, a doubling chosen without a search, a table of symbols behind a narrower expression, a case-insensitive search for a flat
19 Voice-leading pairs ga_voice_leading_pair in GaMcpServer, its search at the pin and on main, and the parked voice-leading skill a ranking that never checks what it ranks, more candidates that make the answer worse, a sorted matching that is the least only for equal sizes, a string order that one consumer fixed and another passes on
20 Generated progressions ga_generate_progression in GaMcpServer, GA’s twelve-key tables, the stitching with ga_voice_leading_pair at the pin and on main, and the parked progression skill spelling from a key signature rather than a name, two sources that agree on a wrong chord, a parameter without a limit, answers for single moves that don’t make a path
21 The voicing search ga_search_voicings and ga_voicing_vocabulary in GaMcpServer, GA’s query reader, tag registry and voicing-search skill, at the pin and on main, and the parked voicing-search skill a word read and then dropped, many tags on few bits, a tag that isn’t a filter, words matched by substring, a score range out of reach
22 Similar chords IcvNeighborsSkill and IntervalClassVectorSkill in GA.Business.ML, GrothendieckService.FindNearby and the routing hints, at the pin and on main, and the parked icv-neighbors skill routing anchors the parser doesn’t read, a table that falls back to a major triad, a sort over equal costs, neighbors that depend on the vector only
23 Harmonic distance and path GrothendieckDeltaSkill and IcvShortestPathSkill in GA.Business.ML, GrothendieckDelta and GrothendieckService.FindShortestPath, at the pin and on main a distance that is never zero, an interpretation that reads one rule, mojibake in an answer, a search that can’t succeed, steps counted as sets
24 Set classes and the Grothendieck parser SetTheoryEquivalenceSkill and GrothendieckParseSkill in GA.Business.ML, and GrothendieckOperationsParser in GA.Business.DSL, at the pin and on main a relation never read, a set read from its last number, a parser whose spaces are already eaten, an answer about no chord
25 What reaches the transpose skill DefaultRoutingHintProvider, TransposeSkill, SkillMdPlugin and the two routers of the chatbot host, at the pin and on main a hint that misses the skill’s own examples, a skill no fallback can reach, a default that answers every question nobody claims
26 The modes catalog ModesSkill, Modes.yaml and ModesConfig, at the pin and the same on main modes that aren’t their family’s scale, names cut by a YAML comment, formulas numbered by position
27 Notes that sound outside OutsideNotesSkill and ChordVocabulary, at the pin and the same on main tensions no chord scale holds, an 11 inside 13th chords, chord symbols cut short, sharps in flat chords
— Journal
  • The .NET 10 SDK and Git. On Windows, run the course scripts from Git Bash.
  • About 20 MB of disk for GA’s partial clone, and about 1.1 GB once GA’s projects and the course program are built.
  • A network connection for the first run only, to clone GA and restore the NuGet packages. After that, everything runs offline.
  • No guitar needed, but the chord shapes in lesson 2 are the first ones a guitarist learns.