Issue 01중국 AI
AC POST
중국 AI 목록
掘金2026년 9월 19일 12:31중국어 → 한국어

오픈소스 AI Agent 소스 열람 후 다시 생각한 파일 검수

로컬 우선 AI 오피스 Agent인 OpenWorkBuddy 소스를 살펴본 뒤 파일 검수를 어떻게 바라봐야 하는지 다시 정리한 글이다.

중국어 원문을 AI로 번역했습니다. 고유명사와 수치는 원문 표기를 우선하며, 중요한 판단에는 아래 출처 원문을 함께 확인하세요.

프로젝트 추천 글이 아니다. 40일, 159 star의 오픈소스 Agent를 읽고 나서, Agent 엔지니어링의 몇 가지 구체적인 설계 트레이드오프에 대해 적은 노트다.

먼저 배경을 밝혀 둔다. 오해가 없도록.

나는 최근 오픈소스 프로젝트 하나를 뒤지고 있다: OpenWorkBuddy ( github.com/CatCatUncle/openworkbuddy ), 로컬 우선(local-first) AI 오피스 Agent다. 이 녀석이 하는 일은: 사용자가 한마디 하면, 스스로 계획하고, 도구를 호출하고, 검수해서, PPT / Word / Excel / 웹페이지 같은 파일을 사용자 디스크에 떨궈 놓는다.

star는 많지 않다, 159개. 그런데 코드 구조가 나에게 좀 영감을 줬다. 특히 내가 원래 그다지 중요하게 여기지 않았던 한环节(단계)—— 파일 검수 .

이 글은 주로 세 가지를 다루는데, 모두 내가 따로 꺼내서 논의할 가치가 있다고 생각하는 설계 문제다:

- Agent는 자신이 "정말로 다 끝냈는지"를 어떻게 아는가?

- Agent에 권한을 올려줄 때, "기어(档位)"와 "게이트(闸门)" 중 어느 쪽이 더 믿을 만한가?

- "남의 플러그인을 설치하는" 진입점의 보안 경계는 어디에 그어야 하는가?

一、"나 완료했어"——Agent의 가장 믿을 수 없는 한마디

먼저 내가 밟았던 함정 하나를 말하겠다.

Agent로 일을 시킬 때 가장 흔한 사고는 그것이 못 해내는 게 아니라, 그것이 다 했다고 말하는 것이다 . 디렉터리에 가서 파일을 찾아보면, 없다. 돌아가서 물어보면, 아주 진지하게 사과하고, 다시 한 번 "완료됨"이라고 말한다.

이 문제의 근원은 이해하기 어렵지 않다: LLM의 출력은 텍스트이고, "파일이 쓰였는가"는 외부 세계의 사실 이다. 이 둘 사이에는 자연스러운 결속이 없다——엔지니어링 차원에서 강제로 결속하지 않는 한.

대부분의 Agent 프레임워크는 모델이 도구 호출(예: write_file )을 출력하게 하고, 도구가 성공을 반환하면 흐름이 계속되게 한다. 이건 이미 루프가 닫힌 것처럼 보이지만, 중간에 간과되기 쉬운 틈이 하나 있다:

도구가 "성공"을 반환한 것이, 파일이 실제로 디스크에 있다는 것과 같지 않다.

예를 들어 경로를 잘못 썼거나, 디렉터리 권한이 부족하거나, 쓰기가 중단되었거나, 혹은 도구 구현 자체에 버그가 있는 경우——이런 상황에서 도구는 여전히 정상처럼 보이는 결과를 반환할 수 있고, 모델은 그것을 근거로 작업이 완료됐다고 여긴다.

OpenWorkBuddy의 방식은 한마디로 요약할 수 있다:

모델이 파일을 썼다고 주장하면, 디스크에서 검증한다; 검증되지 않으면 작업은 완료로 치지 않고, 되돌려 다시 시킨다.

이건 아주 소박한 발상이다. 소박해서 거의 적을 가치도 없어 보일 정도다. 하지만 그것은 "모델을 신뢰하는" 문제를 "사실을 검사하는" 문제로 전환한다. 이 전환 자체가 관건이다——일단 디스크에서 검증하기로 결정하면, 이후의 모든 엔지니어링 동작에 앵커(기준점)가 생기기 때문이다.

