프롬프트 엔지니어링

텍스트, 확률, 코드. 그 사이에서 진동하며 컨텐츠를 생성하는 이야기를 담아냅니다.
eval is not evil (with LLM)
아래의 글을 먼저 읽고 오면 글의 제목과 맥락을 이해하기 쉽습니다. eval()? eval() 함수는 다양한 스크립트 언어에서 제공하는 기능으로, 문자열 형태로 작성된 코드를 실행할 수 있는 함수입니다. JavaScript, Python, PHP, Ruby 등에서 공통적으로 존재하며, 문자열을 그대로 가져와서 코드로 실행이 가능한 만큼 강력한 도구이지요. 하지만 그동안 eval은 위의 레퍼런스에서처럼 사악한 사술로 비추어졌습니다. python에서는 단일식만 처리가 가능한 eval()과 여러 문의 코드를 처리하는 exec()이 구분됩니다. 하지만, 이 글에서는 같은 맥락의 함수로 여기겠습니다. eval() is evil? 이렇게 강력한 도구가 왜 위험한 것을 넘어서, 사용하는 것 자체에도 '사악하다'는 오명이 붙었을까요? 가장 큰 문제는 보안 취약점입니다. eval()은 문자열로 전달된 내용을 그대로 실행하는 함수입니다. 그렇기에 입력이 정확하게 통제되어야 안전한 사용임을 전제로 하지요. 이런 함수가 문제가 되는 상황은 어떤 상황일까요? 외부에서 임의로 입력된, 신뢰할 수 없는 데이터를 실행하는 경우입니다. 이런 특성은, '사용자를 절대로 믿지말라'고 가르치는 웹 개발에서 특히 문제가 됩니다. 임의의 유저가 어떤 입력을 가져올 지 모르는 일이고, 이를 그대로 믿어서는 안되니깐요. 예를 들어, 사용자가 입력한 문자열을 그대로 eval()로 처리하면, 공격자는 이를 악용해 시스템 명령어를 실행하거나 데이터를 탈취할 수 있습니다. XSS이나 RCE 같은 심각한 공격에 노출될 위험도 있죠. 문자열로 받은 코드를 실행하기에 생기는 문제도 있습니다. 그대로 실행하기엔 사전에 성능 평가나, 디버깅도 어렵습니다. 문제가 생긴다면, 이를 잘 캐치할 수 없죠. 이를 보면, eval() 자체의 문제이기보다는 eval() 함수가 사용되는 환경을 둘러싼 문제에 가깝지 않으신가요? eval() 자체는 강력한 도구이지만, 런타임에서 항상 불안함을 가지고 있던 eval()이었고, 비교적 개방적인 웹 생태계였기에 이런 분위기가 형성된 것이라고 봅니다. 사실 아래와 같은 "eval is evil but not why you may think"와 같은 글에서도 eval 자체의 문제라기 보다는 시스템의 문제이기에 적확하게 사용하면 된다고 하지만, 그럼에도 불구하고 "This is just horrible advice"와 같은 댓글이 달리기도 하죠. eval() with llm's output?
  • T
    Two_Jay
