목적: OpenAPI/Swagger spec을 작성할 때 graph-tool-call이 더 정확한 tool graph를 생성하도록 하는 best practice.
이 가이드를 따르지 않아도 graph-tool-call은 동작합니다. 하지만 가이드를 따르면 관계 감지 정확도가 크게 향상됩니다.
# 패턴: {action}{Resource}
paths:
/users:
post:
operationId: createUser # ✅ 동사 + 명사
get:
operationId: listUsers # ✅ list는 복수형
/users/{userId}:
get:
operationId: getUser # ✅ get은 단수형
put:
operationId: updateUser
delete:
operationId: deleteUser# ❌ 프레임워크가 자동 생성한 이름
operationId: UsersController_findAll # NestJS 스타일
operationId: users_api_get_user_by_id # 너무 길고 구조 불명확
operationId: endpoint_23 # 의미 없음효과: CRUD 패턴 감지 정확도 95% → operationId가 없으면 path에서 추론 (정확도 75%)
tags:
- name: pets
description: Pet management operations
- name: orders
description: Order lifecycle management
paths:
/pets:
post:
tags: [pets] # ✅ tag 필수
operationId: addPet
/orders:
post:
tags: [orders] # ✅ 같은 도메인은 같은 tag
operationId: createOrder효과: tag → 자동 카테고리 생성. tag 없으면 path prefix로 fallback (정확도 낮음)
⚠️ Stripe API는 tag가 전혀 없어서 587개 endpoint를 path prefix로만 분류해야 합니다.
# 리소스 계층 = path 계층
/users # 컬렉션
/users/{userId} # 단일 리소스
/users/{userId}/orders # 하위 리소스 (parent-child 관계 자동 감지)
/users/{userId}/orders/{orderId}
/users/{userId}/orders/{orderId}/items# ❌ flat한 path는 관계 감지 불가
/getUser
/getUserOrders
/createOrder
/cancelUserOrder효과: path hierarchy → REQUIRES 관계 자동 감지 (confidence 0.95)
components:
schemas:
Pet: # ✅ 공유 스키마 정의
type: object
properties:
id:
type: integer
name:
type: string
paths:
/pets:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet' # ✅ $ref 사용
/pets/{petId}:
get:
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Pet' # ✅ 같은 $ref → COMPLEMENTARY 감지효과: 같은 $ref 참조 → COMPLEMENTARY 관계 자동 감지 (confidence 0.85)
# ✅ response에 id 필드가 있으면 → 다른 endpoint의 parameter와 매칭
/pets:
post:
responses:
'201':
content:
application/json:
schema:
type: object
properties:
id: # ✅ 이 필드가
type: integer
description: Pet ID
/pets/{petId}: # ✅ 이 parameter와 매칭됨
get:
parameters:
- name: petId # response.id → param.petId (REQUIRES 감지)
in: path
schema:
type: integer효과: producer-consumer 관계 자동 감지 (RESTler 알고리즘)
components:
schemas:
Order:
properties:
status:
type: string
enum: # ✅ enum으로 상태 정의
- pending
- confirmed
- shipped
- delivered
- cancelled
description: "Order lifecycle status"효과: enum 상태 → PRECEDES (호출 순서) 관계 자동 추론
pending → confirmed: createOrder PRECEDES confirmOrder
confirmed → shipped: confirmOrder PRECEDES shipOrder
/pets/findByTags:
get:
deprecated: true # ✅ deprecated 표시
description: "Use findPetsByStatus instead"효과: deprecated endpoint는 tool graph에서 자동 제외 (옵션)
/orders/{orderId}/cancel:
post:
summary: "Cancel an order" # ✅ 짧은 요약
description: | # ✅ 상세 설명
Cancels a pending or confirmed order.
Cannot cancel shipped orders.
Requires the order to exist (call getOrder first).
operationId: cancelOrder효과: description → BM25 keyword matching + embedding similarity 정확도 향상
API 간 호출 순서가 중요하면 Arazzo spec 추가:
# arazzo.yaml
arazzo: 1.0.0
info:
title: Order Workflow
workflows:
- workflowId: order-cancel
steps:
- stepId: list
operationId: listOrders
- stepId: get
operationId: getOrder
dependsOn: list
- stepId: cancel
operationId: cancelOrder
dependsOn: get효과: 완벽한 호출 순서 관계 추출 (confidence 1.0)
| # | 항목 | 영향 | 필수 |
|---|---|---|---|
| 1 | operationId에 {action}{Resource} 패턴 |
CRUD 감지 | ★★★ |
| 2 | 모든 operation에 tag | 카테고리 | ★★★ |
| 3 | RESTful path 계층 | 부모-자식 관계 | ★★☆ |
| 4 | $ref로 스키마 공유 | COMPLEMENTARY | ★★☆ |
| 5 | Response에 ID 필드 | REQUIRES | ★★☆ |
| 6 | Enum으로 상태 정의 | PRECEDES | ★★☆ |
| 7 | Deprecated 표시 | 필터링 | ★☆☆ |
| 8 | Description 충실히 | 검색 품질 | ★★☆ |
| 9 | Arazzo workflow | 호출 순서 | ★☆☆ |
@app.post("/users", tags=["users"], operation_id="createUser")
async def create_user(user: UserCreate) -> User:
"""Create a new user account.
Returns the created user with generated ID.
"""@Operation(
operationId = "createUser",
summary = "Create user",
tags = {"users"}
)
@PostMapping("/users")
public User createUser(@RequestBody UserCreate user) { ... }@ApiTags('users')
@ApiOperation({ operationId: 'createUser', summary: 'Create user' })
@Post('/users')
createUser(@Body() user: CreateUserDto): User { ... }