이 발상을 추상화해 보면, 이식 가능하다:

단계 일반적 방식 검수식 방식 파일 생성 도구가 200을 반환하면 통과 목표 경로에 파일이 실제로 존재하고 비어 있지 않은지 검증 이미지 생성 URL을 반환하면 통과 이미지 크기 재판독 / 디코딩 성공 여부 확인 문서 생성 "저장됨"을 반환하면 통과 문서를 다시 열어 구조 완전성 대조 코드 수정 diff를 반환하면 통과 컴파일 또는 테스트 한 번 돌리기

핵심 차이는: 검수의 근거가 집행자의 자기 진술이 아니라, 개조 대상 자체에서 온다는 것이다.

이 패턴은 보편성이 매우 강하다고 생각한다. "Agent 산출물 vs 불확실한 실행 과정"이라는 모든 장면에 이 구조를 적용할 수 있다. 그리고 그 최대 비용은 대개 검사 함수 하나를 더 작성하는 것뿐이다.

二、권한 모델: 기어가 스위치보다 유용하다

Agent가 일을 하려면 권한이 있어야 한다. 권한을 주는 일에 대해, 나는 두 가지 전형적 방식을 봤다.

첫째는 이원 스위치 : 전부 열거나(어떤 명령이든 실행 가능), 전부 닫거나(채팅만 가능). 이 설계의 경험은: 전부 열면 마음이 불안하고, 전부 닫으면 아무것도 못 한다.

둘째는 건별 승인 : 매 명령마다 팝업으로 물어본다. 안전감은 최대지만, 반나절 쓰면 무너진다——승인 피로에 빠지면 무작정 "허용"을 누르기 시작하고, 안전성은 오히려 전부 여는 것보다 낮아진다.

OpenWorkBuddy는 세 번째를 쓴다: 4단계 권한 기어.

text

plan → 읽기만 하고 쓰지 않음, 보고 계획만 세울 수 있음 ask → 핵심 동작 전 동의를 구함 auto → 통상 작업은 자동 실행, 고위험 동작은 여전히 차단 full → 완전 개방

이 설계가 흥미로운 지점은, 그것이 "권한 부여"를 일회성 스위치 결정이 아니라, 작업에 따라 전환되는 연속 변수로 만든다는 것이다.

여기서 주목할 디테일이 하나 있다——그것은 전역 설정이 아니라, 호출할 때마다 개별 지정할 수 있다 :

bash

openworkbuddy --perm plan "이 데이터를 분석해서 어떤 결론을 얻을 수 있는지" openworkbuddy --perm full "프로젝트를 실행하고, 스스로 오류를 고쳐"

차이가 뭔가? 내가 Agent에게 글 한 편을 읽고 요약을 쓰게 할 때는, plan이면 충분하다. 그것은 쓰기 권한조차 가져서는 안 된다. 반면 버그를 자동으로 고치게 할 때는, full이 필요한 대가다.

같은 사용자라도, 작업마다 필요한 신뢰 수준이 완전히 다르다. 권한을 사용자에게 묶는 것(모두 열거나 모두 닫거나)보다, 작업에 묶는 게 낫다.

이 관점은 많은 Agent 제품 설계로 확장할 수 있다고 본다. 권한의 입도는 "이 사용자를 믿을 수 있는가"가 아니라, "이 동작을 믿을 만한가"여야 한다.

또한 여기에는 기어와 병행하는 게이트 메커니즘 한 층이 더 있다: 명령 승인, 파일 블랙리스트, URL 화이트리스트, 감사 로그.

기어가 관리하는 것은 "이번 라운드에 얼마나 큰 자유도를 주느냐"이고, 게이트가 관리하는 것은 "어떤 동작은无论如何(어떤 경우에도) 허용하지 않는다"이다. 기어는 완화할 수 있지만, 게이트는 돌파할 수 없다 ——이 두 층을 분리하는 것이, 하나의 "보안 등급"으로 뭉치는 것보다 명료하다고 생각한다.

三、플러그인 진입점: 저평가된 리스크 표면

세 번째 문제는 좀 더 분명히 얘기하고 싶다. 구체적인 보안 설계와 관련되기 때문이다.

