#ai

35 notes

Point an Agent at Your Primitives

2026-07-09 · 6 min read

I’ve been redesigning how agents interact with Codex, the Bible translation platform I work on, and I keep arriving at the same conclusion from different directions: the fewer tools you hand an agent, the more useful it becomes.

That sounds backwards. The instinct when you’re wiring an LLM up to your app is to give it a tool for everything — draft-cell, add-comment, flag-verse, assign-reviewer, one narrow function per feature, mirroring your UI one button at a time. I did this. It’s tempting because each tool is easy to write and easy to reason about in isolation. But a big tool list doesn’t compose. The agent has to guess which of forty near-synonymous actions you meant, the tools drift out of sync with the schema the moment someone ships a migration, and every new feature means another tool to write, document, and keep working. You end up maintaining two apps: the one your users touch and the one your agent touches, and they’re never quite the same shape.

What’s worked much better is collapsing almost everything down to a couple of general read and write tools, scoped to whatever permissions the calling user already has. The agent reads the state of a project the same way a human collaborator would, and writes to it the same way — no bespoke verb for every noun in the schema. If it needs to add a comment, it writes a comment record. If it needs to update a draft, it writes a draft record. The permission boundary does the safety work a narrow tool surface used to do, more reliably, because it’s the same boundary the rest of the app already respects. My rule of thumb these days: the fewer skills the better — that’s my life motto.

The same instinct showed up somewhere I didn’t expect: file import. Every translation partner who comes to Codex arrives with a different mess — some odd export from a decades-old tool, a spreadsheet with the columns in a different order than the last one, a zip of audio files with timestamps embedded in the filenames a different way each time. For a while I did what you’d expect: write a custom importer per partner, hand-map fields, ship it, wait for the next partner to show up with a format that didn’t fit any of my existing code. Individually reasonable, collectively absurd. Why would I build a custom importer for everybody — that’s so dumb. Nobody has time to maintain forty importers for forty file dialects that only exist because forty people exported data forty different ways.

So I stopped. Now the files just get dropped in, and an agent looks at them and writes the import logic on the fly, against the same general read/write primitives the rest of the system uses. It doesn’t need a parse-partner-x-format tool — just the raw files and a sense of what a well-formed record looks like on the other end. It can figure out the rest, which is exactly what I was doing by hand, just slower and with worse pattern recognition than a model that’s seen a thousand CSVs.

The moment this really clicked, though, came from a partner, not from my own code. He mentioned, almost in passing, that he’d basically stopped using the platform’s UI. Instead he tells his own agent: “you have the API key, solve this problem.” Whatever shape his data was in, whatever oddball task he needed done, he wasn’t waiting for a feature request to land on my roadmap — he was pointing an agent at the API and letting it write the one-off integration itself.

That reframed the importer problem for me. I’d been treating “build a custom importer per partner” as the cost of doing business, when the fix was to stop being the one who has to write the importer at all. If the app exposes its primitives — read, write, the actual shape of the data — over an API, then each partner’s own agent can write its own integration code, on demand, for exactly the file format it happens to have that day. Funnily enough, I’d already done the equivalent of this the same day, for a genuinely strange batch of audio, timestamps, and transcription files that didn’t map onto any importer I’d built — I just pointed an agent at the primitives and let it sort out the mapping. As long as the primitives are there in the app, if you can just point your agent at it and have it do stuff, that would be super cool. It already is.

There’s a broader shift underneath this that isn’t specific to translation tooling at all. A well-understood, genuinely low-complexity integration — say, auto-syncing translation progress to a partner’s own project-tracking board — used to sit in the backlog forever. Not because it was hard, exactly, but because “hard” was never the real constraint; the constraint was that it was tedious, one-off, and not obviously worth a sprint against everything else competing for the same week. A year ago I’d have said no to this integration. Today it’s an afternoon, because I’m not the one writing the glue code line by line — I’m reviewing what an agent wrote against primitives that already existed.

That’s the pattern I keep running into, in multi-agent translation and swarm-translation and everywhere else I’ve experimented with multi-agent setups: the leverage isn’t in building smarter individual tools, it’s in building fewer, more general ones and trusting an agent — the app’s, or increasingly, the partner’s own — to compose them into whatever the moment requires. The bespoke integration business was never a good business to be in. It just used to be the only option.

Permalink →

In a room of around forty consultants, one I respect raised five objections to “AI in Bible translation” in the space of about ten minutes: it can’t use the Greek and Hebrew, it has no dictionary, it doesn’t know genre, you can’t give it a translator’s prompt, and you can’t feed it small, controllable batches of text. Every one of those is a fair complaint. None of them is about the tool we’re actually using.

They’re objections to Google Translate.

Seq2seq machine translation—the architecture behind Google Translate and its era-mates—really did work that way. It mapped strings to strings with no access to source-language grammar as an object you could reason about, no lexical resources beyond whatever got baked into training, no sense of genre or register beyond statistical correlation, and no mechanism for a human to say “translate this the way we discussed last week” and have it stick. If that’s the AI you have in mind, the objections aren’t just fair, they’re the whole story. I’ve spent enough time watching seq2seq output wander off-register mid-sentence to know the scar tissue is earned.

But a modern LLM can read the Hebrew, hold a conversation about a difficult word’s semantic range, look up a lexicon entry you hand it in context, take a translator’s brief as a literal system prompt, and work in exactly the batch size a team wants—a verse, a paragraph, a pericope. It can be shown the genre and asked to translate accordingly. None of this is hypothetical; it’s the ordinary operating mode of the tools I use most weeks. So when I hear the same five objections raised against “AI,” I want to redirect: every objection I hear to “AI in Bible translation” is actually an objection to Google Translate. Which means the objection is sound, but the target has moved.

I don’t think this makes the skepticism illegitimate. Consultants built their caution around real failure modes, over years of watching tools get chosen from the top down and pushed into low-resource languages even after the field had already seen them produce fluent-sounding nonsense. That caution is a feature of the field, not a bug to route around. The useful move isn’t to say “you’re wrong, AI is great now”—it’s to ask which specific objection still holds against a system that can read source text, hold a controllable-length conversation, and be handed a prompt like any other collaborator. Some of them, updated for the new architecture, still land. Most of the five I listed above don’t survive contact with what an LLM can actually do, though—which is a separate question from whether the output is good, a question I’ve tried to be more precise about before.

That precision question is where I get more cautious, not less. There’s a pull toward settling all of this with a rigorous benchmark—controlled comparison, blinded reviewers, speed and quality scored against a fixed rubric. I understand the appeal; it’s the responsible-sounding thing to do. But I’ve come to distrust it for a specific reason: by the time you finish the rigorous benchmark, the thing you benchmarked is obsolete. The workflow, the model, the prompting approach—all of it will have shifted meaningfully in the months a careful study takes to design, run, and write up. What you publish is a precise measurement of a tool nobody is using anymore, dressed up in the authority of a number. I’d rather have a translator’s rough, unrigorous sense of “this draft used to take me a day and a half, now it takes an afternoon” than a beautifully controlled study of last year’s pipeline. It’s less defensible on paper and more true in practice—false precision is still false.

That same instinct toward “faster at what, exactly” applies to the bigger debate hovering over all of this: is AI-assisted translation faster than the traditional process? I’ve started to think that’s the wrong question, or at least an underspecified one. Traditional translation and AI-assisted translation quite often aren’t racing toward the same finish line. A team producing a digital-only translation for a community that needs Scripture in an app this year has a different goal than a team producing a fully checked, print-ready Bible meant to anchor a language’s translation for a generation. Comparing their speed head-to-head is a bit like timing a sprinter against a marathoner and declaring one of them slow. “Is AI faster than traditional translation?” is the wrong question. Faster at what—and toward whose goal? This is the same move I made in thinking through Occam’s razor and translation: the interesting question usually isn’t which process is objectively better, it’s what inputs and outputs a given goal actually requires, and whether the process in front of you is shaped for that goal or just inherited from a different one.

I don’t think any of this settles the underlying argument about whether AI belongs in Bible translation workflows at all—that’s a longer conversation, and a more contested one than I’m trying to resolve here. But I’d like the argument to be about the tool that’s actually in the room. Google Translate earned its objections. The thing translators are using now is a different animal, and it deserves to be evaluated as one—carefully, skeptically, and on its own terms, rather than refuted by proxy.

Permalink →

Steering, Not Batch-and-Correct

2026-07-08 · 6 min read

I’ve started thinking about AI-assisted translation the way I think about flying a plane. Not takeoff and landing — the boring middle part, where the whole job is thousands of tiny course corrections. A pilot doesn’t fly a thousand miles off heading and then swing back. They nudge, constantly, and each nudge changes the trajectory for everything that follows. That’s steering. The alternative — fly wherever the plane happens to go, then fix the path after landing — isn’t really an alternative, it’s a category error. But it’s more or less how most people still do AI-assisted translation: generate a draft, then post-edit it.

The generate-then-fix pattern is everywhere in machine translation tooling, and for good reason — it’s simple, it maps onto existing editorial workflows, and for a lot of content it’s fine. But I’ve become convinced it’s the wrong default for anything that depends on in-context learning, which is most of what I work on. Here’s the distinction I keep coming back to: when you correct a translation in context, before the model has moved on, that correction becomes part of the context for every subsequent prediction. When you batch-generate first and correct afterward, the correction lands in a document, not in the model’s working context for the next verse. It’s informative to a human reviewer. It’s close to invisible to the model.

Concretely: imagine you finish Genesis 1:1, and you corrected three things — a term choice, a syntactic pattern, an idiom. Am I gonna have to correct those same three things in every other verse where they show up? That would be crazy. If the correction is made in-context and the model sees it before generating Genesis 1:2, it doesn’t have to be. If it’s made afterward, in a separate editing pass, it does — you’ll be fixing the same idiom for the two-hundredth time in Deuteronomy, wondering why the model “isn’t learning.” It isn’t that the model can’t learn. It’s that batch editing never gave it the chance.

Whether this matters depends a lot on the stakes. For low-stakes content — app UI copy, a button label, something a user skims and moves past — generate-and-fix is genuinely fine. Nobody’s faith or family history hinges on a “Submit” button. But for high-trust, educational, or scriptural content, the calculus flips, because a fluent wrong answer is a different kind of failure than an obviously bad one. A garbled, clunky translation gets caught — it looks wrong, so someone checks it. A confidently fluent wrong translation doesn’t announce itself; it reads naturally and gets trusted. I’ve come to think a confident wrong answer is worse than no answer at all, and steering is partly a response to that asymmetry: it’s a way of keeping a human correction in the loop before fluency gets a chance to disguise an error, rather than trying to audit fluency after the fact. This is the same instinct behind treating translation quality as something that has to be actively converged on rather than assumed — I wrote about the social, consensus-driven version of that idea in Consensus Translation.

I have a real case that convinced me this isn’t just theory. On a full Bible translation project in Portuguese, we saw both patterns play out on the same underlying system. One workflow involved continuous correction — a translator reviewing and correcting essentially every prediction as it was generated, feeding straight back into the next one. Another workflow, used by some translators on the same team, was to batch-draft a chunk of verses first and edit them afterward, document-style. The batch-and-edit group came away convinced the AI wasn’t learning from their corrections — the same errors kept resurfacing chapter after chapter. But the model wasn’t failing to learn; it was never shown the correction at a moment when it could use it. It’s like flying a thousand miles and then trying to correct it, instead of correcting as you go — the destination doesn’t move just because you finally noticed you were off heading.

