8장. 보안 - 안전한 도구 실행
왜 안전한 도구가 필요한가 — 주문번호만 알면 누구 주문이든 보인다
한 줄 요약
7장까지 만든 도구는 필요한 정보를 조회할 수 있지만, 접근 권한을 확인하지 않습니다. 주문번호만 알면 다른 고객의 주문 정보도 조회할 수 있습니다. 이번 장에서는 로그인한 고객 본인의 주문만 조회하고 처리할 수 있도록 도구를 수정합니다. 완성한 도구는 이후 장에서도 사용할 수 있도록 haru_tools.py 모듈로 정리합니다.
1. 지금 도구에 물어볼 질문
6장의 get_order_status를 다시 봅니다.
def get_order_status(order_id: str) -> dict:
row = ORDERS[ORDERS["order_id"] == order_id]
if row.empty:
return {"found": False, ...}
r = row.iloc[0]
return {"found": True, "order_id": r["order_id"], "product_name": r["product_name"], ...}
주문번호가 orders.csv에 있기만 하면 상품명, 옵션, 결제 금액, 주문 일시를 돌려줍니다. 묻는 사람이 누구인지는 어디에서도 확인하지 않습니다.
채팅창에 누군가 이렇게 입력했다고 합시다.
"주문 HR20260620024 상태 알려주세요."
이 주문은 그 사람의 것이 아닙니다. 다른 고객(C013)의 주문입니다. 지금 도구는 그대로 답합니다.
주문번호는 비밀이 아닙니다. 택배 상자에 붙어 나가고, 캡처 화면에 찍혀 돌아다닙니다. HR + 날짜 + 일련번호라는 규칙이 있어 짐작해서 넣어 볼 수도 있습니다.
번호를 아는 것과 볼 자격이 있는 것은 다른 문제입니다. 지금 도구는 그 둘을 구분하지 못합니다.
2. 에이전트라서 더해지는 것
식별자만 알면 남의 데이터가 열리는 문제는 LLM이 나오기 전부터 있던 문제입니다. 에이전트에서는 여기에 한 가지가 더해집니다.
도구를 부르는 것이 사람이 아니라 모델입니다. 그리고 모델은 고객이 한 말을 근거로 도구의 인자를 채웁니다. 고객이 무슨 말을 하든 그것이 인자가 될 수 있습니다.
| 누가 | 하는 일 | 믿을 수 있는가 |
|---|---|---|
| 고객 | 채팅창에 글을 쓴다 | 무엇이든 쓸 수 있습니다 |
| 모델 | 그 글을 읽고 도구와 인자를 고른다 | 고객의 글에 끌려갑니다 |
| 도구(우리 코드) | 받은 인자로 데이터를 읽는다 | 여기서 막아야 합니다 |
3. 이번 장에서 다루는 네 가지 위험
| 위험 | 지금 상태 | 이번 장의 처방 |
|---|---|---|
| 남의 주문 조회 | 주문번호만 맞으면 보여 준다 | 로그인한 고객의 주문만 보여 준다 |
| 개인정보 노출 | 도구가 준 값은 그대로 답에 나올 수 있다 | 모델에게 주기 전에 가린다 |
| 쓰기 도구의 부작용 | 아직 쓰기 도구가 없다 | 되돌릴 수 있는 것만 도구로 만든다 |
| 도구가 죽는다 | 뜻밖의 입력에 예외가 난다 | 어떤 경우에도 값을 돌려준다 |
네 가지를 꿰는 원칙은 하나입니다.
안전은 모델에게 부탁해서 얻는 것이 아니라 코드의 구조로 만든다.
시스템 프롬프트에 "남의 주문을 보여 주지 마라"고 적는 것은 부탁입니다. 3장에서 본 것처럼 프롬프트는 모델의 행동을 꽤 잘 바꾸지만, 매번 지켜진다고 보장하지는 못합니다. 도구가 남의 주문을 애초에 돌려주지 않게 만드는 것은 보장입니다.
4. 이걸 모르면 무엇을 판단하지 못하는가
- 도구의 인자를 정할 때 무엇을 인자로 받아도 되고 무엇은 받으면 안 되는지 가려내지 못합니다.
- "프롬프트에 금지라고 썼으니 됐다"와 "코드가 막고 있다"의 차이를 설명하지 못합니다.
- 어떤 기능을 도구로 만들어도 되는지, 만들지 말아야 하는지 정할 기준이 없습니다.
5. 이번 장에서 만드는 것
파일을 두 개 만듭니다.
| 파일 | 역할 |
|---|---|
haru_tools.py |
안전장치를 갖춘 도구 모듈. 9장부터 24장까지 대부분의 장이 이 파일을 불러 씁니다 |
lesson08_safe_tools.py |
그 안전장치가 실제로 막는지 확인하는 파일 |
지금까지의 lesson…py 파일은 그 장에서 실행하고 끝나는 파일이었습니다. haru_tools.py는 다릅니다. 이름에 번호가 없는 것은 앞으로 계속 쓰는 부품이기 때문입니다.
핵심 정리
- 7장까지의 도구는 주문번호만 알면 누구의 주문이든 보여 줍니다.
- 모델은 고객의 말을 근거로 인자를 채웁니다. 그래서 막는 일은 도구 코드가 해야 합니다.
- 이번 장의 위험은 남의 주문 조회, 개인정보 노출, 쓰기 도구의 부작용, 도구의 예외 네 가지입니다.
- 부탁은 프롬프트에, 보장은 코드에 둡니다.
- 산출물은 이후 모든 장이 쓰는 모듈
haru_tools.py입니다.