안스로픽의 'Fable' 모델이 생물학 관련 용어가 포함된 순수 소프트웨어 포팅 작업을 안전상의 이유로 잦아들어 과도한 필터링에 대한 비판이 제기되었습니다. 저자는 C++로 작성된 생물학 데이터 분석 툴을 Rust로 변환하려다 거부당했으며, Fable의 분류기가 오판을 일으키는 것으로 보인다고 지적했습니다. 이로 인해 연구자들은 정상적인 코딩 및 연구 작업에 큰 불편을 겪을 수 있음을 시사합니다.
번역된 본문
제목: Fable은 유용한 모델이 아닙니다
저자: 롭 패트로 (Rob Patro)
날짜: 2026년 7월 7일
안스로픽(Anthropic)의 Fable(Mythos의 '안전 강화' 버전) 출시는 여러 가지 이유로 롤러코스터 같은 일이었습니다. 6월 9일에 처음 출시되었지만, 6월 12일에 미국 정부가 Fable과 Mythos에 수출 통제를 가했습니다. 이는 안스로픽이 자체 직원을 포함하여 미국 시민이 아닌 사람들에게 모델을 제공할 수 없음을 의미했습니다. 모든 사용자를 확인하는 것은 불가능했고 심각한 법적 조치의 위험이 있었기 때문에 모델을 계속 제공하는 것은 사실상 불가능했고, 결국 안스로픽은 모델을 철회했습니다. 몇 주간의 협상 끝에 수출 통제가 해제되었고 안스로픽은 모델에 대한 접근을 복원했습니다 (현재 일반적으로 사용 가능한 것은 Fable뿐이며, Mythos는 여전히 미리 승인된 특정 파트너에게만 제공됩니다). 물론 이 모든 과정이 온라인에서 많은 논란을 일으켰고, 엄청난 양의 추측과 많은 뉴스 기사를 쏟아내게 만들었습니다. 그럼에도 불구하고, 여기서 제가 초점을 맞추고 싶은 것은 그런 일들이 아닙니다. 오히려 적어도 컴퓨터 과학 분야의 연구 수준 작업에 있어서 왜 Fable이 유용한 모델이 아니라고 생각하는지 설명하고 싶습니다.
첫 번째 실패 (이해는 되지만; 그렇다고 하기엔 어려움)
저는 RNA-seq 데이터에서 전사체 정량화를 위한 널리 사용되는 도구인 salmon을 작성하고 유지 관리하고 있습니다. 원래 salmon 코드는 C++11/14로 작성되었으며, 올해 초 ChatGPT의 도움으로 약간 업데이트하고 모듈화하여 C++20 표준으로 끌어올렸습니다. 그러나 제가 꽤 오랫동안 가졌던 좀 더 야심 찬 목표는 salmon을 Rust로 다시 작성하는 것이었습니다.
참고: 이 작업은 결국 완료되어 salmon 2가 탄생했습니다 (이미 C++ 버전과 동등한 수준을 넘어섰고 새로운 기능을 빠르게 추가하고 있지만, 그 내용은 다른 포스팅에서 다루겠습니다).
6월 9일 원래 Fable이 출시되었을 때, 저의 첫 생각은 이를 활용하여 salmon의 재작성 작업을 조율하는 것이었습니다. 지금까지 실험실에서 개발된 다른 여러 라이브러리나 프로그램을 C++에서 Rust로 포팅하거나 재작성한 적이 있었는데, 주로 Opus(4.6-4.8)의 도움을 받았고 그 과정은 매우 순조로웠습니다. 그래서 이번이 Fable이 어느 정도 수준인지 확인할 수 있는 좋은 기회가 될 것이라고 생각했습니다.
아아, 상세한 설명과 테스트 세부 정보 및 구현 지침을 포함하여 포팅 내레이티브를 작성하는 데 시간을 들인 후, Fable('계획' 모드)에 프롬프트를 제출했는데 즉시 안전 문제를 이유로 제 쿼리를 플래그 지정하고 거부한 뒤, 대신 Opus 4.8로 보내겠다고 제안했습니다. 당연히 저는 프롬프트가 거부된 이유를 알고 싶었습니다.
안스로픽은 Fable이 어떤 프롬프트를 거부하고 허용할지 결정하기 위해 '분류기(classifier)'를 사용한다고 주장하지만, 이 분류기가 엄청나게 잘못 조정되어 있다는 사실이 널리 보고되었습니다. 적어도 표면적으로는, 제 프롬프트가 RNA-seq 데이터를 다루는 소프트웨어 작업과 관련이 있고 문서 및 소스 코드의 생물학적 용어가 프롬프트 거부를 유발하는 데 필요한 레드 플래그를 작동시켰기 때문에 거부된 것으로 보입니다.
저는 Fable에게 기존의 오픈 소스이자 널리 사용되며 공개적으로 사용 가능한 C++ 소프트웨어 도구를 Rust로 재작성해 달라고 요청하는 것뿐이라고 설명하려고 시도했지만 헛수고였습니다. 재작성 자체가 새로운 '생물학적' 연구를 포함하지 않습니다. 이 초기 요청은 순수한 소프트웨어 작업이며, 이것은 Fable의 강점이라고 할 수 있는 부분입니다. 그럼에도 불구하고 Fable은 프롬프트를 거부했을 뿐만 아니라, 왜 거부했는지 자세히 공개하거나 설명하지도 않았고 이 문제를 피하기 위해 프롬프트를 어떻게 작성해야 하는지 이해하도록 돕기도 거부했습니다.
어쩌면 15~30분 동안 프롬프트의 표현을 바꾸어 보려다가 실패한 끝에, 저는 포기하고 그냥 Opus 4.8을 사용해 작업을 진행했습니다 (기꺼이 요청을 수락했고 결국 포팅 작업을 훌륭하게 완수했습니다).
그러나 이 일은 Fable이 사용하는 '분류기'가 사실상 분류기라기보다는 생물학적 연구 (그리고 아마도 사이버 보안 연구)와 관련된 주제(또는 사용자)와 관련된 어떤 것에도 참여하기를 거부하는 용어 및 사용자 목록일 뿐이라는 첫 번째 생각을 갖게 했습니다. 이러한 시도는 엄청난 실망을 안겨주었습니다. 불구하고 c
Fable is not a useful model Rob Patro July 07, 2026 The release of Anthropic’s Fable (the “safety conscious” version of Mythos) has been a roller coaster ride for many reasons. Originally released on June 9th, the US government placed export controls on Fable and Mythos on June 12. This meant that Anthropic could not serve the model to anyone who is not a US citizen, including their own employees. The impossibility of verifying all users at the risk of severe legal action made it functionally impossible to continue serving the model so Antrhopic pulled it. After a couple of weeks of negotiations, export controls were lifted and Anthropic restored access to the model(s) (only Fable is generally available, Mythos is still available only to specific, pre-approved partners). All of this, of course, cause much drama online, and resulted in a tremendous amount of speculation and many news stories. Nonetheless, that is not want I wanted to focus my thoughts on here. Rather, I wanted to explain why I think that, at least for research-level tasks in Computer Science, Fable is not a useful model. The first flop (understandable; but not really) I wrote and maintain a widely-used tool for transcript quantification from RNA-seq data called salmon . The original salmon code was written in C++11/14, and early this year, I updated and modularized it a bit (with the help of ChatGPT), and brought it up to the C++20 standard. However, my more ambitious goal, and one that I’ve had for quite some time, was to re-write salmon in rust . Note : This did eventually happen, resulting in salmon 2 (which is already beyond parity with the C++ version and is adding new features quickly, but that is for another post). When the original Fable release dropped on June 9, my first thought was to use it to help orchestrate the salmon rewrite. Now, I’ve succesfully ported or rewritten several other libraries or programs developed in the lab from C++ into rust, mostly with the help of Opus (4.6-4.8), and those went fairly smoothly. So, I thought that this would be a great opportunity to see how Fable compared. Alas, after spending some time crafting my detailed description and porting narrative, complete with implementation instructions and testing details, I submitted the query to Fable (in “plan” mode) and it immediately flagged my query on safety concerns, rejected it, and offered to send it to Opus 4.8 instead. Naturally, I wanted to know why the prompt was rejected. Anthropic claims that Fable uses a “classifier” to determine what prompts are rejected and which are allowed, though it’s been widely reported that this classifier is stupendously miscalibrated . Nominally, it seems, my prompt was rejected because it involves working on software that deals with RNA-seq data, and the biological terminology in the documentation and source code set off the red flags needed to trigger the prompt rejection. I tried, to no avail, to explain to Fable that I am simply asking to re-write an existing, open source, widely used, publicly available C++ software tool in rust. The rewrite itself does not involve novel “biological” research. The inital ask is purely a software task, which is supposed to be a strong suit of Fable. Yet, not only did Fable refuse the prompt, but it also refused to disclose or explain why it refused the prompt in any detail, or to help me understand how to prompt it in a way so as to avoid this issue. After perhaps 15 to 30 minutes of failed attempts at rephrasing my prompts, I gave up and simply proceeded with Opus 4.8 (which happily complied and, all said and done, did a great job with the port). However, this was my first inkling that the “classifier” used by Fable is not so much a classifier as, perhaps, a simple rejection list of terms and users, refusing to even begin to engage with subjects (or users) who have any relation to biological research (and likely, also, cybersecurity research). This attempt was massively disappointing. Despite the clear lack of any security risk or implication, Fable flatly refused to engage with me in work for which it should be well-suited. Taking a peek on social media, I learned that my experiences were shared by many others, including biologists who had Fable refuse to answer prompts as innocuous as “why am I?”, “what is a mitochondrion?” and …. “what should I have for dinner?”. Truly strange. The second flop (unforgivable) While I thought of other challenges I could pose to Fable, it disappeared, succumbing to the administration’s export controls on June 12. Thus, while I had come up with another piece of interesting work that I wanted it to take a crack it, the model was simply unavailable. On July 1st, after coming to terms with the administration (and not providing many details on precisely what had traspired), Anthropic re-released Fable. With this re-release, they mentioned even stricter safeguards. Nonetheless, Fable was back, so, I decided to give it another go. the setup : Back in the end of grad school, I worked on a paper about the problem of “Parsimonious reconstruction of network evolution” , which basically asks; if we are given a network (say protein interaction network), and the series of gene duplication, creation and deletion events for the proteins involved, can we reconstruct a parsimonious history of interaction gains and losses that reconstructs the observed network? The formal problem statement appears in the paper, along with generations to multiple species, etc. Nonetheless, we discovered something interesting, if we model the problem under the parsimony criterion, there is an efficient (polynomial) dynamic program that yields a (there can be many) most parsimonious solution. In the model we adopt in the paper, a protein inherits the interaction state of its parents, and rather than having to think about interaction creation and deletion separately, we simply consider “flipping” the interaction between two proteins (i.e. if they interact and we no longer wish them to do so, we flip the interaction off; if they don’t interact and we wish them to, we flip the interaction on). However, the solutions that are generated by the dynamic program can be such that they are not physically realizable . How? Assume that there are two distinct proteins A and B in our gene tree, such that neither is a descendant of the other. Let’s denote by \(A_l\) and \(A_r\) the left and right children of A and by \(B_l\) and \(B_r\) the left and right children of B. Now, assume that our dynamic program identifies a parsimonious solution that involves the following set of interaction changes. It flips the interaction state between \(A_l\) and B, as well as the interaction between \(B_r\) and A. This particular set of flips is not physically realizable, because it assumes that \(A_l\) co-exists with B (so that gene A must have duplicated before B). Yet, it also assumes that \(B_r\) co-exists with A (so that gene B must have duplicated first). We call this structure a “blocking loop”. It turns out that these types of simple blocking loops (those involving 2 interaction flips and 2 tree edges) can generally be forbidden. However, one can construct arbitrarily long chains of interaction flips that are themselves realizable, but where adding one more interaction turns the whole sequence of interaction flips into a physically unrealizable loop. Take a look at Figure 2 for a graphical example of this. So, while we could come up with a dynamic program to find a parsimonious history (i.e. minimal set of flips), we could not make it do so while avoiding all blocking loops! We eventually settled on a heuristic. First, find a parsimonious history. If there are no blocking loops, we’re good to go. If there is a blocking loop, pick one edge in the loop, forbid it (set its cost in the dynamic program to infinity), and rerun the dynamic program. Keep doing this until we find a solution free of blocking loops. Those solutions with specific edges forbidd