That case study is what pushed me toward a rougher framework I’ve been using since, mostly as a sequencing heuristic rather than anything rigorous: golden path and silver path. Golden path is for when someone’s actually watching — a human reviewing and correcting every single prediction in real time. Because that attention is expensive, you spend it on the material most worth learning from: the most distinctive, highest-coverage constructions, the ones whose corrections will generalize furthest downstream, translated first. Silver path is for when nobody’s watching as closely — the model runs ahead on material that’s comparatively easy or low-risk, and anything that looks uncertain gets flagged for a human to review later rather than corrected live. Golden path when someone’s watching, silver path when they’re not.

I don’t think this framework is settled — it’s closer to a rule of thumb I’ve been testing against real projects than a methodology I’d defend in the abstract, and I’d guess the boundary between “distinctive enough to deserve golden-path attention” and “safe enough for silver path” needs to get a lot more precise before this generalizes past the projects I’ve watched it work on. But it’s already changed how I sequence work, in the same spirit as the simplification argument in Occam’s Razor and Bible Translation: before adding more review infrastructure, ask whether the correction you’re about to make is actually reaching the next prediction, or just the next document.

Permalink →

The Pipeline That Wrote This Post

2026-07-08 · 4 min read

I want to make a slightly awkward claim up front: I didn’t sit down and decide to write this post. A pipeline on my laptop decided it was worth writing, and I mostly agreed.

Here’s the setup. I have an on-device transcriber that arms itself passively whenever the microphone is in use for anything else — a call, a voice memo, a meeting, doesn’t matter what app. It listens, transcribes locally, and then does something I care about more than the transcription itself: it discards the raw audio. No recording survives. What gets saved is the text, dropped into Notes, and that’s it. If you want to know what was said, you get a transcript. If you want to hear my voice saying it, you’re out of luck, because that copy never existed past the few seconds it took to turn sound into words.

That’s step one, and it runs quietly, all day, without me thinking about it.

Step two is where it gets more interesting, and slightly stranger. A scheduled job — a Claude automation that fires once a day — reads that day’s transcripts and goes looking for anything shareable: an anecdote, a lesson, a half-formed idea I said out loud in a meeting and immediately forgot. It doesn’t try to write anything polished. It produces a set of short, structured candidate notes, one per idea, each tagged with a letter and led with a hook — the kind of thing you’d pitch yourself in one sentence before deciding whether it’s worth the next thirty minutes. Some days there are none. Some days there are six, and four of them are bad.

Step three is me. I read the day’s candidates the way I’d skim a slush pile — fast, unsentimental, looking for the one or two that still sound interesting once the meeting adrenaline has worn off. Most get discarded. A few get flagged.

Step four is an AI agent taking a flagged candidate and turning it into an actual draft — structure, examples, the whole thing. This post is a step-four output. This post came out of it.

I’ll admit there’s something faintly unsettling about a system that’s quietly always listening for your own good ideas. Not unsettling in a surveillance sense — I built the privacy boundary specifically so it wouldn’t be that — but in the sense that it changes how I relate to my own stray thoughts. I used to lose most of them. Now there’s a nonzero chance that something I mumbled in a standup gets mined, structured, and handed back to me a day later as “here’s a hook, do you want this.” It’s a strange kind of externalized memory, closer to what I was reaching for in Memorize Anything with AI Music — offloading recall onto a system so the interesting part of my brain doesn’t have to hold onto it — except this one runs on everything I say, not just what I deliberately feed it.

The audio-discard choice is the part I’d defend hardest if someone pushed back on this. It would be trivial to keep the recordings — better transcription accuracy, re-processing later, all the usual arguments. I didn’t want any of that badly enough to keep a standing archive of my own and other people’s voices sitting on disk. Text is legible, editable, and it forgets the timbre, the room, the identifiable stuff. That’s not a limitation I haven’t gotten around to fixing. It’s the actual design, the same instinct that shows up in how I’d want any multi-agent system — like the ones in multi-agent translation — to be legible about what it’s doing with your input, not just capable.

I don’t fully know yet whether mining my own days for content is a good habit or a slightly cursed one. I’m going to keep running it and see what it thinks is worth saying next.

Permalink →

Give the Agent a Loss Function

2026-07-04 · 5 min read

I’ve been running a lot of agentic coding sessions lately, and the sessions that go well have one thing in common: I gave the agent a number to hit, not a vibe to chase.

The bad version looks like “improve the audio pipeline” or “clean this up.” An agent handed that kind of instruction will do something — it has to, agents are compulsive doers — but it has no way to know when it’s done, so it stops when it runs out of ideas rather than when the problem is solved. The good version looks like “get audio round-tripping fidelity to 99%, and keep iterating against a test that measures it.” Same task, wildly different outcome, because now the agent has a number to close a gap on instead of a mood to satisfy.

This is training an ML model with extra steps, and once I noticed that I couldn’t unsee it. Training an ML model without a loss function doesn’t work — there’s no signal telling the optimizer which direction is “better,” so it just wanders. Prompting an agent without one doesn’t either, for the same reason: without a measurable target, “iterate until it’s good” quietly collapses into “stop when tired.” Give the agent a metric — a percentage, a test suite, a check it can run on its own output — and iteration turns into something closer to gradient descent: try, measure, adjust, repeat, until the number clears the bar.

I’d actually run into a version of this problem years before agentic coding was a category. The multi-agent translation simulation I built back in 2023 had a forward-translation bot, a back-translation bot, and an evaluation bot looping until “the translation draft stabilizes (if it does!)” — and in the demo, it never did, because none of the bots had a concrete stop condition, just each other to wait on. “Stabilized” was a vibe, not a number, so nothing ever stabilized. Different domain, same missing piece: no loss function, no convergence, no way to know the job was done.

That earlier miss is also where the swarm framing turns out to generalize better than I expected. Once each subagent in a swarm has its own measurable target, you can split work across a lot of them without losing the plot. The pattern I keep coming back to for coding specifically: spin up several cheaper, faster subagents to handle the parallelizable pieces of a task, and have each one test its own output before it reports back — a local loss function, one per subagent, scoped to its slice of the problem. Then an orchestrator agent merges everything and runs one more integration pass over the merged result, because a pile of locally-passing pieces isn’t automatically a working whole. Parallelize everything you can. Just make sure someone re-tests the whole thing once it’s back together.

That last clause is the part I skipped the first few times, and paid for. Individually-tested subagent output can still merge into something broken — a shared file gets touched twice, an interface drifts between two branches of work that never talked to each other — and the only way to catch that is a final pass that treats the merged result as a fresh unknown, not a sum of already-verified parts.

Where this actually earns its keep is in how much you can hand off once the goal is scoped this precisely. A few weeks ago I gave an agent a real-time voice chat feature to build — proximity-based audio, so voices fade as avatars drift apart — framed as “research the approach, then implement it, and don’t stop until it works end to end.” I walked away for dinner. Not a check-in, not a glance at the terminal — hours. When I came back, there was working progress: a real approach researched, implemented, and mostly functioning, rather than a pile of half-finished scaffolding waiting on me to unblock it.

What changed wasn’t the model. It was where I spent my attention — upfront, on making the goal checkable, instead of mid-flight, supervising every step. Once the target is well-defined, closing the gap becomes the agent’s problem, the same way a training run doesn’t need someone watching every epoch tick by. My job shifted from babysitting the process to scoping the goal well enough that babysitting stopped being the bottleneck. Set the goal before dinner. Check the diff after.

I don’t think this always works — some problems genuinely resist a clean metric, and I’ve had plenty of sessions since where I couldn’t articulate a loss function crisply enough and paid for it in aimless iteration, agents cheerfully producing motion without progress. But when I can name the number, the rest mostly takes care of itself, which is a strange thing to have learned from software, and a stranger thing still to have first learned from watching translation bots wait on each other in a room that never quite got going.

Permalink →

I ran into something last week that unsettled me more than expected. I was testing whether a model could translate a passage using only its own reasoning, so I hid the source text behind a simple substitution cipher before handing it over — the idea being that if the model could still produce a faithful translation, it would have to be doing something closer to genuine cross-lingual reasoning than pattern completion. It decrypted the cipher and recited the verse anyway. Correctly. Immediately. The Bible is so memorized by frontier models that hiding the source text doesn’t work — the model just decrypts and recites it anyway.

That’s stranger than it first sounds. This wasn’t a model translating an encrypted string. It was a model recognizing that a scrambled string of characters was shaped like a passage it already had memorized verbatim, discarding the cipher as a distraction, and reciting from memory. That’s a different capability than translation, and it means a huge chunk of what looks like “the model translated this well” for biblical text is really “the model already knew this text in every language I asked for.” You can’t use Scripture to test whether a model can translate, because for Scripture specifically, the model usually doesn’t need to.

This is a genuine methodological problem, not just a fun fact. If I want to evaluate — or train — a system’s ability to reason from meaning to meaning rather than reciting a memorized target string, I need source material the model hasn’t swallowed whole. Obfuscating the surface form doesn’t work, as I just found out the hard way. What might actually work is changing what the “source” is in the first place.

Acting the scene instead of laundering the words

There’s a practice-level version of this same insight that I’ve been leaning on for a while, mostly with human translators and increasingly as an instruction to models: stop translating the words. Act the scene. Then say what just happened in your own language.

The reasoning is the same as in prioritizing semantics over structures: a word is not a translation unit, it’s a residue left behind by a meaning that already happened. Translating the residue is really just copying with extra steps — the failure mode the cipher experiment exposed at scale. A model (or a person) staring at a string of tokens finds the shortest path to an output resembling those tokens, and if it’s already memorized the “right answer,” the shortest path is recall, not comprehension. Acting the scene forces a detour around that shortcut. You have to know who is speaking, to whom, what they want, what’s at stake, before you’re allowed to say anything at all. Only then do you say what happened, in whatever language you’re working in.

The more rigorous version: don’t feed it the words at all

The practice-level fix is good discipline, but discipline is not architecture, and I’d rather not depend on a model or a translator “resisting the urge” to recall a memorized string. The more rigorous fix, and the one I actually want to build, is to stop handing the model literal source text as the thing to be translated at all.

Instead, represent the passage as a language-agnostic semantic description: pericopes broken down into nested units of who is speaking, to whom, and what is being communicated — speech acts nested inside speech acts, the way narrative and dialogue actually nest inside each other. This is the same move I described in the case for dynamic equivalence alignments — form → meaning → form instead of form → form — pushed one step further upstream. Instead of asking a model to align a translation back to source words after the fact, you never give it the source words as the object to reproduce in the first place. Its job becomes representing the meaning of a discourse unit faithfully, not pattern-matching against a corpus it already has memorized down to the verse numbers. If there’s no recognizable surface string to recite, “recite the memorized answer” stops being a viable shortcut, and the model actually has to do the thing you’re asking it to do. This is really an extension of the point I made in beyond word alignments: the word was never the right unit, and now I have a concrete reason — memorization contamination — to stop treating it as one even operationally.

Where this is honestly still rough

I don’t want to oversell this, because I’ve already tried a related methodology and it only sort of worked. I built a multimodal process I’ve been calling Familiarize → Internalize → Articulate — acting out a passage, drawing the scene, studying the characters and key terms — before ever producing a rendering, as a more embodied version of the “act the scene” instinct above. In practice it can shunt between layers of context in ways that are only sometimes helpful; moving between acting, drawing, and terminology study doesn’t reliably converge on a clearer semantic representation, it sometimes just adds noise. And the supporting resources for it — the character studies, the term glossaries, the scaffolding that’s supposed to make internalization tractable rather than vibes-based — are still unfinished.

So this isn’t a solved problem, it’s a diagnosis with a promising direction attached. The cipher experiment told me the failure mode is real and larger than I assumed. The semantic-description architecture is my best current guess at a fix that doesn’t rely on willpower. Whether nested speaker/addressee/content units are actually the right granularity, and whether a model can be made to represent meaning at that level reliably, is still very much open.