OpenWorkBuddy의 확장 방식은 Markdown 파일 하나를 skills/ 디렉터리에 떨구는 것이다. 이게 경험상 가장 편안한 지점이다——능력을 추가하는 데 코드를 고칠 필요도, 재시작할 필요도, 패키징할 필요도 없이, 저장하고 나면 다음 작업부터 바로 효력이 난다.

그런데 이 설계에는 숨은 전제가 하나 있다: 이 디렉터리에 파일을 넣는 사람을 신뢰한다는 것.

왜냐하면 skill이 본질적으로 뭔가? 낯선 사람이 쓴 자연어 지시문 한 조각을, 사용자 머신에서 명령을 칠 수 있는 Agent에 연결하는 것이다.

이 조합의 리스크 등급은, 내가 보기에 많은 사람이 생각하는 것보다 높다. 그것은 "텍스트 한 조각을 읽었다"는 그런 단순한 게 아니다——텍스트가 행동으로 변한다.

그래서 이 프로젝트는 설치 전에 정적 검사 한 층(34개 규칙)을 하는데, 그중 10개는 실제로 막는다: 리버스 셸, curl | bash , SSH 개인키 읽기, 디스크 삭제, 흔적 제거 같은 것은 곧바로 차단하고, 나머지는 원문을 사용자에게 그대로 펼쳐 보여준다.

하지만 진짜로 나를 흥미롭게 한 것은, 이 검사기가 무엇을 했느냐가 아니라, 그것이 자신을 어떻게 설명하느냐다.

프로젝트는 자신의 검출률을 공개적으로 명시했다: 공개 라벨링 세트에서 약 74.9% , "설치를 권장하지 않음" 판정의 정확도 약 60.1% ——쉽게 말해, 네 개 중 하나를 놓친다 .

그리고 내가 아주 실질적이라고 생각하는 설명을 한 줄 붙였다:

이것이 정적 검사의 천장이고, 이것이 강제 설치 진입점을 반드시 남겨야 하는 이유다.

이 한마디가 설계의 트레이드오프를 명확히 짚는다.

정적 검사는 본질적으로 패턴 매칭으로 적대적 목표를 쫓는 것이다——악성 지시문은 표현을 바꿀 수 있고, 난독화할 수 있고, 여러 파일에 분산될 수 있다. 공격 표면이 적대적이기만 하면, 검출률은 100%로 수렴할 수 없다. 이를 인정하고, 그에 근거해 "사용자 강제 설치" 구멍을 남기고, 동시에 리스크를 명확히 알리는 것——이것이 "우리는 악성 플러그인을 전면 차단했다"고 선언하는 것보다 책임감 있다.

나는 적지 않은 프로젝트가 보안 능력에 대해 "XX 방어를 지원함"이라고 표현하면서, 구체적 검출률이 얼마인지, 오판율이 얼마인지 한 글자도 언급하지 않는 것을 봤다. 사용자 입장에서 이런 모호한 표현은, 오히려 "나는 74%밖에 안 된다"고 명확히 쓰는 것보다 평가하기 어렵다——얼마나 신뢰를 줘야 할지 모르기 때문이다.

정량화 가능한 능력 경계를 제시하는 것 자체가 제품 성숙도의 일부다.

덧붙여 구현 디테일 하나: 그 검사 로직은 키워드가 아니라 행위 조합 에 기반한다. 단독 curl은 문제가 아니고, 단독 printenv도 문제가 아니다; 그러나 같은 파일에서 키를 읽고 동시에 외부로 전송하는, 완전한 유출(exfiltration) 특징이 구성될 때만 막는다.

이 발상은 단순 블랙리스트보다 영리하다——블랙리스트의 문제는 오탐이 높고 우회가 쉽다는 것인데, "민감 데이터 읽기 + 외부 전송"이라는 행위 조합으로 판정하면 견고성이 훨씬 좋아진다.

四、곁다리로 본 몇 가지 엔지니어링 디테일

위 세 덩어리를 다 쓴 뒤에도, 자잘한 점 몇 개가 기록할 만하다. 결론은 아니고, 관찰이다.

