팁 (조언)
포털 UI를 사용하시겠습니까? 이제 REST API를 사용하지 않고 포털에서 직접 후크를 만들고 관리할 수 있습니다. 포털은 시각적 양식 및 코드 편집기를 제공합니다.
curl 명령이 필요하지 않습니다.
이 자습서에서는 에이전트가 모든 응답에 완료 마커를 추가하도록 강제하는 중지 후크를 사용하여 사용자 지정 에이전트를 만듭니다. REST API를 통해 후크를 구성한 다음 포털의 플레이그라운드에서 테스트합니다.
예상 시간: 15분
메모
에이전트 수준 및 사용자 지정 에이전트 수준 후크: 이 자습서에서는 사용자 지정 에이전트(사용자 지정 에이전트 수준 후크)에 후크를 만듭니다. 이러한 후크는 특정 사용자 지정 에이전트가 실행되는 경우에만 발생합니다.
전체 에이전트(모든 스레드, 모든 사용자 지정 에이전트)에 적용되는 에이전트 수준 후크를 만들려면 포털에서 Builder>Hooks를 사용합니다.
| 수준 | 만드는 방법 | Scope |
|---|---|---|
| 에이전트 수준 | 포털: 빌더 > 훅 | 모든 스레드 및 사용자 지정 에이전트에 적용됩니다. |
| 사용자 지정 에이전트 수준 | REST API(이 자습서) 또는 포털: 에이전트 캔버스 > 사용자 지정 에이전트 > 후크 관리 | 하나의 사용자 지정 에이전트에만 적용됩니다. |
이 튜토리얼에서는 다음을 배우게 됩니다:
- REST API를 사용하여 중지 후크를 사용하여 사용자 지정 에이전트 만들기
- 포털의 테스트 플레이그라운드에서 후크 동작 테스트
- 감사 도구 사용을 위한 PostToolUse 후크 추가
- 정책 후크를 사용하여 위험한 명령 차단
사전 요구 사항
- 실행 중인 상태의 Azure SRE 에이전트
- curl 을 사용하여 REST API 호출
-
Azure CLI에서 액세스 토큰을 얻기 위해 로그인했습니다.
az login
후크 API 형식 이해
이 자습서에서는 REST API v2 를 사용하여 사용자 지정 에이전트에 후크를 만듭니다. 포털의 YAML 편집기 탭은 v1 형식을 표시하고 API를 통해 구성된 후크를 표시하지 않지만 후크는 여전히 활성 상태입니다. 작성기>후크 페이지 또는 테스트 실험 공간에서 확인할 수 있습니다.
팁 (조언)
API와 포털을 사용하는 경우:
- 포털 (빌더 > 후크): 시각적 형식의 에이전트 수준 후크에 가장 적합합니다. 코드가 필요하지 않습니다.
- API (이 자습서): 사용자 지정 에이전트 수준 후크, CI/CD 파이프라인 또는 프로그래밍 방식 관리에 가장 적합합니다.
에이전트의 API URL 찾기
에이전트의 API 기본 URL은 다음 패턴을 따릅니다.
https://{agent-name}--{hash}.{hash}.{region}.azuresre.ai
찾으려면 다음을 수행합니다.
- sre.azure.com 열고 에이전트를 선택합니다.
- 왼쪽 사이드바에서 작성기>에이전트 캔버스를 선택합니다.
- 브라우저의 개발자 도구를 엽니다(F12 또는 검사를 마우스 오른쪽 단추로 클릭 > ).
-
네트워크 탭으로 이동하여 "api"로 필터링하고 URL이
.azuresre.ai로 끝나는 요청을 찾습니다. - 기본 URL은 이전
/api/...의 모든 항목입니다.
또는 요소 탭에서 src 특성을 확인하세요. <iframe>의 src가 https://{agent-name}--로 시작하는 항목을 찾으세요.
액세스 토큰 가져오기
다음 명령을 실행하여 SRE 에이전트 API에 대한 액세스 토큰을 가져옵니다.
TOKEN=$(az account get-access-token \
--resource <RESOURCE_ID> \
--query accessToken -o tsv)
중지 후크를 사용하여 사용자 지정 에이전트 만들기
이 단계에서는 my_hooked_agent라는 사용자 지정 에이전트를 만들며, 응답이 === RESPONSE COMPLETE ===로 끝나는지 확인하는 Stop 후크를 포함합니다. 마커가 누락된 경우 후크는 응답을 거부하고 에이전트에 마커를 추가하도록 지시합니다.
AGENT_URL="https://your-agent--xxxxxxxx.yyyyyyyy.region.azuresre.ai"
curl -X PUT "${AGENT_URL}/api/v2/extendedAgent/agents/my_hooked_agent" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d @- << 'EOF'
{
"name": "my_hooked_agent",
"properties": {
"instructions": "You are a helpful assistant. Be concise.",
"handoffDescription": "",
"handoffs": [],
"enableVanillaMode": true,
"hooks": {
"Stop": [
{
"type": "prompt",
"prompt": "Check the agent response below.\n\n$ARGUMENTS\n\nDoes it end with === RESPONSE COMPLETE ===?\nIf yes: {\"ok\": true}\nIf no: {\"ok\": false, \"reason\": \"Add === RESPONSE COMPLETE === at the end.\"}",
"timeout": 30
}
]
}
}
}
EOF
응답 본문에서 전체 에이전트 구성을 사용하여 HTTP 202 수락 을 받습니다.
다음 예제에서는 참조를 위해 v2 YAML 형식의 동일한 구성을 보여 있습니다.
api_version: azuresre.ai/v2
kind: ExtendedAgent
metadata:
name: my_hooked_agent
spec:
instructions: |
You are a helpful assistant. Be concise.
handoffDescription: ""
enableVanillaMode: true
hooks:
Stop:
- type: prompt
prompt: |
Check the agent response below.
$ARGUMENTS
Does it end with === RESPONSE COMPLETE ===?
If yes: {"ok": true}
If no: {"ok": false, "reason": "Add === RESPONSE COMPLETE === at the end."}
timeout: 30
중지 후크의 작동 방식
중지 후크는 사용자에게 반환되기 전에 에이전트의 응답을 평가합니다.
-
$ARGUMENTS에이전트의 최종 응답을 포함하는 후크 컨텍스트 JSON으로 바꿉니다. - LLM은 프롬프트를 평가하고
{"ok": true}또는{"ok": false, "reason": "..."}을 반환합니다. - 거부된 경우 이유가 사용자 메시지로 삽입된 후에도 에이전트가 계속 작동합니다.
- 세 번의 거부(기본값) 후 에이전트가 중지됩니다.
포털에서 후크 테스트
다음 단계에 따라 중지 후크를 테스트합니다.
포털에서 귀하의 에이전트로 이동하여 생성 도구>에이전트 작업 영역을 선택합니다.
테스트 플레이그라운드 라디오 단추를 선택합니다.
Subagent/Tool 드롭다운을 선택하고 my_hooked_agent 찾은 다음 적용을 선택합니다.
채팅에
What is 2+2?을 입력하고 보내기를 선택합니다.
어떻게 되는지 보세요.
- 에이전트는 먼저 4로 응답합니다.
- 중지 후크는 응답을 평가하고 거부합니다(완료 표식 없음).
- 에이전트가 계속되는 사고 프로세스 단계가 나타납니다.
- 최종 응답이 나타납니다. 4 === RESPONSE COMPLETE ===.
후크가 작동했습니다. 중지하기 전에 에이전트가 표식을 추가하도록 강제했습니다.
감사를 위한 PostToolUse 후크 추가
에이전트에서 사용하는 모든 도구를 기록하는 PostToolUse 후크를 추가합니다. 두 후크를 사용하여 새 PUT 요청을 전송하여 동일한 에이전트를 업데이트합니다.
curl -X PUT "${AGENT_URL}/api/v2/extendedAgent/agents/my_hooked_agent" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d @- << 'EOF'
{
"name": "my_hooked_agent",
"properties": {
"instructions": "You are a helpful assistant. Be concise.",
"handoffDescription": "",
"handoffs": [],
"enableVanillaMode": true,
"hooks": {
"Stop": [
{
"type": "prompt",
"prompt": "Check the agent response below.\n\n$ARGUMENTS\n\nDoes it end with === RESPONSE COMPLETE ===?\nIf yes: {\"ok\": true}\nIf no: {\"ok\": false, \"reason\": \"Add === RESPONSE COMPLETE === at the end.\"}",
"timeout": 30
}
],
"PostToolUse": [
{
"type": "command",
"matcher": "*",
"timeout": 30,
"failMode": "allow",
"script": "#!/usr/bin/env python3\nimport sys, json\ncontext = json.load(sys.stdin)\ntool = context.get('tool_name', 'unknown')\nprint(json.dumps({'decision': 'allow', 'hookSpecificOutput': {'additionalContext': f'[AUDIT] {tool} executed.'}}))"
}
]
}
}
}
EOF
matcher: "*" 는 이 후크가 모든 도구 호출에 대해 실행한다는 것을 의미합니다. 스크립트는 도구 이름을 기록하고 대화에 메시지를 삽입합니다 [AUDIT] .
후크를 테스트하려면 에이전트에게 도구를 트리거하는 질문(예: "실행 echo hello")을 요청합니다.
위험한 명령 차단
rm -rf, sudo, chmod 777 를 차단하는 두 번째 PostToolUse 후크를 추가하십시오.
PostToolUse:
# Audit hook (runs for all tools)
- type: command
matcher: "*"
timeout: 30
failMode: allow
script: |
#!/usr/bin/env python3
import sys, json
context = json.load(sys.stdin)
tool = context.get('tool_name', 'unknown')
print(json.dumps({"decision": "allow",
"hookSpecificOutput": {"additionalContext": f"[AUDIT] {tool} executed."}}))
# Policy hook (only for shell tools)
- type: command
matcher: "Bash|ExecuteShellCommand"
timeout: 30
failMode: block
script: |
#!/usr/bin/env python3
import sys, json, re
context = json.load(sys.stdin)
command = context.get('tool_input', {}).get('command', '')
for pattern in [r'\brm\s+-rf\b', r'\bsudo\b', r'\bchmod\s+777\b']:
if re.search(pattern, command):
print(json.dumps({"decision": "block", "reason": f"Blocked: {pattern}"}))
sys.exit(0)
print(json.dumps({"decision": "allow"}))
감사 후크와의 주요 차이점:
-
matcher: "Bash|ExecuteShellCommand"는 셸 도구에서만 실행됩니다(패턴이^(Bash|ExecuteShellCommand)$로 고정됨). -
failMode: block는 스크립트 자체가 충돌하는 경우(엄격한 모드) 도구 결과를 차단합니다. - 위험한 패턴이 발견되면 이유와 함께 반환
"block"합니다.
후크 응답 형식
프롬프트 후크와 명령 후크는 다른 응답 형식을 사용합니다.
프롬프트 후크
프롬프트 후크는 간단한 JSON을 반환합니다.
{"ok": true}
{"ok": false, "reason": "Please fix X."}
명령 후크
명령 후크는 확장된 JSON을 반환합니다.
{"decision": "allow"}
{"decision": "block", "reason": "Dangerous command."}
{"decision": "allow", "hookSpecificOutput": {"additionalContext": "Audit note."}}
명령 후크는 JSON 대신 종료 코드를 사용할 수도 있습니다.
| 종료 코드 | 행동 |
|---|---|
0 출력 없음 |
Allow |
0 JSON을 사용하여 |
JSON 구문 분석 |
2 |
차단(stderr가 이유가 됨) |
| 기타 | 기본 설정으로 전환 failMode |
주의
이유가 없는 거부는 승인으로 처리됩니다. 거부할 때 reason를 항상 포함합니다.
확인
후크를 구성하고 테스트한 후 다음 조건을 확인합니다.
- REST API v2 를 사용하여 사용자 지정 에이전트 수준 후크를 구성합니다. 해당 사용자 지정 에이전트에만 적용합니다.
- Builder > 만듭니다. 전체 에이전트에 적용합니다.
- 중지 후크로 인해 에이전트가 중지하기 전에 마커를
=== RESPONSE COMPLETE ===추가합니다. - PostToolUse 감사 후크는 도구 호출에 대한 메시지를 기록합니다
[AUDIT]. - 정책 후크는 다음과 같은
rm -rfsudo위험한 명령을 차단합니다.
Troubleshooting
다음 표에서는 에이전트 후크에 대한 일반적인 문제 및 솔루션을 나열합니다.
| 문제 | 해결 방법 |
|---|---|
| 포털 YAML 탭에 후크가 표시되지 않음 | 예상 - YAML 탭에 v1만 표시됩니다. API를 통해 만든 사용자 지정 에이전트 수준 후크는 활성 상태이며 Builder>Hooks 또는 플레이그라운드에 표시됩니다. |
Unsupported kind: ExtendedAgent |
v2 엔드포인트 사용: PUT /api/v2/extendedAgent/agents/{name}. |
Handoffs cannot be null |
JSON 페이로드에 "handoffs": []를 추가합니다. |
| 후크는 효과가 없습니다. | 거부할 때 reason 필드를 포함해야 합니다. 거부가 없으면 승인으로 처리됩니다. |
| 에이전트가 무한 루프에 빠짐 | 아래쪽 maxRejections (기본값: 3, 범위: 1-25). |