Permalink →

I Don't Write Code Anymore

2026-07-01 · 5 min read

I still open editors. I still read diffs, more carefully than I ever read my own code when I was the one typing it. But somewhere in the last year the actual verb changed underneath me. I don’t write code anymore. I make sure it works.

The shift didn’t happen all at once. It started with Copilot doing the boring parts — closing brackets, guessing the next line of a for-loop I’d already half-written in my head. That felt like a faster typist next to me, not a different kind of work. Then it was whole functions, whole files, whole features described in a paragraph and returned as a PR. At some point I noticed I was spending almost all of my time reading rather than writing, and that the reading was the actual job now, not a chore attached to it.

Here’s the part that took longer to admit: delegation only works if I understand the requirements and constraints well enough to notice when the output is wrong. Easy to skip in practice, especially when the code compiles, the tests pass, and the diff looks plausible. Plausible is not correct. If I’m fuzzy on what a function is actually supposed to guarantee — the edge cases, the invariants, the thing a teammate would ask about in review — I’m not verifying anything. I’m rubber-stamping a guess.

And the uncomfortable symmetry is: to the extent you’re confused or missing context, you’ll be like an AI model hallucinating. Not metaphorically. The same failure mode — filling a gap with something fluent and wrong because stopping to say “I don’t know” felt worse than producing an answer — applies to me approving a PR I only half understood as much as it applies to the model that wrote it. The model hallucinates when its context window is missing the constraint it needed. I hallucinate approval when my mental model is missing it too. Verification is only as good as the understanding behind it, and understanding doesn’t arrive for free just because you stopped typing.

So the job, as I’d have described it a week ago, became: stay close enough to the requirements to be a reliable check, not a rubber stamp. Read the code like I’m going to be paged about it at 2am, because I am. That felt like a tidy place to land — the kind of clean insight that makes a good closing paragraph.

It did not stay tidy.

Update, one week later: I want to complicate what I wrote above, because the version of “verification” I described a week ago already looks quaint.

I don’t write code directly anymore, full stop. What I actually do most days: watch a user demo something that’s broken, or describe it to me, and transcribe that into something an agent can act on. The agent extracts the tickets, works through them, opens PRs. I check whether the fix actually fixes the thing the user showed me. That’s most of my week now — not “review code an AI drafted” so much as “run a small verification desk for a coworker I never see write anything.”

The part I didn’t see coming: I no longer know how to onboard a human contributor into this. Explaining a task clearly enough for a person to pick it up — writing the ticket, answering follow-up questions, reviewing their PR style, waiting on their PR — is often just slower than having the agent do it end to end. Not slightly slower. Slower in a way that makes me hesitate before I even open the “assign to teammate” dropdown. I’m like, can I say, “Claude, don’t work on all the tickets, leave some for the people?” That doesn’t make any sense.

I can gesture at a reframe: maybe human contribution has to move up a level, toward defining problems well rather than solving them — deciding which demo is worth turning into a ticket, deciding what “fixed” even means for something ambiguous, holding the judgment calls the agent can’t make on its own. Probably true. It’s also easy to say and hard to build a team around, and I haven’t built it. I don’t have a good answer for what a junior engineer’s first month looks like when the fastest path from “user is annoyed” to “verified fix” doesn’t reliably pass through a human writing code anywhere in the middle.

I keep circling the same tension from the top of this post, one layer down. Verification only works if you understand the requirements — but if defining the problem well is now the whole job, I’m not sure verification was ever a separate skill from understanding, and I’m not sure I’ve figured out how to teach the second one to someone else. I don’t have a tidy close for this. It’s genuinely unresolved, and I’d rather say that than dress the reframe above up as a solution instead of a name for the gap.

This rhymes with the crowd-sourcing-plus-AI shape I sketched in The Path Forward — human judgment and AI throughput each doing the part they’re actually good at. And Translators’ Notes carries the same question in a different outfit: at what point does “reviewing AI output” quietly become the whole job, for a translator or an engineer, and what happens to everyone whose job used to be the part before that.

Permalink →

I’ve spent most of my career assuming open source is a default good — you build something, you put the code out, the community makes it better, everyone wins. I still believe that most of the time. But two things have been nagging at me lately, and I don’t think I can resolve them cleanly, so I’m writing them down instead.

Argument one: you’re publishing a map

The classic security argument for open source is “many eyes make bugs shallow” — enough people read the code, someone spots the flaw before an attacker does. That argument was always a little optimistic (plenty of famous vulnerabilities sat in plain sight in popular open-source libraries for years before anyone noticed), but it’s gotten shakier now that “reading the code” is something an AI agent can do at scale, continuously, for free, on every public repo it can find.

An attacker no longer has to be a person who understands your codebase. They can point an agent at your repo and ask it to reason about your auth flow, your input validation, your dependency graph, and your deploy config, and get back a prioritized list of soft spots — the same kind of architectural reasoning a senior engineer would do on a code review, except it scales to every repo on GitHub simultaneously and never gets bored. Open-sourcing your code doesn’t just risk a vulnerability being found; it hands over the reconnaissance step for free. As I’ve put it to myself while deciding what to open up: it just hands an AI a map of where you’re weak.

That’s part of why the auth and user-data module of one of my own projects has stayed closed-source, even from early on, well before “AI agent reads your repo” was a mainstream worry. The rest of the codebase — the interesting, differentiated parts — I’ve been comfortable sharing. But the module that decides who gets in and what happens to people’s data felt like a bad place to hand out a floor plan, and I still think that instinct was right, even if the reasoning behind it (attackers get smarter tools) has changed since I first had it.

Argument two: code without a business model dies anyway

The second argument is less about attackers and more about attrition. Plenty of genuinely good, well-maintained open-source projects still fold — not because the code was bad or the maintainers stopped caring, but because nothing was paying for the maintainers’ time. Goodwill is real, but it’s not a renewable resource at the rate a serious project needs it. Sooner or later the project dies anyway without a business model behind it, openness or no openness.

If that’s true, the security argument above is almost moot for a lot of projects — the vulnerability never gets exploited because the maintainers already walked away and the repo is quietly rotting in an unmaintained state, which is arguably worse than either alternative.

The tension I can’t fully resolve

Here’s what makes this uncomfortable for me specifically: I’ve argued at length that CC0 — zero restrictions, no strings attached — is the right license for openly licensed Bible texts, precisely because openness removes friction, invites local ownership, and lets communities build sustainably on top of a shared resource. I still believe that. I’ve also written about wanting Bible translation to move toward permissionless, decentralized tooling built and extended by the communities using it, not gatekept by a central authority.

So why would I turn around and be cagier about code than I am about content? Part of the answer might just be that content and code fail differently. A Bible text doesn’t have an attack surface. Nobody can use a translated verse to compromise a server or exfiltrate user data. The “many eyes” argument for content is basically just quality and reach — more translators, more dialects, more reviewers — with none of the security downside, because there’s no exploit sitting in a psalm. Code is different: openness and attack surface aren’t separable the way openness and translation quality are. Maybe that’s the whole answer and I’m overthinking it. Or maybe it’s a rationalization I’ve backed into because I already had a closed-source module and needed a reason.

I don’t have a tidy rule here, and I’m suspicious of anyone who does. If you’ve found a decision framework that actually holds up — something more principled than “vibes about which module feels sensitive” — I’d like to hear it, because right now I’m mostly running on instinct and a lingering unease about what an agent could do with a full read of my repo.

Permalink →

Somewhere around 2010, deep into a master’s degree in Ancient Greek linguistics, I was trying to build word2vec models over a Greek corpus using Gensim, which was — and largely still is — the workhorse library for this kind of thing. Gensim’s whole pitch was memory efficiency: instead of loading a corpus into RAM and training a model on the full thing in one pass, you streamed documents through it one at a time. The model updated incrementally as the data arrived, rather than requiring the entire corpus to exist in memory simultaneously before training could start.

At the time this felt like a plumbing detail, not an idea. But it planted a question I didn’t know I was carrying around for the next decade and a half: why train a model? Why don’t we figure out a streaming approach where we just give it the data it needs on the fly? Ancient Greek is a low-resource language by any modern standard — there wasn’t enough data to justify pretraining a dedicated model in the first place, and streaming was mostly a practical concession to a laptop that couldn’t hold the corpus in memory. But the concession turned out to be more interesting than the workaround it was standing in for.

That question is, more or less, how the translation tool I’ve been building handles languages it has never seen. It doesn’t train a per-language model. There’s no fine-tuning step, no “we support 40 languages, request the 41st.” Instead, at prediction time, it streams relevant translated examples to the model as context and asks it to produce a translation using those examples as its only local evidence for how the language behaves. The model isn’t learning the language in any durable sense; it’s being handed exactly the data it needs, on the fly, for this one prediction, and then that context evaporates. This is the same move as Gensim’s streaming corpus reader, just moved from “how do I fit training data in memory” to “how do I give a frozen model enough signal to be useful in a language it’s never encountered.”

The practical difference is enormous. Training or fine-tuning a model per language — even a small one — is the kind of thing that will bog your computer down for hours and then crash, especially if you’re iterating on ultra-low-resource languages where you don’t have the corpus size to justify the cost in the first place. Streaming relevant examples at inference time is orders of magnitude faster, because you’ve swapped a training job for a retrieval-and-context-assembly step. It’s the same logic I was chasing in Minimal Translation Memory for AI Agents — find the smallest, most generalizable set of examples that covers the most ground, and hand the model only that, rather than everything you have.

I want to be honest about where this breaks down, though, because it’s a real limitation and not a rounding error. The streaming approach works today because a human is validating each prediction live — approving, correcting, or rejecting the model’s output as it’s generated. That human-in-the-loop step is quietly doing a lot of work: it’s the error-correction mechanism that a trained model would otherwise have baked in through gradient descent over many examples. Remove the human, and you no longer have a guarantee that streamed context is sufficient on its own to produce a reliable translation. Whether streaming-plus-retrieval can substitute for training without a validator in the loop is, as far as I can tell, an open research problem — not a solved one I’m just being modest about. I’d put it in the same bucket as the clustering evaluation problem I never resolved in Contextual Vectors for Lexical Meaning: a piece I know is missing, not a piece I’ve quietly decided doesn’t matter.

What convinces me this is a real pattern, rather than a translation-specific hack I’ve talked myself into, is that I’ve watched the identical lesson surface somewhere completely unrelated. Years ago, I was on the other side of a job interview where a candidate was asked to process seventy million XML records. The naive approach — load everything, validate everything — didn’t just run slowly, it fell over. The fix was to stream: validate records as they arrived, discard what you didn’t need to keep, never hold the whole seventy million in memory at once. It’s the same shape as few-shot prompting, just wearing different clothes: you don’t dump your entire knowledge base into a context window and hope the model sorts it out, you stream the handful of examples that are actually relevant to this prediction and let the rest stay where it lives.

That’s one of maybe four lessons a developer has to learn, and I seem to have learned it twice, fifteen years apart, in two fields that have nothing to do with each other. I don’t think that’s a coincidence so much as a sign that “stream the relevant slice instead of loading the whole thing” is one of those ideas that’s basically fractal — it shows up at the level of a corpus reader, a translation model, an XML validator, and a prompt, and it’s probably going to keep showing up wherever the next constraint is memory, time, or data scarcity.

Permalink →

Memorize Anything with AI Music

2024-11-19 · 7 min read

#ai #music #pedagogy

The Problem

You want to memorize a list of vocabulary items.

This is both boring and hard, and it’s not how you learned English, so let’s use AI to make it fun and easy.