확장 비용의 하한. 위에서 언급한 skill 메커니즘은, 내 생각에 2차 개발자에게 주는 가치가 저평가되어 있다. 전통적 플러그인 체계는 먼저 manifest를 정의하고, 훅을 등록하고, 라이프사이클을 거쳐야 한다; Markdown 스킬은 이 모든 걸 건너뛴다. 대가는 표현력 제한이고, 이득은 거의 마찰 제로다. "사용자가 스스로 능력을 만들게 하고 싶은" 제품에게 이 트레이드오프는 이득이다.

배포 스크립트는 성공을 가식하지 않는다. 그것의 Docker 배포 스크립트는 헬스 체크가 실제로 통과할 때까지 기다렸다가 성공을 보고하고, 안 뜨면 로그를 뽑아 보여준다. 사소한 일이지만, "배포 실패 시 실패를 명확히 알려주기"는 많은 프로젝트에서 추가로 해야 하는 작업이다.

"퇴사 클로즈드 루프"라는 기능이 존재한다는 사실 자체. 그것은 직원 퇴사 시 닫아야 할 진입점을 나열한다: QR로 연결된 기기, 명의의 예약 작업, 사용하지 않은 초대 코드, 연동된 2차 인증, 실행 중인 작업. Agent가 스스로 작업을 실행하고, 스스로 기기를 연결할 수 있게 되면, 그것은 관리가 필요한 주체가 된다. "퇴사 시 어떻게 그것을 회수하는가"라는 문제는, 내 생각에 Agent가 기업 시나리오로 나아갈 때 반드시 답해야 하는 것인데, 이 프로젝트는 오픈소스 버전에서 이미 답을 내놓았다.

실행 과정에 로컬 Trace가 있다. 모델, 도구, 소요 시간, Token, 입출력이 전부 로컬에 기록되고, 선택적으로 Langfuse를 연동한다. 프롬프트를 조정하는 사람에게 이건 로그보다 유용하다.

五、내가 여기서 추출한 세 가지

딱 세 마디만 가져간다면:

1. 검수 기준은 개조 대상 위에 놓여야 한다

집행자의 자기 진술 위에 놓아서는 안 된다. 모델이 완료했다고 해도 완료가 아니고, 디스크에 파일이 존재해야 완료다. 이 원칙은 모든 Agent 산출물에 적용된다.

2. 권한의 입도는 사용자가 아니라 작업에 묶여야 한다

기어로 연속적 신뢰 수준을 표현하고, 게이트로 절대적 하한선을 지킨다. 둘을 분리해서 설계한다.

3. 보안 능력은 정량적 경계를 과감히 제시해야 한다

"나는 74%밖에 안 된다"고 명확히 말하는 것이, "나는 전면 방어한다"고 말하는 것보다 더 신뢰할 만하고, 더 유용하다.

프로젝트 자체에 대해, 몇 마디 필요한 정보를 덧붙인다. 광고 글처럼 보이지 않도록.

그것은 2026-08-10에 저장소를 만들었고, 최신 커밋은 2026-09-18이며, 40일 동안 수십 차례 반복했고, star 159. JavaScript로 작성했고, Node 18+에서 바로 실행되며, 제로 빌드다. 라이선스는 PolyForm Noncommercial——개인, 학습, 비영리는 무료, 상용은 라이선스가 필요하다. 라이선스를 구매해도 기능이 잠금 해제되지 않는다 , 왜냐하면 코드가 한 벌뿐이고, 기능 스위치나 회색 버튼이 없기 때문이다.

배포에는 세 가지 경로가 있다: 로컬 설치(5단계 마법사), VPS + Docker(한 줄 명령), 기업 도입(SSO / 감사 외부 전송 / 내부망 / SLA).

코드를 읽고 싶다면, server.js로 들어가서, 이어서 agent.js가 모델과 도구를 어떻게 편성하는지 보면 된다. 핵심 로직은 길지 않다.

git clone https://github.com/CatCatUncle/openworkbuddy.git cd openworkbuddy && npm install && npm run app

이 글의 모든 데이터는 저장소 공개 정보에서 가져왔으며, 수집 시점은 2026-09-19이다.

당신도 Agent 관련 작업을 하고 있다면, 특히 위의 "파일 검수" 부분에 다른 실천이 있다면, 댓글로 얘기 나누자——내가 더 궁금한 것은 다른 사람들이 이 문제를 어떻게 푸는가다.