# How Agent Reach's `format` Command Cleans and Formats XHS API JSON Output

> Learn how Agent Reach format command cleans XHS API JSON output. Reduce payload size by over 80 percent for LLM-ready structures. Discover efficient data handling.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-06-07

---

**The Agent Reach `format` command exposes `format_xhs_result` in [`agent_reach/channels/xiaohongshu.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/xiaohongshu.py) to strip noisy XHS API JSON down to a compact, LLM-ready structure, often reducing payload size by over 80 percent.**

The **Panniantong/Agent-Reach** repository includes a dedicated channel for XiaoHongShu (XHS) that handles the messy reality of third-party API responses. When you run the `format` sub-command, Agent Reach cleans and formats verbose XHS API JSON output into a minimal, semantically rich representation that minimizes token consumption for downstream AI models.

## Core Implementation in [`xiaohongshu.py`](https://github.com/Panniantong/Agent-Reach/blob/main/xiaohongshu.py)

The entire cleaning pipeline lives in [[`agent_reach/channels/xiaohongshu.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/xiaohongshu.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/xiaohongshu.py). This file defines the public entry point `format_xhs_result` as well as the private helpers `_clean_note` and `_clean_comment` that perform the heavy lifting.

## How `format_xhs_result` Processes API Responses

The function starts by inspecting the raw payload and normalizing common wrapper patterns before delegating to the note cleaner.

### Input Type Detection

`format_xhs_result` first determines whether the payload is a **list** (typical for paginated search results) or a **dict** (single note or a response wrapper). This decision dictates whether the function iterates over multiple items or cleans a single object.

### Wrapper Normalization

Many XHS responses bury the actual content under nested keys such as `"items"` or `"data"` → `"items"`/`"notes"`. The helper extracts these arrays automatically so downstream logic always receives a flat list of note objects to process.

### Delegation to `_clean_note`

Once the payload is normalized, every note object is passed to the private helper **`_clean_note`**. This method performs the field extraction and type conversion, returning a lean dictionary that preserves only the information most relevant to LLM prompts.

## Fields That `_clean_note` Preserves

`_clean_note` maps verbose XHS API fields into a standardized, compact schema. Only the following categories are retained:

- **Basic metadata** – `id`, `note_id`, `xsec_token`, `title`, `desc`, `type`, and `time` are copied directly when present.

- **Content** – The `content` field is added only as a fallback to `desc`; if `desc` is already set, no duplicate text is inserted.

- **Author** – A small nested dict is built from `user` or `author` objects, retaining only `nickname`, `user_id`, and `nick_name`.

- **Engagement** – Interaction counts (`liked_count`, `collected_count`, `comment_count`, `share_count`) are pulled from `interact_info`/`note_interact_info` structures and top-level fields alike.

- **Images** – Image URLs are extracted from `image_list` or `images_list`. Each entry may be a dict (in which case `url`, `url_default`, or `original` is grabbed) or a plain string.

- **Tags** – Tag names are read from `tag_list` or `tags`. Dict entries are resolved via the `name` key, while plain strings are kept as-is.

- **Comments** – If a `comments` array exists, each element is routed through `_clean_comment` to produce a trimmed reply object.

## How `_clean_comment` Trims Comment Noise

Replies often carry large user metadata and tracking fields that are irrelevant for summarization. **`_clean_comment`** retains only:

- **`content`** – copied directly if present.
- **`user`** – resolved from `nickname` or `nick_name` found in `user_info` or `user`.
- **`like_count`** and **`sub_comment_count`** – copied unchanged when available.

## CLI Integration: The `format` Sub-command

The `format` sub-command is exposed in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py). It reads raw JSON from a file or stdin, forwards it to `format_xhs_result`, and prints the resulting Python object or JSON. Because the CLI delegates directly to the channel helper, any updates to `_clean_note` or `_clean_comment` are immediately reflected in command-line behavior without additional glue code.

## Code Examples

Below are runnable snippets that demonstrate the transformation.

### Cleaning a Single Note

```python
import json
from agent_reach.channels.xiaohongshu import format_xhs_result

# Raw JSON from the XHS API (e.g., from `xhs note get <id>`):

raw = json.loads("""{
    "note_card": {
        "id": "12345",
        "title": "My Travel Diary",
        "desc": "A short description",
        "user": {"nickname": "Alice", "user_id": "u678"},
        "interact_info": {"liked_count": 10, "comment_count": 2},
        "image_list": [{"url": "https://img.example/pic1.jpg"}],
        "tag_list": [{"name": "travel"}, {"name": "photography"}],
        "comments": [{"content": "Nice!", "user_info": {"nickname": "Bob"}}]
    }
}""")

cleaned = format_xhs_result(raw)
print(json.dumps(cleaned, ensure_ascii=False, indent=2))

```

The script produces compact, LLM-ready JSON:

```json
{
  "id": "12345",
  "title": "My Travel Diary",
  "desc": "A short description",
  "user": {
    "nickname": "Alice",
    "user_id": "u678"
  },
  "liked_count": 10,
  "comment_count": 2,
  "images": ["https://img.example/pic1.jpg"],
  "tags": ["travel", "photography"],
  "comments": [
    {
      "content": "Nice!",
      "user": "Bob"
    }
  ]
}

```

### Cleaning a Search Result List

```python

# search_output is the raw JSON returned from `xhs search <query>`

cleaned_list = format_xhs_result(search_output)

# Returns a list of cleaned dicts following the same trimmed schema

```

## Summary

- The **Agent Reach `format` command** cleans XHS API JSON output by routing data through `format_xhs_result` in [`agent_reach/channels/xiaohongshu.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/xiaohongshu.py).
- **Wrapper normalization** handles nested `"items"` and `"data"` keys, while **input type detection** supports both single notes and lists.
- **`_clean_note`** preserves only essential metadata, content, author info, engagement metrics, images, tags, and trimmed comments.
- **`_clean_comment`** further reduces reply objects to content, user name, and key counts.
- The design aligns with the project's token-efficiency goals, often shrinking payloads by more than 80 percent according to the source comment on line 13 of [`xiaohongshu.py`](https://github.com/Panniantong/Agent-Reach/blob/main/xiaohongshu.py).

## Frequently Asked Questions

### What is the primary purpose of the Agent Reach `format` command?

The command transforms verbose XiaoHongShu API JSON into a compact, structured representation. This reduces noise and token usage, making the output ideal for downstream LLM consumption.

### Which source file implements the core formatting logic?

The core logic resides in [`agent_reach/channels/xiaohongshu.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/xiaohongshu.py). This file defines `format_xhs_result`, `_clean_note`, and `_clean_comment`, while [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) simply exposes the `format` sub-command that calls them.

### How does `format_xhs_result` handle different XHS response shapes?

It detects whether the payload is a list or dict, extracts nested arrays from common wrapper keys like `"items"` or `"data"`, and then delegates each note object to `_clean_note`. This ensures consistent cleaning regardless of whether the input is a single note or a paginated search result.

### What comment fields survive the cleaning process?

`_clean_comment` retains only `content`, the author's `nickname` (or `nick_name`), `like_count`, and `sub_comment_count`. All other metadata is discarded to keep comment threads concise.