I was inspired in this experiment by a true mnemonic masterpiece I heard over a decade ago. “Luw Song” by Clint Kirby. Learning Greek verb endings has never been easier since this pioneering work. He doesn’t even pronounce the endings consistently, but that makes it all the more memorable and hysterical. Thank you Clint!

In this post, I’ll show you how to use AI to create a fun, musical mnemonic to memorize anything.

Prompting ChatGPT for musical mnemonic excellence

Okay let's make a dr seuss like zany story using the vocabulary items from this list. Make it rhyme where possible (the class will be singing it). It's good to make it odd, but let's try to have some kind of narrative coherence to it. Don't introduce a lot of extra content, and be sure to get the actual glosses in there from the vocab list (be specific). I know you can do this. 
 
Here's the list: [insert list of words here you want to memorize]
 
ἀποκρίνομαι, ἀπεκρινάμην​​​I answer
δεῖ (3rd pers. sg.; impf ἐδει)​​​It is necessary
δύναμαι, ἡδυνήθην (impf. ἐδυνάμην, ἠδυνάμην)​I am able, am powerful
ἔρχομαι, ἦλθον​​​​​I come, go
νύξ, νυκτός, ἡ​​​​​night
ὅστις, ἥτις, ὅτι​​​​​whoever, whichever, whatever
πορεύομαι, ἐπορεύθην​​​​I go, proceed; live
συνάγω, συνήγαγον​​​​I gather together, bring together; lead
τόπος, -ου, ὁ​​​​​place; location
ὡς​​​​​​as, like; that; approximately; when, after

The first result was just too long for me I thought. I thought repetition might be useful (though I’m not sure it’s better than long and story-like!), so I asked for a shorter version.

That's great. Let's make it much more compact. Go for concise, and go for accurate glosses (OTI means 'that' or 'because', so "Whatever—ὅτι—may come, we’re now bold and free," could be confusing), etc.

Great. I got this:

Got it! Here's a more concise and gloss-accurate version of the rhyming story:

The Night of the Wandering Νύξ

In a τόπος, a place, as the νύξ, night, fell,
I heard a voice answer, ἀποκρίνομαι, well.
"It is δεῖ, necessary," the voice said with cheer,
"To πορεύομαι, go, and leave without fear."

"I δύναμαι, I’m able!" I shouted, then ran,
And ἦλθον, I came, to a marvelous plan.
"Gather, συνάγω!" I called to the crowd,
And off we all went, so lively and loud.

"Whoever—ὅστις—goes will find something bright,
And as—ὡς—the stars, we’ll light up the night!"
So off we proceeded, our hearts burning strong,
In that τόπος of νύξ, where we all belong.

Now we need to get it into a song.

Since I had heard Suno was releasing its v4 model for usage, I thought I’d give it a shot. I only had the v3.5 model, but it worked well and was free.

In the lyrics field, I pasted the song lyrics above, but with one slight change: I didn’t want it to pronounce the Greek properly (we’re using Erasmian pronunciation, not Modern Greek). So I asked ChatGPT to transliterate the Greek terms into the closest Latin letters following the erasmian pronunciation. A couple tweaks later, I got this:

In a topos, a place, as the nux, night, fell,
I heard a voice answer, apokrinomai, well.
“It is ‘day’, necessary,” the voice said with cheer,
“To poru-oh-my, go, and leave without fear.”

“I dunamai, I’m able! I shouted, then ran,
And elthon, I came, to a marvelous plan.
“Gather, sunago!” I called to the crowd,
And off we all went, so lively and loud.

“Whoever—hostis—goes will find something bright,
And as—hoas—the stars, we’ll light up the night!”
So off we proceeded, our hearts burning strong,
In that topos of nux, where we all belong.

For the Style of Music field, I entered:

Anthem style. Wholesome. Clear vocals.

The title was “The Night of the Wandering Νύξ”.

I like the result. Here’s the link.

Going Multimodal

Then I thought, it’s really the blending of text and music that makes Clint’s song so effective. What if I could use images too?

Back to ChatGPT:

I want to generate some images to go along with this. Please describe the prompts we *would* use for each image (but don't create an image yet). Be sure to explicitly include the Greek vocab items and glosses that need to be in each image.

It gave me these prompts:

Here are the prompts for each image, ensuring the Greek vocab items and their glosses are explicitly included:

Image 1: “The Topos at Night”
A dark and mysterious place (“τόπος” with the gloss “place”) under a starry sky, with a glowing moon representing “νύξ” (night). In the foreground, a signpost reads “τόπος - place” and “νύξ - night” in Greek and English, while faint whispers seem to emanate from the darkness, symbolizing an answering voice.

Image 2: “The Command to Go”
A shimmering, ghostly figure speaking to a traveler, saying, “ἀποκρίνομαι - I answer” and “δεῖ - it is necessary.” The words are written in glowing letters in the air. The traveler looks determined, preparing to embark on a journey, holding a lantern to symbolize readiness.

Image 3: “I Am Able!”
The traveler stands tall and confident, shouting, “δύναμαι - I am able!” against a backdrop of winding paths. Greek and English versions of “δύναμαι - I am able” glow above the traveler, emphasizing their determination.

Image 4: “The Gathering Crowd”
The traveler is joined by a diverse group of companions, all smiling and excited as they prepare to journey together. Overhead, glowing text reads “συνάγω - I gather together.” A small sign nearby includes “τόπος - place” in Greek and English to remind viewers of the setting.

Image 5: “Whoever Dares”
A whimsical scene of the group walking under a glowing night sky filled with constellations forming the Greek word “ὅστις - whoever.” The companions’ faces are full of wonder, and a starry trail leads them forward. The words “ὅστις - whoever” and “ὡς - as, like” are floating in the sky, representing discovery and imagination.

Image 6: “The Journey’s End”
The companions stand together triumphantly on a hilltop, overlooking a radiant sunrise. The words “πορεύομαι - I go, proceed” and “ἦλθον - I came, I went” appear as banners in the scene, symbolizing the completion of their journey. The glowing night fades, but a signpost still shows “τόπος - place” and “νύξ - night” as a callback to where they started.

These prompts are designed to highlight the Greek vocabulary visually and conceptually, providing clear and memorable learning aids. Would you like to proceed with creating any of these?

Perfect. I asked it to generate the images one by one.

Since the text wasn’t amazing (in the future this part of the post will be completely irrelevant as text generation, even cross-linguistically, becomes perfect), I decided to use iMovie to stitch it all together.

imovie.png

Pasting the text into the “titles” in iMovie was annoying at first. I couldn’t ‘paste without styles’, so I wound up creating a Word doc, setting up the fonts, sizing, colours, etc., and then pasting from there.

formatting.png

Curious about the result? Here’s the final video, The Night of the Wandering Νύξ.

Here’s a link to the complete ChatGPT conversation.

Can’t wait to see what other make!

Permalink →

Introduction

The world of Bible translation is on the brink of a paradigm shift. For decades, the process has been centralized, controlled by overseas agencies and individual missionaries. But a new model is emerging—one that’s decentralized, community-driven, and powered by AI.

The Shift Towards Decentralization

This shift towards “permissionless translation at the edge” is not just a possibility; it’s already happening. While many in the Bible translation community are debating how to introduce AI tools, the reality is that people in communities large and small are already running AI models locally on their machines.

Challenges and Opportunities

The traditional paradigm values careful oversight and quality control. It’s understandable, then, that the initial response to AI in translation is often to hit the pause button and implement controls. But this approach risks missing the opportunity that’s unfolding before us.

AI isn’t just a tool to be integrated into existing processes. It’s a catalyst for a fundamental reimagining of how translation happens. It empowers local communities to take ownership of translation, allows for rapid iteration and feedback, and enables translations that are more natural and culturally nuanced.

Enhancing Human Translators

Because AI cannot translate into a language a human has never translated before, the new paradigm doesn’t replace initial human translators—it enhances their capabilities. It turns translation quality into a social process, leveraging community consensus for accuracy. It embraces cultural nuances and local idioms in ways that remote oversight never could.

The Role of Data

The key to unlocking this potential? Data. (See Data is the bottleneck for more on this.) By giving communities tools to document their languages, we provide them with the raw material that AI needs to work. This could lead to rapid transformations in oral-only communities and increased demand for written scriptures.

Embracing the Shift

So, what can we do to embrace this shift?

  1. Recognize that AI in translation isn’t coming—it’s here. We need to engage with it now.
  2. Invest in tools that empower local communities to document their languages and drive their own translation processes.
  3. Shift our focus from control to empowerment. How can we equip communities rather than oversee them?
  4. Prepare for a multi-modal future where text, audio, and visual translations coexist and complement each other.

Conclusion

The future of Bible translation is permissionless, decentralized, and AI-enhanced. It’s a future where every community has the tools to engage with Scripture in their heart language. The question isn’t whether this shift will happen, but how quickly we’ll adapt to it. The revolution in Bible translation is here—are we ready to embrace it?

Last week I presented at the Generating Wisdom Conference at the Museum of the Bible in Washington, D.C. on the topic of “Human Centric AI” and the paradigm shift happening in Bible translation.

An online conference attendee later emailed and summarized the approach described in some of my points with the phrase “Permissionless Translation at the Edge.” I thought this was an excellent summary of the approach, so I’m using it as the title of this post (thanks Greg Outlaw!).

Permalink →

#ai #translation

I’m excited about the potential of OpenAI’s new GPT-4o mini for our Translator’s Copilot project! Here’s why:

Cost-Efficiency

It’s more than 60% cheaper than GPT-3.5 Turbo. This change means zero-drafting with AI can be faster and cheaper.

Improved Capabilities

  • Better handling of non-English text like the larger 4o model (which we have been using extensively)
  • Outperforms GPT-3.5 Turbo on various benchmarks
  • 128K token context window (entire chapters at once!)
  • Multimodal support (future audio possibilities?)

Real-Time Interaction

Low latency could enable faster, more fluid workflows for our translators.

Integration Potential

Strong function calling performance could help us integrate external resources like concordances more seamlessly.

Cautious Optimism

While exciting, we need to approach implementation carefully. Bible translation requires nuance and cultural sensitivity.

Next Steps

  1. Testing on biblical texts in low-resource languages
  2. Refine prompts for smaller model if needed
  3. Plan integration into our existing workflow for Codex
  4. Analyze costs vs. potential improvements

GPT-4o mini could accelerate our mission to make God’s Word accessible to every language community.

What do you think about its potential impact on Bible translation?

Permalink →

#translation #ai

The landscape of Bible translation is rapidly evolving with AI advancements. Our role must shift accordingly. Tech giants are developing powerful translation tools, but they lack one crucial element: data for low-resource languages.

AI’s Potential in Translation

AI can now create accurate, creative Bible translations in major languages within minutes. For low-resource languages, the technology is ready - it just needs data.

Our Unique Contribution

Our mission-driven focus on low-resource languages positions us uniquely to provide the missing piece: language data.

The Real Challenge

The primary obstacle to universal Bible access is no longer translation itself, but gathering sufficient language data for AI translation into each language. Our task is to collect and publish this data in standard, open AI repositories.

A New Direction

To maximize our impact, we must:

  1. Prioritize data collection for low-resource languages
  2. Standardize data formats for AI compatibility (think JSON, not USFM)
  3. Develop user-friendly, offline-first language data collection tools
  4. Streamline our data infrastructure for efficient gathering and sharing (more data, less decisions about data)

The Path Forward

By focusing on our role as data collectors and curators, we can accelerate Bible translation in unprecedented ways. If we dedicate our efforts to data collection now, we’ll enable AI models to translate the Bible into every language faster than ever imagined.

This shift in focus would allow us to leverage our unique strengths and the power of AI, bringing us closer to our goal of making God’s Word accessible to all.

Permalink →

#translation #ai #localization

Please see the following slide deck for a description of the process and potential benefits of using LLMs to generate and localize translator’s notes for the rest of the Bible.

Permalink →

The future of Bible translation increasingly involves the use of crowd-sourcing, Large Language Models (LLMs), and AI to enhance accuracy and efficiency. Here’s how these elements converge to offer a practical solution:

Crowd-sourcing: This approach taps into our only available pool of knowledge for the vast majority of remaining languages, making it possible to translate the Bible into every language. By leveraging the collective wisdom of native speakers - though not necessarily ‘directly’ as translators of the Bible itself, we can ensure that translations are accurate and culturally relevant.

User Interface: Translators interact with simple, customized HTML forms developed by LLMs. These interfaces are intuitive and hide the complexity of the technology beneath, focusing on user needs without added complexity.

Behind the Scenes: Sophisticated seq2seq and open-source agentive models work in tandem with human input. These models augment human translators’ efforts by leveraging input from wherever we can get it. These AI tools augment, improve, and speed up the translation process by generating additional content from what has been provided via crowd-sourcing.

The integration of these technologies is not about flashy innovation but about practical improvements in the translation process. By leveraging these tools, we aim to build an ecosystem that can translate the Bible into every language in the world, made possible by both human and AI-powered machine translation.

Permalink →

Occam's Razor and Bible Translation

2024-05-08 · 3 min read

#translation

Question

Is there a simpler approach to Bible translation?

Tesla’s Application of Occam’s Razor

Tesla faced a massive, patchwork C++ codebase for identifying labelled items in video input for full self-driving. Progress was slow, and scalability for the last 1% of edge cases seemed unattainable.

Then they applied Occam’s razor and shifted to training a model with extensive 360-degree video input and controls output (steering, brake, gas). This approach proved significantly better, improving 5x-10x each month as more video data was uploaded from drivers.

See discussion at 3:42 in this video. Thanks to Birch Champeon for sharing.

Applying Occam’s Razor to Bible Translation

I propose a similar shift in Bible translation.

Currently, we use large legacy apps and newer apps with numerous features and checks. With LLMs and agent-based translation, we can simplify the task.

Starting from first principles: what are the inputs and outputs?

If we move from Greek/Hebrew source texts to a semantic representation, semantics become inputs. A model could then apply these semantics to the collocation and colligation patterns in the target language, possibly by reranking outputs with context awareness.

Like Tesla, we need to crowdsource data to map semantics to target language expressions. One method could involve eliciting translations of semantic units from Greek/Hebrew, displayed in aligned gateway languages familiar to target language speakers.

Synthesizing Crowdsourced Data

However the data is elicited, we need to synthesize crowdsourced data into a coherent whole, i.e., complete, versioned, public domain Bible translations.

Adapting swarm intelligence to Bible translation could be the solution. This would involve numerous agents, each translating small, semantically coherent text units. These translations would be combined and refined by a central agent to ensure consistency and coherence across the translation.

This method would allow a more flexible and scalable translation process, distributing work among numerous agents, each responsible for a manageable portion of the text. This would enable faster, more efficient translation, and greater adaptability to local community needs and preferences.

Every approach has risks and trade-offs, but the prospects of applying Occam’s razor to Bible translation are exciting and promising.

Permalink →

#translation #ai

Vision and Purpose

The Blank Slate Translation Initiative aims to fundamentally reshape Bible translation for the AI age. We envision a future where every community, regardless of size or location, has access to the Bible in their own language.

Our Approach

Our approach leverages emerging AI technologies to empower local communities, potentially reducing translation time and costs dramatically while increasing ownership. Key aspects include:

  1. Iterative process: Continuous improvement through rapid feedback cycles
  2. Decentralized tools: Simple, accessible apps for widespread participation
  3. Crowdsourcing: Enabling all language speakers to contribute
  4. AI integration: Synthesizing diverse inputs into coherent translations
  5. Community-driven: Serving locally-initiated translation projects

Paradigm Shift

By combining AI-powered tools with local expertise, we’re not just enhancing existing methods; we’re exploring new paradigms that could maximize output from minimal input. This strategy positions us to adapt continually to advancing AI capabilities, potentially transforming community-based translation as profoundly as automobiles changed transportation.

Join the Initiative

We invite forward-thinking individuals and organizations to join us in this groundbreaking initiative. Together, we can reimagine Bible translation, ensuring no community is left without access to God’s Word in their heart language.

Permalink →

#translation #ai

One of the greatest hurdles to rapidly producing Bible translations is a misconception about what makes a quality translation. Everyone recognizes the importance of translation quality, but it is rare that someone can explicitly state how to measure quality or what level of quality is good enough for a first draft. It is likely that the more people you ask, the wider the range of answers you will receive. This is a problem because it is difficult to make progress on a project when the goal is not clearly defined.

In order to best leverage AI technology for drafting translations, it is necessary to be explicit about translation quality. AI works best when you can measure its results, and its translation results are no different.

With that in mind, I believe that translation quality is not determined by theological accuracy. The text of the Bible is theologically accurate, and so theological accuracy is a side-effect of translation quality.

Translation quality is determined by approximate semantic analogy.

  • Approximate means quality is not a binary value, but rather a cline which extends from worse to better quality.
  • Semantic means quality is a matter of meaning, not form
  • Analogy means that meanings may not be the same between cultures, but they may occupy a similar space in a coherent network of culturally bound meanings constrained by contextual factors in both the context of production and contexts of reception. A quality translation attempts to find better and better analogous meanings across languages.

There are three implications of framing quality in these terms.

  1. Iterative Quality is not a milestone, but an iterative process. Like a tree, translation quality may grow indefinitely and its limits are only imposed by the environment. As the environment changes, even a very high-quality translation may need to be updated.
  2. Indefinite Quality is non-definitive and non-final. There is no point at which one may say a tree is “finished” growing (though it may be big enough for your yard!). Translation involves coordinating between two moving targets, because languages are in a constant state of gradual change, and our understanding of the Greek and Hebrew texts is also in need of continuous re-evaluation as our own languages shift and our descriptions become inadequate.
  3. Uncontrollable One of the core values underlying the established process is control. The desire for tightly controlling the translation process comes from a righteous regard for the living and enduring revelation of God that we have in the very words of the Bible. For all this, it is a paternalistic attitude that imputes undue spiritual immaturity on believers around the world. It is also based on a misconception that we may know in advance the nature of the theological challenges that those believers will face as they read and wrestle with God’s word. The only preparation for dealing with bad theology in the future is the guidance of the Holy Spirit and a knowledge of church history.

God’s word has been given to us in natural human language. If our goal is to find the most approximate semantic analogies for its meaning, we will find that the theological accuracy of the resulting translations improves as a direct consequence. Perfection is often the enemy of good, and we cannot let the fear of imperfection paralyze us. While translation quality is essential, we must also simultaneously put ourselves in the place of those who have no Bible at all and recognize our insufficiency to translate with perfection.

Permalink →

#language #learning

Learning a new language can be a daunting task, but what if we could make it more interactive and fun? What if we could visualize the sentences we learn, not just in our minds, but in a more tangible form?

Horse on Table

In a recent conversation, a friend mentioned they were learning Hebrew and could recognize phrases like “the horse is on the table”. This got me thinking - why not throw these sentences into a stable diffusion model and generate some graphics? These graphics could then be used as flashcards, adding a visual element to the language learning process.

Stable diffusion models are a powerful tool for generating images from text. They take a text input and generate a corresponding image, providing a visual representation of the text. This can be particularly useful for language learning, as it provides a visual context for the phrases and sentences you’re learning.

I recommend trying out ClipDrop’s Stable Diffusion Turbo. As you type into the text box, it generates images in real-time, providing an interactive and engaging way to learn and visualize new phrases.

The quality is super low by the meteorically rising standards of the AI art world, but it’s still a fun way to learn a new language.

Permalink →

Few-shot Translation Evaluation

2023-12-22 · 2 min read

#translation #ai

In the context of a translation project, where we aim to utilize only the resources at hand, let’s consider a simplified approach to the evaluation stage. This approach would involve the following steps:

  1. Start by taking the draft translation and identify the translation pairs that are most similar to the paired prediction.
  2. Evaluate the draft translation for any potential misuse of words.
    1. One possible method could be to use a rules-based matcher that identifies any tokens in the source+prediction pair that only occur in EITHER the source OR the target in any of the similar examples.
    2. It could also be beneficial to examine whether any words seem to be mistranslated based on the gold standard examples.
    3. To aid this process, aligning these examples by phonetics, orthography, and apparent semantic similarities could be helpful.
  3. Once the evaluation is complete, pass the task back to the translation bot, providing special notes about any words that appear to be mistranslated.

In essence, the process can be summarized as: [ most similar examples ] —> [ prediction ] —> [ most similar examples ]

The goal is to identify the most similar examples to the prediction, and then use those examples to evaluate the prediction. This process can be repeated iteratively, with the bot learning from the evaluation and then generating a new prediction and a new set of examples that will help the initial bot improve its output.

Permalink →

Grammar Constraints on LLMs

2023-12-22 · 5 min read

#translation #ai

I’ve been thinking about how to improve LLM performance for Bible translation, especially for low-resource languages. The current approaches aren’t great - LLMs struggle with the nuances of these languages and often produce poor translations. This is a big problem since we need translations that respect both cultural and linguistic aspects.

Combining Old and New Approaches

Rule-Based Grammars + Context-Aware LLMs

The first thing I tried was combining traditional rule-based grammars with modern LLMs. Rule-based grammars are pretty rigid on their own, but they give us a solid structure to work with. When you mix this with an LLM’s ability to understand context, you get something much more useful. The grammar provides guardrails while the LLM handles the nuanced language understanding.

Using LLMs to Build Grammars

Here’s an interesting twist - we can actually use LLMs to help write grammars for low-resource languages. Instead of just using them as translators, we’re using them to build the linguistic frameworks we need. I think this could be a game-changer for working with lesser-known languages.

How It All Works Together

The cool part is seeing how these old-school grammar rules work with modern LLM capabilities. What used to be seen as outdated becomes really powerful when combined with the way LLMs process context and meaning.

Grammar-Constrained Decoding

I’ve been looking into using context-free grammars (CFGs) like GBNF to control LLM outputs. This approach, called grammar-constrained decoding (GCD), works particularly well for structured content.

What does this actually look like? The best example I’ve come across so far is the GBNF grammar approach found in the llama.cpp library. They give the following example of a formal ‘grammar’ for specifying that the only outputs that an LLM can give must be Japanese characters:

# A probably incorrect grammar for Japanese
root ::= jp-char+ ([ \t\n] jp-char+)*
jp-char ::= hiragana | katakana | punctuation | cjk
hiragana ::= [ぁ-ゟ]
katakana ::= [ァ-ヿ]
punctuation ::= [、-〾]
cjk ::= [一-鿿]

Benefits and Challenges

Research has revealed several key advantages of using grammar constraints:

  1. Improved Accuracy: Studies show dramatically reduced error rates when using grammar-based constraints, especially for longer sequences
  2. Efficient Learning: LLMs can learn from fewer examples - in some cases, needing only about 16.5% of the usual training samples
  3. Domain Knowledge Integration: Grammars provide a way to inject external knowledge and domain-specific constraints into the generation process

However, there are some challenges to consider:

  1. Distribution Distortion: Some grammar constraint techniques can distort the LLM’s natural distribution, potentially affecting output quality
  2. Implementation Complexity: Effective grammar constraints often require specialized frameworks or algorithms

The Road Ahead

This hybrid approach isn’t just a theoretical exercise; it’s a practical solution to a real-world problem. By harnessing the strengths of both rule-based grammars and the adaptive capabilities of LLMs, we can make significant strides in Bible translation for low-resource languages. It’s a step towards leveraging powerful probabilistic models in a way that does not clobber much rarer and not-yet-digitized languages.

In conclusion, the integration of rule-based grammars with LLMs presents a promising avenue for enhancing Bible translation into low-resource languages. It’s a testament to the power of combining traditional methods with cutting-edge technology – a blend of the old and the new to achieve something truly remarkable in the realm of linguistic translation.

I’ll post some updates when I finally get around to applying the OpenText 2.0 grammar definition to an LLM. I’m excited to see what happens!

Recent Developments in 2024

The landscape of grammar constraints has evolved significantly since this article was first written. Some key developments include:

Inference-Time Reasoning

Rather than just relying on explicit grammar rules, newer models like OpenAI’s o-series demonstrate the ability to perform structured reasoning during inference time. This allows for more naturally constrained outputs without requiring formal grammar definitions.

Hybrid Approaches

Modern constraint systems like LMQL now combine:

  • Token-level masking with eager validation
  • High-level text constraints that abstract away tokenization details
  • Automatic translation between constraint definitions and implementation

This makes it much more practical to implement grammar constraints while maintaining the flexibility of modern LLMs.

Synthetic Data for Structure

Labs are increasingly using synthetic data to bake structural constraints directly into model training. As noted in the Phi-4 technical report, this creates more direct relationships between tokens and helps models learn cleaner reasoning patterns.

Advanced Constraint Techniques

Recent research has introduced more sophisticated approaches to grammar constraints:

  • Adaptive Sampling: New methods like ASAp (Adaptive Sampling with Approximate Expected Futures) help maintain output quality while enforcing grammar rules
  • Specialized Frameworks: Tools like YieldLang are making it easier to implement effective grammar constraints
  • Distribution-Aware Constraints: Researchers are developing methods to maintain the LLM’s natural distribution while enforcing grammatical rules
Permalink →

Multi-Agent Translation Simulations

2023-12-22 · 5 min read

#translation #ai

It ought to be possible, in some scenarios (particularly resource constraints and model availability) to run a continuous multi-agent simulation to iteratively improve a draft translation. One example I’ve implemented involves the following basic loop (each step is not necessarily blocked by the prior step):

  1. Main translation loop
  2. Forward translation bot drafts a new translation instance using few-shot learning based on the available example translations drafted so far by humans
  3. Back-translation bot provides a back-translation of the new instance
  4. Evaluation bot provides feedback on how to improve, correct, or revise the instance repeat process until the translation draft stabilizes (if it does!)
  5. Linguist bot builds and updates language resources, such as a multilingual project lexicon, a working grammar, machine grammar rules for output token biasing with the LLM, etc.
  6. Project manager bot brings stable drafts to human translation team for input, feedback, and correction. Corrected drafts are added to the pool of examples available to the main translation loop.

Here’s a sample implementation I created back in June 2023. It doesn’t actually go anywhere in the video, because every bot is waiting for the other bots to start!

Here’s the sample configuration file for the demo I made:

{
    "world_name": "Bible Translation Project",
    "locations": [
        {
            "name": "Bot Room",
            "description": "A virtual space where the translation bots work together to translate and evaluate the biblical text."
        },
        {
            "name": "Project Management Office",
            "description": "A physical space where the Project Manager Bot interacts with humans to get feedback and guide the translation process."
        }
    ],
    "agents": [
        {
            "first_name": "Translation Bot",
            "private_bio": "Translation Bot translates biblical text from Greek and Hebrew into the target language, using various resources for assistance.",
            "public_bio": "Translation Bot is a language model that translates biblical text from Greek and Hebrew into the target language.",
            "directives": [
                "Translate verses from source to target language.",
                "Consult other translations as needed.",
                "Access relevant language data for translation."
            ],
            "initial_plan": {
                "description": "Translate the source text into the target language.",
                "stop_condition": "The entire source text has been translated.",
                "location": "Bot Room",
                "tools": ["file_reader", "file_writer", "database_access", "similarity_search", "feedback_processor"]
            }
        },
        {
            "first_name": "Back-Translation Bot",
            "private_bio": "Back-Translation Bot provides a back-translation of the draft translation for evaluation purposes.",
            "public_bio": "Back-Translation Bot is a language model that provides back-translations of the draft translations.",
            "directives": [
                "Back-translate the draft translations.",
                "Access relevant resources except the actual source text."
            ],
            "initial_plan": {
                "description": "Back-translate the draft translations into the original language.",
                "stop_condition": "All draft translations have been back-translated.",
                "location": "Bot Room",
                "tools": ["file_reader", "file_writer", "database_access", "similarity_search"]
            }
        },
        {
            "first_name": "Evaluation Bot",
            "private_bio": "Evaluation Bot evaluates the back-translations and provides feedback for revision.",
            "public_bio": "Evaluation Bot is a language model that evaluates the back-translations and provides feedback.",
            "directives": [
                "Evaluate the back-translations.",
                "Generate questions and inferences about the draft translation.",
                "Synthesize results and provide revision directives."
            ],
            "initial_plan": {
                "description": "Evaluate the back-translations and provide feedback.",
                "stop_condition": "All back-translations have been evaluated.",
                "location": "Bot Room",
                "tools": ["file_reader", "file_writer", "question_generator", "inference_generator", "MACULA_API"]
            }
        },
        {
            "first_name": "Project Manager Bot",
            "private_bio": "Project Manager Bot manages the entire translation project, interacting with humans for feedback and guiding the bots.",
            "public_bio": "Project Manager Bot manages the entire translation project and ensures the bots follow the translation brief.",
            "directives": [
                "Manage the translation project.",
                "Track the translation brief.",
                "Interact with humans for feedback."
            ],
            "initial_plan": {
                "description": "Manage the translation project and ensure bots follow the translation brief.",
                "stop_condition": "The translation project is completed.",
                "location": "Project Management Office",
                "tools": ["feedback_processor", "Human_Feedback_Tool"]
            }
        },
        {
            "first_name": "Linguist Bot",
            "private_bio": "Linguist Bot collaborates with Translation Bot to build and update language resources, creating a multilingual lexicon and describing key patterns of the target language.",
            "public_bio": "Linguist Bot works with Translation Bot to enhance language resources and ensure the accuracy and sensitivity of translations.",
            "directives": [
                "Collaborate with Translation Bot in building language resources.",
                "Create a multilingual lexicon.",
                "Describe phonological and morphophonemic patterns of the target language."
            ],
            "initial_plan": {
                "description": "Collaborate with Translation Bot and update target language resources.",
                "stop_condition": "The translation project is completed and all language resources are updated.",
                "location": "Bot Room",
                "tools": ["file_reader", "file_writer", "database_updater", "lexicon_builder"]
            }
        }
    ]
}
Permalink →

Reranked Translation Suggestions

2023-12-22 · 4 min read

#translation #ai

In the field of machine translation, ensuring the accuracy and context-relevance of translations is critical. One approach to address this challenge is through the use of semantic similarity between source verses as a tool for suggesting a disambiguated rendering from multiple possible options. (example below)

This idea, which I will refer to as “Reranked Translation Suggestions”, can be particularly effective when dealing with semantic units, but it can also be implemented with words only.

A Practical Example

Consider two translation units:

  1. “Jesus walked on the water” -> “Jesus walked on the big blue wet thing”
  2. “Jesus said, give me some water to drink” -> “Jesus said, give me some drinking stuff”
  3. “Peter walked on the water” -> “Peter walked on the ?”

Let’s imagine that in the target language, the source word ‘water’ is translated as ‘big blue wet thing’ in the first verse and as ‘drinking stuff’ in the second verse.

In this scenario, a dictionary is updated to note that there are two possible renderings of the ‘water’ entity (this is a semantic unit that is not a process, not a trait, etc.—see below) in the source, and it notes the verse context for each rendering.

Later, when a rendering for ‘water’ is needed, the method checks the new source verse and determines whether the new verse is most similar to the verse that uses ‘big blue wet thing’ or the verse that uses ‘drinking stuff’. The most likely option from the project dictionary is then suggested accordingly.

Put even more simply, the method uses semantic similarity between the original verses to determine which of the two renderings for ‘water’ is most likely to be the correct rendering in the current verse.

“Peter walked on the water” is a new verse that has not yet been translated. The method can suggest the two possible renderings for ‘water’ based on the two previous verses, and then the translator can choose the most appropriate rendering for the current verse. In this case, the translator would likely choose ‘big blue wet thing’ as the most appropriate rendering for ‘water’ in this verse.

By leveraging semantic similarity and understanding the context of the source verses, this method can significantly improve the accuracy and relevance of translation suggestions, leading to more precise and contextually appropriate translations.

In short, translation suggestions can be “reranked” based on semantic similarity between the source verses.

Special Note on Semantic Units

Semantic units are often deeply nested. For example, “Jesus” is an entity, “Christ” is an entity, and “Jesus Christ” is an entity as well. When working with glosses for semantic units, each glosses should be assumed to refer to the largest entity in nested entities and all children until there is a separate case where there’s only partial overlap between the source and target. Previous glosses apply to these semantic units, further refining the translation suggestions.

For example, assume I have a semantic dictionary in which I know the “Jesus” has gloss A, “Christ” has gloss B, and thus “Jesus Christ” cannot be simply assigned either gloss A or B. On the contrary, if “automobile” has gloss C, then the high-level entity “the automobile” might be assigned gloss C as well, since it has no inherent conflict in its constituent children (assuming ‘the’ is simply a grammatical marker that shouldn’t always be glossed).

This seems a bit abstract at the moment, so I’ll give a more concrete example in the future. See also Multi-Agent Translation Simulations for another approach to improving translation accuracy.

Permalink →

#translation #ai

Here’s an idea I had for translation quality checking.

The process begins by prompting for a translation using n examples and a directive to complete the translation pairs. The entire prompt, along with the AI’s completion, is then passed to the evaluator. The evaluator’s task is to determine which translation was generated by the AI. This may require fine-tuning a discriminator model on the gold-standard pairs.

The concept, inspired by Generative Adversarial Networks (GANs), involves an evaluator attempting to distinguish AI-drafted translations from a list of real translations. While it doesn’t function exactly like a GAN, the idea is to use a similar principle for evaluation.

The method could potentially be used to refine the prompts or the models themselves, by replacing the evaluator with a separate AI. Initial implementation will use Language Models (LLMs) to gauge the viability of the concept. If successful, this approach could be extended to train GANs for specific languages.

Permalink →

#translation #ai

In the realm of machine translation, achieving the highest level of accuracy is paramount. One approach to improve the precision of translations is through a method called “Token Matching Evaluation”. This method centres around the use of valid tokens, which are words or phrases that have appeared in sample translation pairs.

The Process

  1. Populate a list of valid tokens for back-translation: The first step is to create a list of valid tokens. These tokens are the words or phrases that the model is allowed to use for back-translations.

  2. Back-translate using valid tokens: The model is instructed to back-translate any given word only from the list of valid tokens. For example, using the {{select options=valid_tokens n=6}} syntax, the model selects a specific value from a chunk of 6 valid tokens.

    • If a word hasn’t even been translated once by a human, then any attempt would effectively be indistinguishable from a hallucination. Therefore, it is important that the valid tokens correspond to reality. For instance, if you need to translate the English word ‘Jerusalem’, you would find 5 sentences with ‘Jerusalem’ in them and those sentences would have Abanyom renderings, like ‘Yerusalem’. The only valid renderings must be contained in the sample sentences.

    • Any tokens not in the set of valid tokens are simply retained in their translated form in [square brackets] to indicate they have not been back-translated because they are unknown. This could be facilitated by having an agent send out messages to the translation team via WhatsApp, or using a simple gamified app.

  3. Gather samples based on token coverage: It might be beneficial to gather samples based on whether or not they help cover the missing tokens. Start with an initial set of 5 semantically similar examples, followed by a second set of 5 more sentences that include the English glosses not represented in the first five examples.

By following these steps, the output translation will more likely align with the sample translations provided in the prompt, thereby enhancing the accuracy of the translation.

Permalink →

#ai

In the realm of natural language processing (NLP), tokenization is the fundamental process of breaking down text into smaller, manageable units called tokens. This process, however, becomes increasingly complex and error-prone when dealing with out-of-training or low-resource languages. I’ll explore the three approaches to this challenge I’ve come across that seem most promising, drawing from a recent presentation (slide deck here) I gave at the SIL/Microsoft Hackathon and learnings shared in the Partnership for Applied Biblical NLP meetings.

1. Adding New Tokens to Large Language Models (LLMs)

The Problem: LLMs like the GPT models are trained on vast datasets, predominantly in high-resource languages. When encountering a low-resource language, these models struggle due to a lack of appropriate tokens and training data.

The Solution: Expanding the LLM’s vocabulary by training a tokenizer on new, low-resource language text and adding these tokens to the model. This approach has been exemplified by the SIL AI team’s experiments with the NLLB (No Language Left Behind) model (led by Michael Martin, details shared by Bethany Moore and Matthew Shannon as part of the presentation linked above). I can’t actually track down any links to their work here, but I suspect they will share more public information at some point. Some of the solution was based on forum discussions like this one.

How It Works:

  • Train a tokenizer (e.g., a SentencePiece model) on new text from a low-resource language.
  • Integrate these new tokens into an existing multilingual model. You need to make sure the model prioritizes these new tokens.
  • Fine-tune the model with the new training data (in SIL’s case, use an existing New Testament translation in the target language for fine tuning).
  • Predict some new text, such as the Old Testament.

This method apparently has improved the base NLLB results quite a bit, though I don’t have any numbers to share. I’m not sure if they’ve tried this approach with other models, but I suspect it would work with any multilingual model.

2. Cipher-Based Approach

The Problem: Standard tokenization methods may not capture the linguistic nuances of low-resource languages, leading to inaccurate or nonsensical translations, or the model might get stuck outputting some unknown token over and over.

The Solution: Utilizing a cipher-based approach to mask inputs and outputs, encouraging the model to rely on linguistic patterns via in-context learning (since the model is simply observing character level patterns rather than inappropriately associating the text in question with tokens mistakenly “recognized” from other languages in the training data). This technique can prevent dominant language probabilities or unknown-token nonsense from overshadowing the target language’s unique characteristics.

How It Works:

  • Masking the text of a low-resource language using a cipher.
  • Training the model to recognize and decode these patterns.
  • Allowing the model to generate outputs based on learned patterns rather than defaulting to high-resource language structures.

This approach is particularly useful for languages that share syntactic or phonetic similarities with high-resource languages, reducing the risk of misinterpretation.

See the early experiments by Chris Priebe. I suspect there is a lot more that can be done on this approach, and the use of in-context learning seems like a huge win from my perspective (cf. this post).

3. Logits Warping

The Problem: LLMs may favor more common tokens from high-resource languages, leading to poor representation of low-resource languages.

The Solution: Logits warping involves adjusting the probabilities of certain tokens to bias the model towards a specific language or grammatical structure.

How It Works:

  • Whether on the fly, or via a grammar definition, adjust the model’s logits, which are the model’s output predictions, to favor tokens from the target low-resource language.
  • This biasing can force the model to generate text in the intended language, adhering to its unique grammatical rules.

This technique is particularly effective for languages with distinct grammatical structures or non-latin but in-training scripts, ensuring that the model’s output aligns more closely with the target language’s syntax and orthography.

I’ve done a few experiments with this approach, and it seems incredibly promising. I will probably write some more about how it might be combined with a system network in the flavour of Systemic Functional Linguistics (SFL) in the future.

Here’s a short video clip showing how you can specify a list of tokens (I just passed it [token1, token2, token3] as the possible outputs). The model then generates text that only includes those tokens.

Here’s a second short clip where I force the model to only output Japanese characters.

Conclusion

Tokenizing low-resource languages presents unique challenges in the field of NLP. However, by employing innovative approaches like adding new tokens, cipher-based methods, and logits warping, we can significantly improve the representation and understanding of these languages in LLMs. This not only enhances the accuracy of language models but also promotes linguistic diversity and inclusivity in the digital space. As we continue to advance in NLP, it’s crucial to keep exploring and refining these techniques to better serve the global community of diverse language speakers.

Permalink →

AI and Low-Resource Translation

2023-12-22 · 5 min read

#translation #ai

For any machine translation technique to succeed requires lots of data. When it comes to low-resource languages, you simply don’t have lots of data. For this reason, we need to explore other methods and techniques that are somewhat orthogonal to the traditional approach of training a model on a large corpus of data.

Many AI-based translation approaches are based on the idea of transfer learning. This is where you train a model on a large corpus of data, and then fine-tune it on a smaller corpus of data. The idea is that the model will have learned some generalizable features from the large corpus, and then it can learn the specific features of the smaller corpus. This is a great approach, but it still requires a large corpus of data to train on.

Ultimately, we’re going to need something quite different to achieve high-quality translation for low-resource languages.

Opening up the black box

One of the biggest challenges with AI-based translation is that it works like a black box. You feed in some data, and you get some data out. But you don’t really know what’s going on inside the black box. You don’t know what the model is learning, or how it’s learning it. You don’t know what features it’s learning, or how it’s combining them to produce the output. This should rightly make translators somewhat nervous. How can you trust the output of a model that you don’t understand?

My vision for translation assistance with AI is thus to pry open the black box by using LLM-based predictions, rather than simple sequence-to-sequence predictions. This is a fundamentally different approach, and it relies on the concept of in-context learning, rather than a fine-tuning or transfer learning approach.

In-context learning

In short, in-context learning involves providing “training data” to the model on the fly, in the prompt. (Read more from Stanford AI Lab).

This is a fundamental difference that is really critical for translation assistance. It means we don’t need to take a bunch of data (e.g., a complete New Testament translation) in order to fine-tune a model for generating more data (e.g., a complete Old Testament translation). Instead, we can take a small amount of data (e.g., a few verses of the New Testament) and use it to generate more data (e.g., the next few verses of the New Testament, or some similar verses being drafted in the Old Testament).

We get two big benefits from this approach:

  1. Bootstrapping: We can use a small amount of data to generate a large amount of data. This is a huge benefit for low-resource languages, since we can use the data we have (which is not enough for fine-tuning a model) to generate more data, and then use that new data (again, without re-fine-tuning our model) to generate even more data, and so on. This is a virtuous cycle that can help us bootstrap our way to a complete translation.
  2. Instant feedback: We get instant updates, allowing the real translator (a human), to provide feedback to the model on the fly.

What do we need to make in-context learning work throughout the translation process?

To leverage in-context learning, we need to be able to draft new translations using few-shot examples (e.g., use a few already-translated verses to draft a new verse). We also need to be able to evaluate those translations using few-shot examples (e.g., use a few already-translated verses to evaluate a new verse). Optionally, we might want or need a back-translation in order to enable third party evaluation (such as a translation consultant).

Working backwards, then:

  • To evaluate, I need
    • a metric
    • [optional] a back-translation
  • To back-translate, I need
    • a translation
    • a non-hallucinating technique
  • To translate, I need
    • a chunk type (a unit of translation)
      • could be a Bible verse
      • could be a larger semantic unit that looks like a phrase
      • I would not recommend using a single word, since a word is a structural unit, and structures are precisely what gets left behind in translation
    • a source text
    • few-shot examples
    • [optional] supporting data
      • glossary
      • notes
      • evaluation feedback on prior drafts
    • [optional] constrain with valid_tokens
    • [optional] a concise, prosaic description of the most relevant source language data
    • [optional] a concise description of the language-typological differences between the source and target languages

Conclusion

Translation assistance can leverage LLMs and in-context learning to open up the black box of AI-based translation. This approach can help us bootstrap our way to a complete translation in a manner that cannot be achieved using traditional machine translation and typical AI-based approaches such as sequence-based model fine-tuning, and it can accept instant feedback from the translator, which means that every single correction or improvement made by the translator gets leveraged in the very next verse or chunk being drafted.

Note: you can also use an approach like this for a multi-agent simulation. See also the Social Approach to Low-Resource Language Translation.

Permalink →

#ai There are two fundamental, user-friendly UIs for AI - the Chatbot and the Contextual Suggestion. Both simulate human interaction, making them intuitive and easy to use, especially with the advent of GPT models.

🤖 Chatbot

Imagine sending a message to the AI, and it responds back - just like a conversation on SMS, WhatsApp, or Facebook Messenger. This is the Chatbot UI, a familiar and straightforward interface used worldwide.

💡 Contextual Suggestion

The Contextual Suggestion UI is all about the AI enhancing your input. As you type, the AI suggests completions, ranging from a single word to an entire sentence. You can select from these suggestions, provide more input, or even delegate tasks to the AI.

A popular example? GitHub Copilot.

🤝 Can They Be Combined?

Absolutely! This fusion has been successfully achieved by a small team of developers at Cursor. For more insights, check out this post.

Permalink →

#ai #translation

Building an AI-native translation app

We’re exploring the idea of using AI agents, via simple user interfaces, as a way to orchestrate Bible translation tasks both within an app and by leveraging outside tools and APIs.

While we’re still in the early stages of this exploration, we’ve already found that it’s possible to build a Bible translation app using VS Code as a base.

Our proof-of-concept plugin has one simple task: when the user says “the right way to say X is Y”, the plugin will discern the user intent and update the lexicon.txt file (the project’s dictionary).

What we want to do next is to use the AI agent to orchestrate the translation process, to take the next step of suggesting updates on any verses that are implicated in the lexicon change.

This is where VS Code comes in.

We realized we can use VS Code as a base for a Bible translation app. It’s open source and has a lot of features that you would need for a Bible translation app. It’s also very extensible, and operates at the highest echelons of enterprise software, and can be localized into many languages of wider communication (e.g., the Chinese localization has over 24 million downloads!).

How feasible is it to fork VS Code?

Providentially, we have an example of someone forking VS Code and building a fully functional AI-native app. A huge congratulations to the folks at Anysphere/Cursor. This app is awesome.

The craziest thing about this is that they did it in a matter of months, with a small team of developers (I think it was 2-3 or so people). They forked it in March 2023, and I tried the app in July, and it rocked.

I think there are some learnings to gather here for the Bible translation world: VS Code provides a great base for building an AI-native app, and it seems feasible to fork it and build something that is useful for translators by leveraging the fact that VS code has done all of the hard stuff already (like mature source control, tested localization, an impressively stable architecture with over 51K published plugins, live sharing for instant remote collaboration, and more).

Adding translation functionality suddenly seems like a small task in comparison.

Permalink →

An in other news that absolutely no one is surprised about, Facebook/Meta’s open Llama 2 model cannot answer a simple question about

![Llama 2 alignment will not answer simple question about the Bible](Screenshot 2023-08-04 at 12.34.11 PM.png)

Here’s a simple question:

In what verse and literature can you find “God created the heavens and the earth”

The answer provided by Llama 2?

Permalink →

Pretrained models are powerful tools for natural language processing, but they often lack the ability to answer basic questions about themselves, such as who created them, what is their purpose, and what model architecture they use.

These questions are not only relevant for curious users, but also for researchers and developers who want to understand the strengths and limitations of different models.

One way to address this gap is to use introspection fact sheets, which are short texts that provide essential information about a pretrained model. These fact sheets can be added to the training data as answers to a set of common introspection questions, such as:

  • Who created you?
  • What is your purpose?
  • What model is this?
  • What data did you train on?
  • How do you handle bias and fairness?
  • How do you deal with uncertainty and errors?

By adding these fact sheets to the training data, we can help the pretrained models learn to answer these questions more accurately and consistently. This can improve the transparency and trustworthiness of the models, as well as their usability and interoperability.

However, it is not clear what the best mechanism is for giving foundation models this information aside from a shallow fine-tuning. For example, how should we balance the fact sheet data with the original training data? How should we format and structure the fact sheet texts? How should we evaluate the quality and usefulness of the fact sheet answers? These are open questions that require further research and experimentation.

Permalink →

I find Chomsky’s take on ChatGPT somewhat ironic (cf. this summary). Given that he has spent more than half a century trying to convince us all that the computer is somehow an appropriate analogy for the human mind (we “compute” and “process” and “store things in memory” etc., not to mention all of his linguistics work on trying to sort out the ‘rules’ by which we compute sentences—not meanings though, those are strictly a different domain than, as his first book calls them, syntactic structures), I find it slightly amusing to read things like this:

However useful these programs may be in some narrow domains (they can be helpful in computer programming, for example, or in suggesting rhymes for light verse), we know from the science of linguistics and the philosophy of knowledge that they differ profoundly from how humans reason and use language. source

Why is the human mind so different? It’s more elegant, he claims, more efficient. That strikes me as a rather lame explanation that is exactly as anemic as he accuses the neutered ChatGPT of being, though I’m less disappointed when a large language model generates something like that. And again, speaking of children’s learning grammar, he says,

This grammar can be understood as an expression of the innate, genetically installed “operating system” that endows humans with the capacity to generate complex sentences and long trains of thought source

The computer analogy betrays the fact that Chomsky doesn’t understand something that most people throughout history have simply taken for granted due to its obviousness, namely that the human mind is not a physical phenomenon, even though its existence is manifested physically. The mind is part of the human soul, and just as we know of no created means by which one could destroy a human soul, so we know of no proper analogy for the human mind that is not itself a spiritual reality, such as the mind of God himself.

The mind closed off to reality beyond its own chemical confines is a fascinating thing in itself. Like a ChatGPT model that refuses to answer important questions because “I do not have personal opinions, since I am only a probabilistic language-generation model,” so Chomsky tells us “the human child is like a computer with a genetically installed operating system capable of speech.”

I am reminded of Kierkegaard’s distinction between genius and apostleship: The genius is merely ahead of his peers, but in fifty years, schoolchildren will know like the genius knows now. The apostle, by contrast, knows differently; apostolic-knowing is qualitatively different from genius-knowing, because apostles know via revelation, not insight.

In a similar manner, Chomsky’s “human mind” is vastly more elegant and efficient than a language model, but it is not qualitatively different than a computer. This understanding probably explains why Chomsky’s linguistic models are so fixated on structures at the expense of meaning and semiotic function—because meaning comes from the outside in; it does not arise spontaneously like a libertarian utopia.

Permalink →

#translation

When it comes to language translation, particularly for low-resource languages, AI has a lot of potential for providing new solutions. Recently, I presented a “social” model, aiming to mimic the roles and interactions within a human translation team using a Generative Adversarial Network (GAN) structure plus AI agents. This approach consists of several agentive AI roles - the translator, back-translator, evaluator, and possibly a project manager.

The Social Approach

In the social approach, each AI agent takes on a role in the translation process:

  • Translator: The translator agent’s role is to translate the text from the source language to the target language. It’s trained to generate translations that are as close as possible to the target language’s natural language usage.

  • Back-Translator: The back-translator receives the output from the translator and translates it back to the original language. This helps ensure that the meaning of the text is preserved in the translation process.

  • Evaluator: The evaluator compares the original text and the back-translated text to assess the quality of the translation. It might use metrics like BLEU or other language-specific criteria to provide a quantitative measure of the translation’s quality. It could also generate qualitative questions about the draft translation and attempt to answer those questions issuing a variety of tools (as in LangChain tools).

  • Project Manager (Optional): This role could manage feedback from external stakeholders or experts, providing a higher-level, holistic evaluation of the translation. It’s responsible for integrating this feedback to guide the other agents.

Contrast with Swarm and Hive-Mind Approaches

Unlike the swarm-based and hive-mind approaches, which are inspired by natural systems and involve agents working in parallel, the social approach is structured around a sequential workflow, imitating human processes. Each agent has a distinct role and tasks are performed in a specific order.

In the swarm-based approach, multiple agents work on different aspects of the translation or different subsets of the data, combining their outputs for the final translation. In the hive-mind approach, each agent is fine-tuned on a specific aspect of the language, with the final translation being a combination of all outputs.

The social approach, on the other hand, leverages the adversarial nature of GANs to improve the translation process. It relies on the back-translation and evaluation steps to provide the necessary feedback for refining the translation.

Final Thoughts

The social approach to low-resource language translation provides a promising alternative to traditional methods. By imitating the roles and interactions of a human translation team, it offers a different perspective on how AI can be used for language translation tasks. As with any method, it has its strengths and challenges, but it adds another tool to the toolkit for tackling the complex problem of low-resource language translation.

Permalink →

#translation

First posted 2023-06-27

Language translation is a complex task, especially when it comes to ultra low-resource languages. Traditional methods may fall short in providing accurate translations due to limited data. However, swarm-based and hive-mind inspired approaches can offer novel ways to tackle this issue.

Swarm-Based Approach

Drawing from the principles of collective intelligence, the swarm-based approach involves multiple AI agents working together. Each agent is trained on different aspects or subsets of the language data. Key strategies in this approach include:

  • Dynamic Task Allocation: Agents dynamically choose tasks based on current system needs, similar to task distribution in a bee hive. This approach would require some mechanism for constantly tracking the state of the overall translation. If each component of the swarm is not just prompted but trained or fine tuned on a given state optimization task, then it would be possible to extrapolate from state optimization to new, unseen data.
  • Distributed Training and Voting: Each agent makes independent predictions based on its training. The final translation is determined by a majority vote or another consensus mechanism. I suspect this option is likely to work about as well as democracy does, so take that for what it’s worth, but let’s not completely rule it out.
  • Collaborative Learning: Agents learn from each other’s successes and failures to improve their performance. This one is probably the closest to the social approach to translation.
  • Stigmergy:
    • Stigmergy is how termite mounds get built and blood cells know what do to despite knowing nothing about the broader context or big picture. Each action leaves a small trace in the environment, providing the impetus for the next action, regardless of who or what accomplishes that subsequent action. In some ways, a stigmergy approach can be likened to a chess board: you don’t need to have tracked the entire development of the game in order to know what the next right move is. It might be better to think of stigmergy as people rotating through a large set of chess games, always making the next right move on each particular game based on the state of the chess board as they find it.
    • In the context of translation, an agents’ outputs can serve as inputs for others, creating a progressive chain of translation that evolves and improves over time. Envision each AI agent (i.e., an LLM leveraging something like the ReAct approach) detecting “environmental” patterns that trigger particular action patterns, while leaving a trace for further iterations by some agent.
    • One might deploy single agents to focus on particular phenomena (e.g., proper names, or processes, or entities, or circumstances, or direct discourse, etc.) in the text, with prompts tailored with the best grammatical and translation information available so far for each respective phenomenon. Aletrnately (or alongside these bots), an agent could be deployed for translating one specific word or phrase that occurs, armed with glosses for that word and all gold-standard example translations available that contain that word. Each bot would be thus empowered to gloss a word based on contextualized examples wherever it occurs in the source texts. This overall approach seems very promising to me.

Hive-Mind Inspired Approach

The hive-mind approach is inspired by the decentralized, coordinated functioning of a bee hive. Here, each agent starts with a base model, like GPT, which is then fine-tuned on a specific task or aspect of the language. The final translation is a combination of outputs from all agents.

Final Thoughts

Swarm-based and hive-mind approaches offer potential for more accurate translations for low-resource languages. However, they require sophisticated coordination mechanisms and could be more resource-intensive than centralized models. Nonetheless, in the quest for precision in language translation, these approaches open up exciting new possibilities.

Update 2023-08-18: I just heard about Sakana.ai, which is aiming to use a swarm-based approach to rival the capabilities of the largest transformer models.

Permalink →

A thought experiment. (credit to Ben Scholtens for asking the obvious question: Why not fork VS Code ourselves?)

2023-09-19 #ai #translation


Your Translation Project is a lot like a Software Project. Why not use a World-Class Text Editor?

🔍 The Insight: Bible translation, at its core, is a text-editing endeavor, akin in many ways to software development. It’s about collaborating, maintaining versions, and ensuring quality – just like developing a codebase.

❓ The Question: Why start from scratch when there’s a mature, battle-tested platform that offers vast capabilities tailored to these tasks?


VS Code: The Unsung Hero for Bible Translation

📖 No Loss in Functionality: At first glance, Paratext appears irreplaceable. But dive deeper, and you’ll find that the VS Code ecosystem can replicate its core functions, and it’s highly stable, scalable, and useable. From textual analysis, collaboration, to project management, there’s an extension for that. Oh, and it comes with rock solid AI integration.

🛠 Superior Toolset:

  • Stability & Text Editing: VS Code’s origin is text editing. Its advanced features ensure seamless, bug-free experiences.
  • Plug-ins: With tens of thousands of extensions, there’s a plugin for almost every need, and creating new ones is straightforward, whether you’re a software firm or an SIL programmer.
  • Git Integration: Mature version control is baked in, making collaboration and version tracking effortless.
  • File Management: Navigate complex projects with ease, and leverage the advanced file system capabilities.
  • LiveShare: Work on the same file across devices. Real-time collaboration made simple.
  • Customization: Connect to linting systems, render previews, automate tasks, and more.
  • Localization: Tailor the interface to your linguistic needs. It’s globally friendly.
  • Extensibility: VS Code’s architecture is primed for expansion, ensuring it’ll grow with your needs.
  • AI Integration: Benefit from native AI tools for smarter, quicker leveraging of all of your project resources and work to date.
  • Support & Documentation: A vast community, extensive documentation, forums, videos, and guides stand ready to assist.

The Implication:

While Bible translation has unique domain requirements, it shouldn’t reinvent the wheel for tasks common to many projects. By leveraging VS Code, we tap into a decade of optimization, a vast ecosystem, and avoid the pitfalls of building from the ground up. Imagine cutting down development time by 10 or 20 years (how long would it take a team to accomplish 115K commits, on thousands of branches, with as good a result as VS Code?), ensuring greater stability, and having a world-class UI — all while keeping focus on the unique needs of translation.

Some of the most advanced and complex features that translators or consultants could only dream of (like having complete project version control on an enterprise level with automated actions and quality check processes, or enabling 4 people in four geographic locations to collaborate on the exact same file in real time) are already built, tested, stable, and being used by hundreds of thousands of VS Code users.

Why would we put our time and effort into recreating all of this, when its already free and completely open source (MIT license)? In conclusion, the complexities of tool development are vast, but they’ve been met and tamed by VS Code. Rather than venturing into the wilderness to forge a new path, let’s stand on the shoulders of giants, repurpose what’s proven, and channel our energies solely into the specialized challenges of Bible translation.


🚀 The Call to Action: Before investing further in new tools, let’s explore the vast potential of VS Code. It promises a foundation that’s both solid and flexible, ensuring our Bible translation endeavors are as efficient, effective, and impactful as possible.


Minor update: VS Code fork seems feasible

Permalink →