DSPy를 BEAM으로 옮긴 Elixir용 LLM 프레임워크 Imp 0.5 공개

Hacker News13일 전조회 4

Elixir로 언어모델 프로그램을 선언적으로 작성하고 스스로 개선하게 만드는 라이브러리 Imp가 공개됐다. GitHub의 deepfates/imp 저장소에서 개발되는 이 프로젝트는 DSPy를 BEAM 가상머신으로 완전히 옮긴 포팅판을 표방한다. 0.5 버전이 Hex에 올라온 첫 릴리스다.

중심에는 시그니처가 있다. issue -> kind: enum[bug,feature,question], summary 같은 한 줄로 입력과 출력 형태를 선언하면, Imp가 그 시그니처에서 프롬프트를 만들고 모델 응답을 검사해 타입이 붙은 필드를 돌려준다. kind는 선언한 세 값 중 하나로만 나오고, 그 밖의 값이 오면 호출이 에러로 끝난다. 프롬프트 문자열도, 응답 파서도 직접 작성할 일이 없다. 같은 시그니처를 그대로 둔 채 Imp.chain_of_thought/2로 추론 단계를 앞에 붙이거나 Imp.react/3로 도구를 쥐어줄 수 있다.

최적화기는 라벨이 붙은 예제와 평가지표를 받아 프로그램을 채점하고 개선한다. 예제는 trainset, valset, testset 세 묶음으로 나뉘며 각각 학습, 후보 선택, 전후 점수 비교에 쓰인다. GEPA는 더 강한 모델을 reflection_lm으로 지정해 실패 지점을 읽고 지시문을 다시 쓴다. max_metric_calls 같은 값으로 호출 예산을 제한할 수 있다. 이 밖에 예제를 골라주는 LabeledFewShot과 BootstrapFewShot, 지시문과 예제 조합을 탐색하는 MIPROv2, 프로그램 자신의 성공·실패 시도에서 규칙을 뽑는 SIMBA, 모델 가중치를 학습하는 파인튜닝과 GRPO 계열이 이름을 올렸다. 최적화 결과는 지시문과 예제를 사람이 읽을 수 있는 새 프로그램이며 JSON으로 저장해 검토할 수 있다.

에이전트를 다루는 방식은 BEAM의 성격을 그대로 반영한다. Imp.call/2는 호출한 프로세스 안에서 프로그램을 실행하고, Imp.start_run/3은 감독 트리 아래 별도 프로세스로 띄운다. 실행 중에는 run_started, model_request, tool_call, tool_result, run_finished 같은 이벤트가 순서대로 쌓여 관찰과 중단, 제한이 가능하다. 모델 요청에는 데드라인이 걸리고, 이미 효과가 발생했을 수 있는 도구 호출은 조용히 재시도하지 않고 unknown으로 보고한다.

도구는 평범한 Elixir 함수다. Imp.tool로 이름, 설명, 스키마를 함께 정의하면 Imp.react/3가 답을 낼 때까지 도구를 호출하는 에이전트를 조립한다. 웹 페이지를 읽는 예제처럼 Req를 쓰는 코드라면 의존성에 Req를 추가하면 된다. MCP 서버의 도구를 가져와 그대로 쓰는 것도, Imp 프로그램을 ACP로 노출해 Zed 같은 클라이언트에 에이전트로 제공하는 것도 지원 범위에 들어간다.

DSPy가 제안한 문제의식은 모델 호출을 측정하고 개선할 수 있는 선언적 함수로 다루자는 것이었다. Imp는 여기에 BEAM 진영의 자산을 얹었다. 에이전트가 곧 프로세스라는 모델 덕분에 상태를 스스로 들고 메시지를 주고받으며 기존 애플리케이션의 감독 트리 안에서 함께 돌아간다. 단일 타입 호출부터 오래 살아 있는 다수 에이전트까지 같은 방식으로 조립하고 각 부분을 측정해 개선할 수 있다는 구상이다. 컨텍스트 윈도보다 훨씬 큰 입력을 다루는 RLM, 샌드박스에서 짧은 식을 계산하는 CodeAct와 program of thought, 직접 만든 모듈도 같은 틀에 올라간다. 최적화기는 에이전트 전체 실행을 되짚어 지시문을 고치거나, 점수를 매길 수 있는 임의의 텍스트·JSON(예컨대 도구 설명)까지 다시 쓰는 데 쓰인다.

실무에서는 프롬프트 문구를 손으로 다듬는 대신 시그니처와 지표를 관리하는 쪽으로 작업이 옮겨간다. 이미 Elixir로 서비스를 운영하는 팀이라면 에이전트를 별도 런타임 없이 기존 감독 구조에 편입시킬 수 있다는 점이 가장 직접적인 변화다.

전제 조건도 분명하다. Elixir 1.19 이상이 필요하고, jaxon과 erlexec 두 의존성의 네이티브 코드를 빌드하기 위해 C와 C++ 컴파일러가 있어야 한다. 첫 컴파일에는 네트워크 접근이 필요한데 erlexec 빌드가 rebar3 플러그인을 내려받기 때문이다. 모델 연결은 ReqLLM을 거치므로 그쪽이 지원하는 제공자를 쓸 수 있다. 0.5는 실험 단계로 API가 바뀔 수 있고, 최적화기들은 대규모 벤치마킹이 더 필요하다는 점을 프로젝트 스스로 인정하고 있다.