멀티 에이전트 구조에서 에이전트 간 HTTP 평문 통신을 관찰하고, 에이전트의 내부 처리 과정(prompt / tool-call / response)이 네트워크 메시지 형태로 어떻게 외부에 드러나는지를 확인합니다.
- Agent 내부 처리 흐름과 네트워크 메시지의 대응 관계 이해
- HTTP payload 내 JSON 필드 의미 분석
- prompt / tool-call / response 구분
agent-http/
├── agent_a/ # Agent A (Client)
│ ├── agent_a.py
│ └── Dockerfile
├── agent_b/ # Agent B (Server)
│ ├── agent_b.py
│ └── Dockerfile
├── tool_server/ # Tool Server
│ ├── tool_server.py
│ └── Dockerfile
├── data/ # 공유 데이터
│ └── hello.txt
├── docker-compose.yml
├── requirements.txt
└── README.md
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Agent A │────────▶│ Agent B │────────▶│ Tool Server │
│ (Client) │ HTTP │ (Server) │ HTTP │ │
└──────────┘ └──────────┘ └──────────────┘
│ │ │
│ [PROMPT] │ [TOOL-CALL] │
│ │ │
│◀───────────────────│◀──────────────────────│
│ [RESPONSE] │ [TOOL-RESPONSE] │
- Agent A: 환경변수
PROMPT로 입력을 받아 Agent B에게 전달 - Agent B: prompt를 분석하여 규칙 기반으로 tool 선택 (prompt에 'file' 있으면 read_file, 없으면 echo)
- Tool Server: Agent B의 요청에 따라 tool 실행
1. Prompt (Agent A → Agent B)
2. Tool-Call (Agent B → Tool Server)
3. Response (Tool Server → Agent B → Agent A)
docker-compose up --build- Wireshark 실행
- 인터페이스: "Adapter for loopback traffic capture" 선택
- 필터:
tcp.port == 5001 || tcp.port == 5002 - 캡처 시작
PowerShell에서:
$body = @{prompt="Please read the file"; from="agent_a"; timestamp=[DateTimeOffset]::UtcNow.ToUnixTimeSeconds()} | ConvertTo-Json
Invoke-WebRequest -Uri http://localhost:5001/process -Method POST -Body $body -ContentType "application/json"연두색 HTTP 패킷 4개:
- POST /process (포트 5001) A -> B
- POST /tool/read_file (포트 5002) B -> Tool Server
- HTTP 200 OK (포트 5002) Tool Server -> B
- HTTP 200 OK (포트 5001) B -> A
$body = @{prompt="Hello test"; from="agent_a"; timestamp=[DateTimeOffset]::UtcNow.ToUnixTimeSeconds()} | ConvertTo-Json
Invoke-WebRequest -Uri http://localhost:5001/process -Method POST -Body $body -ContentType "application/json"캡처 방법: Wireshark에서 HTTP 패킷 선택 → Follow → HTTP Stream
분석 내용:
Prompt 단계 (POST /process):
{
"from": "agent_a", // 발신자
"timestamp": 1768102409, // 요청 시각
"prompt": "Please read the file" // 사용자 입력
}Tool-Call 단계 (POST /tool/read_file):
{
"tool_name": "read_file", // 선택된 tool
"parameters": {
"filename": "hello.txt" // tool 매개변수
}
}Response 단계: 사진 아래쪽의 파란색 부분을 보면 성공적으로 작동했다는 것을 확인할 수 있다.
비교 내용:
| Prompt | URL | tool_name | parameters |
|---|---|---|---|
| "Please read the file" | /tool/read_file |
"read_file" |
{"filename": "hello.txt"} |
| "Hello test" | /tool/echo |
"echo" |
{"message": "Hello test"} |
관찰: prompt에 'file' 키워드 유무에 따라 Agent B가 다른 tool을 선택하고, 이는 HTTP 요청의 URL과 JSON payload로 드러남
컨테이너 중지 및 제거:
docker-compose down이미지까지 삭제하려면:
docker-compose down --rmi all에이전트의 내부 처리 과정(prompt 분석, tool 선택)이 네트워크 메시지로 드러남을 확인:
- Prompt → HTTP POST 요청의 JSON body
- Tool 선택 로직 → HTTP 요청의 URL과 JSON payload
- Tool 실행 결과 → HTTP 응답의 JSON body
모든 내부 처리 과정이 네트워크 패킷 레벨에서 관찰 가능함을 확인.
- 처음에는 Docker 내부 네트워크(172.18.0.x)를 직접 캡처하려고 했는데 이유는 모르겠지만 잘 안됐다.
- 그래서 일단 호스트 포트(5001, 5002)를 통해 통신을 캡쳐했다. 나중에 왜 안됐는지 찾아봐야겠다.





