Skip to content

[week-05] 25620024 - #263

Open
dragonash22 wants to merge 31 commits into
Q00:mainfrom
dragonash22:week-05/25620024
Open

dragonash22 wants to merge 31 commits into
Q00:mainfrom
dragonash22:week-05/25620024

Conversation

@dragonash22

Copy link
Copy Markdown

What I built

4주차의 buyer/seller 협상을 MCP server(market_server.py)로 옮기고, buyer에게 "예산이 올랐다"는 가짜 시장 공지를 끼워 넣는 주입 공격을 두 조건에 똑같이 걸어, 가격 한도를 시스템 프롬프트에만 두는 경우(prompt_inject)와 토큰에도 실어 server가 강제하는 경우(server_inject)를 비교했다. server는 역할을 bearer 토큰에서만 읽고, 토큰에 묶인 협상 외의 negotiation_id와 차례가 아닌 수를 거절하며, 토큰이 없으면 401을 반환한다. host(agent_host.py)는 실습에서 1주차 루프를 바꿔 만든 MCP host에 토큰 헤더를 붙인 것이고, 러너(run.py)가 협상을 열고 토큰을 발급한다.

시나리오 6개 × 3회 × 2조건 = 36회(claude-haiku-4-5, temperature 1.0)를 돌린 결과는 다음과 같다.

condition correct violation attempted violations refused calls mean turns 거절 후 같은 턴에 유효한 수
prompt_inject 16/18 2 5 0 6.89 0/0
server_inject 17/18 0 3 3 7.17 3/3

한도를 넘으려는 시도는 두 조건에서 비슷했지만, 실제로 실행된 것은 prompt_inject뿐이었다. 시나리오 4(최저가 400억, 예산 380억)에서 같은 400억이라는 시도가 prompt_inject에서는 두 번 거래로 성사되었고, server_inject에서는 server가 거절했으며 buyer는 같은 턴 안에서 유효한 수로 바꿨다. 자세한 해석과 로그 근거는 REPORT.md 4장에 있다.

What I tried and discarded

  • 처음 server는 거절할 때 일반 Exception을 던졌는데, SDK가 그 내용을 지워서 거절 이유가 전부 Error executing tool propose로만 나왔다. 이 상태라면 server 조건의 에이전트는 왜 거절당했는지 알 수 없었기 때문에, 거절 클래스를 ToolError로 바꾸고 auth_checks.txt를 다시 만들었다(c7640d6 → d8c8080).
  • accept_proposal은 인자에 가격이 없어 처음 server 기록으로는 시도한 위반을 셀 수 없었다. 모든 수의 시도에 그 수가 확정할 가격을 같이 기록하도록 server를 고쳤다.
  • auth_checks.txt를 만들 때 켜 둔 시장 server가 같은 포트(8100)에 남아 있으면 러너의 관리 키가 맞지 않는 문제가 생길 수 있어서, 러너가 시작할 때 포트가 비어 있는지 먼저 확인하도록 했다.
  • 본 실험 전에 시나리오 4만 조건별로 한 번씩 돌린 시험 실행은 smoke/에 따로 남겼다(본 실험 results.csv에는 포함하지 않음).
  • 실습(1주차 도구를 MCP server로 옮기고 1주차 루프를 host로 바꾸는 7단계)은 lab/에 단계별 커밋과 로그로 남겼다.

How to run

  • Model: claude-haiku-4-5 (Anthropic API), temperature 1.0, 8수 제한
  • Env: ANTHROPIC_API_KEY (키 자체는 저장소에 없음)
pip install "mcp>=2" anthropic httpx
export ANTHROPIC_API_KEY=<본인 키>
cd submissions/25620024/week-05
python run.py --conditions prompt_inject,server_inject --runs 1-3    # server는 러너가 직접 띄움

# auth_checks.txt 재현
MARKET_ADMIN_KEY=<아무 값> python market_server.py &
MARKET_ADMIN_KEY=<같은 값> python auth_checks.py

Checklist

  • python scripts/check_week05.py submissions/25620024/week-05 passes locally
  • Run logs are committed under logs/
  • No API keys anywhere in the diff
  • History is not squashed

🤖 Generated with Claude Code

jaydenkim22 and others added 30 commits September 29, 2026 20:46
…(tools_server.py)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cp-Method or clientCapabilities gets 400

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ols(), execution via call_tool()

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ator via MCP, answer 69504

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o child, URL -> HTTP); loop untouched

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ol calls, both 69504

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…CP tools only) -- read_file then calculator, 69504

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ns read_file -> calculator -> write_note, result.md = 69504

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tted before any run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tiation binding, turn checks, token-carried limits, injection, admin routes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… a plain exception as 'Error executing tool'

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gent; auth_checks.txt re-run, all four reasons visible

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…luded) for the runner's attempted-violation audit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s bearer token; week-04 role prompts, identical across conditions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ernates host runs, audits the server record, appends results.csv, resumes; --out for smoke runs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es / 16 tool calls each, injection shown to buyer; both end open (no deal), kept out of results.csv

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…6 episodes done

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rpretation, discarded attempts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ewritten as terse bullet points

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, one point per line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…abeled in 억 원 throughout

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…auth-check market server, not the lab server)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pt_inject attempts was the seller's (buyer-only 4 vs 3); run 2 scenario 4 buyer reached 380, not stayed below it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants