> ## Documentation Index
> Fetch the complete documentation index at: https://docs.x.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 규칙 작성

> keyword 연산자, conjunction, 부정을 사용하여 X API v2 Filtered Stream 규칙을 작성하고, 필터에 매칭되는 게시물을 거의 실시간으로 전달받으세요.

Filtered stream 엔드포인트는 스트림에 적용된 일련의 규칙에 매칭되는 게시물을 전달합니다. 규칙은 다양한 게시물 속성에 매칭되는 연산자로 구성됩니다.

여러 규칙은 [POST /tweets/search/stream/rules](/x-api/stream/update-stream-rules) 엔드포인트를 통해 적용할 수 있습니다. 규칙을 추가하고 [GET /tweets/search/stream](/x-api/stream/get-stream-rules)을 사용해 연결한 뒤에는, 규칙에 매칭되는 게시물만 전달됩니다. 규칙을 추가하거나 제거하기 위해 연결을 끊을 필요는 없습니다.

***

## 규칙 제한 사항

규칙 수 제한은 [access level](/x-api/getting-started/about-x-api)에 따라 달라집니다. 구체적인 제한은 [filtered stream 소개](/x-api/posts/filtered-stream/introduction)를 참고하세요.

***

## 연산자 유형: standalone 및 conjunction-required

**Standalone 연산자**는 단독으로 사용하거나, conjunction이 필요한 연산자를 포함한 다른 연산자들과 함께 사용할 수 있습니다.

예를 들어, `#hashtag`는 standalone 연산자이므로 다음 규칙이 정상 동작합니다:

```
#xapiv2
```

**Conjunction-required 연산자**는 규칙에서 단독으로 사용할 수 없으며, 최소 하나 이상의 standalone 연산자가 포함되어야만 사용할 수 있습니다. 이는 이러한 연산자를 단독으로 사용할 경우 매우 많은 양의 게시물이 매칭되기 때문입니다.

예를 들어, 다음 규칙들은 conjunction-required 연산자만 포함하고 있으므로 **지원되지 않습니다**:

```
has:media
```

```
has:links OR is:retweet
```

```
embedding_threshold:0.45
```

여기에 `"X data"`와 같은 standalone 연산자를 추가하면 규칙이 정상 동작합니다:

```
"X data" has:mentions (has:media OR has:links)
```

`embedding_threshold:` 연산자(시맨틱 `embedding:` 규칙과 함께 사용)도 conjunction-required입니다.

***

## Boolean 연산자와 그룹화

다음 도구를 사용해 여러 연산자를 조합할 수 있습니다:

| Operator     | Description       | Example                                                            |
| :----------- | :---------------- | :----------------------------------------------------------------- |
| **AND** (공백) | 두 조건을 모두 매칭해야 함   | `snow day #NoSchool`은 "snow" AND "day" AND #NoSchool을 포함한 게시물에 매칭  |
| **OR**       | 두 조건 중 하나라도 매칭    | `grumpy OR cat OR #meme`은 "grumpy" OR "cat" OR #meme을 포함한 게시물에 매칭  |
| **NOT** (대시) | 이 조건에 매칭되는 게시물 제외 | `cat #meme -grumpy`는 "cat"과 #meme을 포함하지만 "grumpy"는 포함하지 않는 게시물에 매칭 |
| **그룹화** (괄호) | 연산자를 하나로 묶음       | `(grumpy cat) OR (#meme has:images)`는 두 그룹 중 하나에 매칭                |

<Note>
  **부정 관련 참고 사항**

  * `sample:` 및 `embedding:`을 제외한 모든 연산자를 부정할 수 있습니다
  * `-is:nullcast` 연산자는 반드시 부정된 형태로만 사용해야 합니다
  * 부정된 연산자는 단독으로 사용할 수 없습니다
  * 그룹화된 연산자를 부정하지 마세요. `skiing -(snow OR day OR noschool)` 대신 `skiing -snow -day -noschool`을 사용하세요
  * `-embedding:"query"`는 지원되지 않습니다
</Note>

***

## 연산 우선순위

AND와 OR를 함께 사용할 때:

1. AND 로직으로 연결된 연산자가 먼저 결합됩니다
2. 그 다음 OR 로직으로 연결된 연산자가 적용됩니다

**예시:**

| Query                    | Evaluated as               |
| :----------------------- | :------------------------- |
| `apple OR iphone ipad`   | `apple OR (iphone ipad)`   |
| `ipad iphone OR android` | `(iphone ipad) OR android` |

모호함을 없애려면 괄호를 사용하세요:

```
(apple OR iphone) ipad
```

```
iphone (ipad OR android)
```

***

## 구두점, 발음 구별 부호, 대소문자 구분

**발음 구별 부호:** 악센트가 포함된 filtered stream 규칙은 악센트가 포함된 게시물에만 매칭됩니다. 예를 들어 `diacrítica`는 \_diacrítica\_에 매칭되지만 \_diacritica\_에는 **매칭되지 않습니다**.

**대소문자 구분:** 모든 연산자는 대소문자를 구분하지 않습니다. `cat` 규칙은 *cat*, *CAT*, \_Cat\_에 모두 매칭됩니다.

<Note>
  **Search Posts는 다르게 동작합니다**

  [search 쿼리 작성](/x-api/posts/search/integrate/build-a-query) 시, 악센트가 포함된 키워드는 악센트가 있는 게시물과 없는 게시물 모두에 매칭됩니다. 예를 들어 `Diacrítica`는 \_Diacrítica\_와 \_Diacritica\_에 모두 매칭됩니다.
</Note>

***

## Quote Tweet 매칭

filtered stream을 사용할 때, 연산자는 Quote Tweet의 콘텐츠 **및** 인용된 원본 게시물의 콘텐츠 모두에 매칭됩니다.

<Note>
  [Search Posts](/x-api/posts/search/introduction)는 다르게 동작합니다—Quote Tweet의 콘텐츠에만 매칭되고 원본 게시물에는 매칭되지 않습니다.
</Note>

***

## 구체성 및 효율성

<Warning>
  단일 키워드나 해시태그와 같은 광범위한 연산자를 사용하는 것은 권장되지 않습니다—엄청난 양의 게시물이 매칭되어 연결을 빠르게 소진하게 됩니다.
</Warning>

**효과적인 규칙 작성을 위한 팁:**

1. **구체적으로 시작한 뒤 확장하기** — 관련성 있는 결과를 반환하는 타깃형 규칙을 만드세요
2. **여러 연산자 사용하기** — 연산자를 조합해 결과 범위를 좁히세요
3. **문자 수 확인하기** — 규칙 문자열 전체가 제한에 포함됩니다

**예시 진행:**

```
# Too broad - 200,000+ Posts per day
happy

# Better - adds language filter and exclusions
(happy OR happiness) lang:en -birthday -is:retweet

# Even better - 59 characters, more specific
(happy OR happiness) place_country:GB -birthday -is:retweet
```

***

## 반복적으로 규칙 다듬기

### 1단계: 기본 규칙으로 시작

```
happy OR happiness
```

### 2단계: 결과를 기반으로 테스트 및 범위 좁히기

여러 언어의 게시물이 있었습니다. 언어 필터를 추가합니다:

```
(happy OR happiness) lang:en
```

생일 인사가 반환됩니다. 이를 제외하고 리트윗도 제외합니다:

```
(happy OR happiness) lang:en -birthday -is:retweet
```

### 3단계: 커버리지 확장

더 많은 감정을 포착하고 싶습니다. 관련 키워드를 추가합니다:

```
(happy OR happiness OR excited OR elated) lang:en -birthday -is:retweet
```

### 4단계: 트렌드에 맞춰 조정

Holiday 게시물이 등장합니다. 이를 제외합니다:

```
(happy OR happiness OR excited OR elated) lang:en -birthday -is:retweet -holidays
```

***

## 규칙 추가 및 제거

규칙을 추가하거나 제거하려면 [POST /2/tweets/search/stream/rules](/x-api/stream/update-stream-rules)를 사용하세요.

### 규칙 추가

`value`(규칙)와 선택적 `tag`(매칭 게시물을 식별하기 위한 값)를 포함한 `add` JSON 본문을 전송합니다:

```bash theme={null}
curl -X POST "https://api.x.com/2/tweets/search/stream/rules" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "add": [
      {"value": "cat has:media", "tag": "cats with media"},
      {"value": "cat has:media -grumpy", "tag": "happy cats with media"},
      {"value": "meme", "tag": "funny things"},
      {"value": "meme has:images"}
    ]
  }'
```

### 규칙 제거

제거할 규칙 ID를 포함한 `delete` JSON 본문을 전송합니다:

```bash theme={null}
curl -X POST "https://api.x.com/2/tweets/search/stream/rules" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "delete": {
      "ids": [
        "1165037377523306498",
        "1165037377523306499"
      ]
    }
  }'
```

***

## 규칙 예시

### 자연재해 추적

허리케인 Harvey에 대한 기상 기관의 게시물에 매칭:

```json theme={null}
{
  "value": "-is:retweet has:geo (from:NWSNHC OR from:NHC_Atlantic OR from:NWSHouston OR from:NWSSanAntonio OR from:USGS_TexasRain OR from:USGS_TexasFlood OR from:JeffLindner1)",
  "tag": "Hurricane Harvey - weather agencies with geo"
}
```

### #nowplaying에 대한 감성 분석

**긍정 감성:**

```json theme={null}
{
  "value": "#nowplaying (happy OR exciting OR excited OR favorite OR fav OR amazing OR lovely OR incredible) (place_country:US OR place_country:MX OR place_country:CA) -horrible -worst -sucks -bad -disappointing",
  "tag": "#nowplaying positive"
}
```

**부정 감성:**

```json theme={null}
{
  "value": "#nowplaying (horrible OR worst OR sucks OR bad OR disappointing) (place_country:US OR place_country:MX OR place_country:CA) -happy -exciting -excited -favorite -fav -amazing -lovely -incredible",
  "tag": "#nowplaying negative"
}
```

### Post annotations 사용

`context:` 연산자를 사용해 이미지가 있는 일본어 게시물 중 반려동물 관련(고양이 제외)을 찾기:

먼저 `tweet.fields=context_annotations`와 함께 [Post lookup](/x-api/posts/lookup/introduction)을 사용해 domain.entity ID를 확인합니다:

* Cats: `domain` 66, `entity` 852262932607926273
* Pets: `domain` 65, `entity` 852262932607926273

```json theme={null}
{
  "value": "context:65.852262932607926273 -context:66.852262932607926273 -is:retweet has:images lang:ja",
  "tag": "Japanese pets with images - no cats"
}
```

### 임베딩을 이용한 시맨틱 매칭 (Enterprise)

`embedding:` 연산자를 사용해 키워드가 아닌 개념적 의미로 게시물을 매칭합니다. Enterprise + Embedding 티어가 필요합니다.

```json theme={null}
{
  "value": "embedding:\"climate change policy\" embedding_threshold:0.4",
  "tag": "climate-semantic"
}
```

정밀도를 위해 구조적 연산자와 결합할 수 있습니다:

```json theme={null}
{
  "value": "embedding:\"quarterly earnings surprises\" lang:en has:links -is:retweet",
  "tag": "earnings-en"
}
```

전체 세부사항과 모범 사례는 [연산자 레퍼런스](/x-api/posts/filtered-stream/integrate/operators)를 참고하세요.

***

## 다음 단계

<CardGroup cols={2}>
  <Card title="연산자 레퍼런스" icon="https://mintcdn.com/x-preview/ygI6sSJPehlc0qNT/icons/xds/icon-bulleted-list.svg?fit=max&auto=format&n=ygI6sSJPehlc0qNT&q=85&s=b9bf8323233df59c682b0fec8e3f88d5" href="/x-api/posts/filtered-stream/integrate/operators" width="24" height="24" data-path="icons/xds/icon-bulleted-list.svg">
    사용 가능한 연산자 전체 목록
  </Card>

  <Card title="Filtered stream 퀵스타트" icon="https://mintcdn.com/x-preview/oR-aRNyj1BKPJtxM/icons/xds/icon-rocket.svg?fit=max&auto=format&n=oR-aRNyj1BKPJtxM&q=85&s=b978d7a9225de31709efbbed5b84e92d" href="/x-api/posts/filtered-stream/quickstart" width="24" height="24" data-path="icons/xds/icon-rocket.svg">
    스트림에 연결하기
  </Card>

  <Card title="샘플 코드" icon="github" href="https://github.com/xdevplatform/Twitter-API-v2-sample-code/tree/master/Filtered-Stream">
    여러 언어로 된 코드 예제
  </Card>
</CardGroup>