👍
2
할루시네이션은 '에러'인가? : 뒤집어 생각해보기
(앞 생략) 그래서, 저희가 서비스를 개발할 때에는 할루시네이션이 기본적으로 에러가 아닌, 기능이라는 관점을 가지고 접근을 했습니다. (이하 생략) 이게 무슨 소리지? 싶었습니다. 아마 그 시점으로부터 2-3개월만 앞으로 당겼어도 말도 안된다면서 고개를 내저었을지도 몰랐죠. 그때의 저는 특정 데이터에 기반해서 문제를 내고 개념을 가르치는 교사 Agent를 개발하고 있었으니깐요. 그렇다면 지금은? 지금은 확실히 다릅니다. 위의 이야기를 이해하고 나니, LLM으로 하는 창의적인 작업에 대해서 경계가 한꺼풀 허물어지고 구현에서 자유함을 경험할 수 있었습니다. 형식을 탈피하고, 스스로 설정한 구현의 경계라는 억압에서 해방되었죠. 사실 위의 대사는 제가 한 말이 아니고, 'Zeta'를 서비스하고 있는 스캘터랩의 김종윤 대표님의 이야기입니다. SK AI Summit 2024에서 가장 저에게 충격적인 멘션이고, 지금도 여운이 남는 멘션이었습니다. 현상이 에러가 되기 위해서는 할루시네이션은 항상 모든 케이스에서 에러와 이어지는가? 사실 거의 모두가 곧잘 그렇게 생각합니다. ChatGPT에서 세종대왕이 맥북을 던지기 시작한 이래로, '사실과 틀리고, 말이 안되는 정보'를 출력하는 현상은 LLM의 대표적인 문제점이 되었습니다. 주어진 문제에서 얼마나 말이 안되는 말을 하는지가 LLM 성능의 척도가 되었고, 말이 안되는 응답은 웃음거리가 되기도, AI포비아의 근거가 되기도, 아니면 고소장의 주요 요인이 되기도 했죠. 이를 극복하기 위한 수단으로써 RAG가 독립적이면서 확고한 기술 스텍으로 성장한 계기가 되었구요. 하지만 돌이켜보면 할루시네이션이 문제라고 지적하는 맥락에서는, 몇 가지 전제가 있었습니다. 첫째, LLM이 생성하는 콘텐츠는 사실적이고 정확해야 한다는 기대가 있었습니다. ChatGPT 출시 이후부터 지금까지 LLM이 지속적으로 발전하면서, 생성하는 콘텐츠는 인간이 작성한 것과 동일하거나 그 이상의 정확성과 신뢰성을 가져야 한다는 기대감도 함께 커졌습니다. 둘째, LLM을 사용하는 유저는 LLM의 응답을 신뢰하고 그 정보를 기반으로 의사 결정을 내릴 수 있다는 전제입니다. 유저들은 LLM의 응답을 비판적으로 검토하기보다는, 그 정보를 그대로 수용하고 의사 결정에 활용할 수 있다는 전제가 깔려 있었습니다. 이는 달리 말하면 LLM은 어떤 특정한 정보를 기반으로 신뢰할 수 있고 믿을만한 컨텐츠를 제공할 것이라는 기대가 있었습니다. 유저가 아닌 LLM이 컨텐츠의 주도권과 방향을 결정하는 핸들을 잡고 있는 셈이었죠.
  • T
    Two_Jay
👍
2
'엔지니어를 위한 실무 프롬프트 엔지니어링 오프라인 수업' 후기
얼마 전에 '엔지니어를 위한 실무 프롬프트 엔지니어링 오프라인 수업' 을 들었습니다. 지금 다니고 있는 DNSoft에서 물심양면으로 지원해주셔서 좋은 기회에 부담 없이 배울 수 있었습니다. 듣기 전 강의를 듣기 전 8월 즈음에 저는 고민에 빠진 상태였습니다. 지금보면 엄청나게 오만하고 자만한 고민이었지만요. "음. LLM은 대충 이해가 가고 프롬프트. 이제 혼자서 쓰고 테스트하고 얼추 회사에서 요구하는 사항은 맞추어서 구현할 수 있는데 이 커리어에서 더 성장할 여지가 있나?" 회사에서 프롬프트 엔지니어라는 직무로 6개월 동안 구르고 나니, 일이라는 게 손에 익은 상태였고, 얼추 감 잡고 스스로 무언가 해볼 수 있는 상태였었습니다. 자연스럽게 제 관심사는 '이것 말고 뭐가 더 있지?'라는 생각으로 쏠리기 시작했습니다. 이제와 되돌아보면 스스로에게 사생결단(?)같은 시간이 필요했던 것 같습니다. 저 또한 GPT의 등장에 적잖히 충격을 먹었고, GPT 3.5와 4가 나올 때 부터 프롬프트 엔지니어링 직무를 준비했습니다. 1월부터 실제 직무에서 일하고 있는데 1년도 채 안되는 시간에 천장에 부딫힌다면, 아무리 참신하고 새로운 직무라도 그 한계가 명확하다고 인정할 수 밖에 없었습니다. 그래서 저는 궁금했습니다. 프롬프트 엔지니어가 제가 아는 선에서 더 성장 가능할지. 프롬프트 엔지니어링이 어디까지 갈 수 있는지를요. 그러던 차에 뤼튼에서 프롬프트 엔지니어였던 강수진님이 강의를 연다는 소식에 열리는 당일 등록을 했었습니다. '이런 고민을 가지고 있는데, 이 일을 우리나라에서 가장 처음 시작한 사람이라면 뭔가 다른 시각에서 문제를 바라보고 있지 않을까?' 라는 생각이 들자마자 수강 결정을 했고, 그 결정은 옳았습니다. 들으면서
  • T
    Two_Jay
2
👍
3
Let's think step by step - "얘 안되던데요?"
"Let's think step by step" '단계적으로 생각해'. 프롬프트에서 자주 찾아볼 수 있는 구문입니다. 이젠 어떤 레거시 프롬프트든 볼 때면 자연스럽게 들어와 있는 구문이기도 하죠. 마치 마법의 주문, 그도 아니면 MSG와 같이 넣어주고 있는 구문이기도 합니다. 저도 자주 쓸까요? 네. 저도 자주 씁니다. 하지만 대부분의 프롬프트 전략은 장단이 있고, 적절하게 사용해야할 때가 있습니다. 실제 사례를 볼까요? 사례 1. 카드게임 봇을 llm으로 하는 프로젝트의 피드백을 해드린 적이 있습니다. "얘가 자기 턴에 낼 카드를 판단할 때 좀 정확하게 상황을 판단했으면 좋겠어요!" 프롬프트를 보고 있으니, 가지고 있는 카드를 순수하게 LLM의 인퍼런스에만 맡겨서 내도록 했습니다. 아래와 같이 프롬프트를 수정하도록 권고했었습니다. 피드백이 만족스러웠는지 몇 주 뒤, 자신들이 한 사이드 프로젝트를 보여주러 왔습니다. 현재 게임 상황에 대해 프롬프트에 넣어서, Let's think step by step을 이용해서 현재 상황에 대한 판단을 먼저 수행하도록 하세요. 그 판단의 결과를 먼저 출력하고, 이후에 낼 카드를 출력하도록 하시면 되어요. 그러면 일단은 조금 더 나은 결과를 보여줄 겁니다. 사례 2. 챗봇 서비스에 사용될 프롬프트를 고치는 중이었습니다. 분명히 1줄로 응답을 출력하게 하는 시스템 프롬프트인데, Let's Think Step by Step이라는 출력이 노이즈로 나오고 있었습니다. 제대로 동작이 안되어서 찾아온 프롬프트를 보고나니, 1줄로 출력하라는 명령이 3번. Let's Think Step by Step라는 구문이 2번 등장하고 있었습니다. 원래 기대했던 성능은 달성하지 못하는 것은 물론이었습니다. 프롬프트를 수정할 시간이 되자, 망설임없이 Let's Think Step by Step를 모두 지우고, 1줄로 출력하라는 명령은 1번만 남겼습니다. 하나는 잘 작동한 사례, 하나는 잘 작동하지 않은 사례입니다. 무엇이 이 결과를 갈랐을까요?
  • T
    Two_Jay
👍🏻👍
2
늦은 피드백 : prompt engineer가 되고 싶은 이에게
시작하기 전에 : 사실 이 글의 주인은 따로 있다. 이제부터 이 글의 원래 주인을 A라고 할 것이다. 얼마 전 우리 회사는 3개월 계약직인 프롬프트 엔지니어를 채용했었다. 이 글의 원래 주인인 A는 그 때 지원자 중 한 분 이었다. 처음 프롬프트 엔지니어링을 시작하는 A는 정성스럽게 프롬프트 전략을 정리해온 포트폴리오까지 만들어서 가져왔다. 아쉽게 떨어지고 난 뒤, A는 나에게 개인적으로 피드백을 요청했다. 하지만, 회사 일에 쫓기던 나는 제 때 피드백을 드리지 못했다. 바빴던 일을 2~3주 동안 쳐내고 돌아와서 보니 온데간데 없었던 A였다. 피드백을 드리고 싶었지만, 연락이 닿지 않아 드리지 못했다. 그렇게 썼던 수신인 잃은 피드백의 초안은 잠들었어야 했다. 시간이 지나 다시 꺼내어보니 처음 프롬프트 엔지니어를 시작하는 분들에게 어떻게 시작해야 할 지 알려주는 좋은 글감이 될 수 있어 보이기에 편지글 형식으로 각색했다. 지원자 A님에게. 면접의 결과를 늦게나마 전달해드려서 정말 죄송하다는 말씀을 드립니다. 피드백은 신속성이 생명인데, 그러지 못하여서 가치가 떨어질지도 모른다고 생각이 들었어요. 하지만 제가 기억하고 있는 A님의 말과 도전을 되짚고 생각해보고 최대한 떠올려 이 글에 실어 보냅니다. 보내어주신 포트폴리오의 노력과, 실습과제에서의 떨림을 기억합니다. 면접에서 제가 난해하고 고민이 필요한, 어쩌면 짖궂은 질문을 던져도 조리있게 노력하여 말씀하시던 모습도 기억납니다. 그 기억을 되짚어서, 질문을 주신 내용인 피드백과 어떻게 앞으로 하시면 좋을지, 그렇게 해서 어떻게 좋은 엔지니어로 시작할 수 있는지 알려드리고 싶습니다. . . . 서슴없이 시도하기 면접 때 실습과제에서 무엇을 해보아야 할 지 망설여졌던 모습을 먼저 되짚어보고 싶습니다. 누구에게나 나의 결과물을 작성하고 공개한다는 것은 쉽지 않은 일입니다. 그것이 평가받는 자리라면 더욱 그렇고, 내가 작성한 결과물이 빠른 피드백을 받는 상황이라면 더더욱 그렇습니다.
  • T
    Two_Jay
👍🏻👍
2