モデル概要
モデル特徴
モデル能力
使用事例
license: apache-2.0 language:
- zh
- en tags:
- AgentCPM-GUI
- gui agent
- android agent
- multimodal base_model:
- openbmb/MiniCPM-V-2_6 pipeline_tag: image-text-to-text
AgentCPM-GUI
GitHub | 技術ブログ
ニュース
- [2025-05-13] üöÄüöÄüöÄ AgentCPM-GUIをオープンソース化しました。これはデバイス上で動作するGUIエージェントで、中国語と英語のアプリを操作でき、RFT強化された推論能力を備えています。
概要
AgentCPM-GUIは、THUNLP、中国人民大学、ModelBestが共同開発したオープンソースのデバイス上LLMエージェントモデルです。MiniCPM-Vをベースにした80億パラメータのモデルで、スマートフォンのスクリーンショットを入力として受け取り、ユーザーが指定したタスクを自律的に実行します。
主な特徴:
- 高品質なGUIグラウンディング — 大規模なバイリンガルAndroidデータセットでの事前学習により、一般的なGUIウィジェット(ボタン、入力ボックス、ラベル、アイコンなど)の位置特定と理解が大幅に向上。
- 中国語アプリ操作 — 中国語アプリ向けに細かくチューニングされた初のオープンソースGUIエージェントで、Amap、Dianping、bilibili、Xiaohongshuなど30以上の人気アプリをカバー。
- 強化された計画と推論 — 強化学習ファインチューニング(RFT)により、モデルはアクションを出力する前に「考え」、複雑なタスクでの成功率が大幅に向上。
- コンパクトなアクション空間設計 — 最適化されたアクション空間と簡潔なJSONフォーマットにより、平均アクション長を9.7トークンに削減し、デバイス上での推論効率を向上。
デモケース(1倍速):
https://github.com/user-attachments/assets/5472a659-cd71-4bce-a181-0981129c6a81
クイックスタート
依存関係のインストール
git clone https://github.com/OpenBMB/AgentCPM-GUI
cd AgentCPM-GUI
conda create -n gui_agent python=3.11
conda activate gui_agent
pip install -r requirements.txt
モデルのダウンロード
Hugging FaceからAgentCPM-GUIをダウンロードし、model/AgentCPM-GUI
に配置します。
Huggingface推論
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from PIL import Image
import json
# 1. モデルとトークナイザーの読み込み
model_path = "model/AgentCPM-GUI" # モデルパス
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True, torch_dtype=torch.bfloat16)
model = model.to("cuda:0")
# 2. 入力の構築
instruction = "请点击屏幕上的‘会员’按钮"
image_path = "assets/test.jpeg"
image = Image.open(image_path).convert("RGB")
# 3. 長辺を1120ピクセルにリサイズして計算とメモリを節約
def __resize__(origin_img):
resolution = origin_img.size
w,h = resolution
max_line_res = 1120
if max_line_res is not None:
max_line = max_line_res
if h > max_line:
w = int(w * max_line / h)
h = max_line
if w > max_line:
h = int(h * max_line / w)
w = max_line
img = origin_img.resize((w,h),resample=Image.Resampling.LANCZOS)
return img
image = __resize__(image)
# 4. メッセージフォーマットの構築
messages = [{
"role": "user",
"content": [
f"<Question>{instruction}</Question>\n当前屏幕截图:",
image
]
}]
# 5. 推論
ACTION_SCHEMA = json.load(open('eval/utils/schema/schema.json', encoding="utf-8"))
items = list(ACTION_SCHEMA.items())
insert_index = 3
items.insert(insert_index, ("required", ["thought"])) # 思考を有効/無効にするには"required"/"optional"に設定
ACTION_SCHEMA = dict(items)
SYSTEM_PROMPT = f'''# Role
你是一名熟悉安卓系统触屏GUI操作的智能体,将根据用户的问题,分析当前界面的GUI元素和布局,生成相应的操作。
# Task
针对用户问题,根据输入的当前屏幕截图,输出下一步的操作。
# Rule
- 以紧凑JSON格式输出
- 输出操作必须遵循Schema约束
# Schema
{json.dumps(ACTION_SCHEMA, indent=None, ensure_ascii=False, separators=(',', ':'))}'''
outputs = model.chat(
image=None,
msgs=messages,
system_prompt=SYSTEM_PROMPT,
tokenizer=tokenizer,
temperature=0.1,
top_p=0.3,
n=1,
)
# 6. 出力
print(outputs)
期待される出力:
{"thought":"任务目标是点击屏幕上的‘会员’按钮。当前界面显示了应用的推荐页面,顶部有一个导航栏。点击‘会员’按钮可以访问应用的会员相关内容。","POINT":[729,69]}
vLLM推論
# vLLMサーバーの起動
vllm serve model/AgentCPM-GUI --served-model-name AgentCPM-GUI --tensor_parallel_size 1 --trust-remote-code
import base64
import io
import json
import requests
from PIL import Image
END_POINT = "http://localhost:8000/v1/chat/completions" # 実際のエンドポイントに置き換え
# システムプロンプト
ACTION_SCHEMA = json.load(open('eval/utils/schema/schema.json', encoding="utf-8"))
items = list(ACTION_SCHEMA.items())
insert_index = 3
items.insert(insert_index, ("required", ["thought"])) # 思考を有効/無効にするには"required"/"optional"に設定
ACTION_SCHEMA = dict(items)
SYSTEM_PROMPT = f'''# Role
你是一名熟悉安卓系统触屏GUI操作的智能体,将根据用户的问题,分析当前界面的GUI元素和布局,生成相应的操作。
# Task
针对用户问题,根据输入的当前屏幕截图,输出下一步的操作。
# Rule
- 以紧凑JSON格式输出
- 输出操作必须遵循Schema约束
# Schema
{json.dumps(ACTION_SCHEMA, indent=None, ensure_ascii=False, separators=(',', ':'))}'''
def encode_image(image: Image.Image) -> str:
"""PIL画像をbase64エンコードされた文字列に変換"""
with io.BytesIO() as in_mem_file:
image.save(in_mem_file, format="JPEG")
in_mem_file.seek(0)
return base64.b64encode(in_mem_file.read()).decode("utf-8")
def __resize__(origin_img):
resolution = origin_img.size
w,h = resolution
max_line_res = 1120
if max_line_res is not None:
max_line = max_line_res
if h > max_line:
w = int(w * max_line / h)
h = max_line
if w > max_line:
h = int(h * max_line / w)
w = max_line
img = origin_img.resize((w,h),resample=Image.Resampling.LANCZOS)
return img
def predict(text_prompt: str, image: Image.Image):
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": [
{"type": "text", "text": f"<Question>{text_prompt}</Question>\n当前屏幕截图:"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{encode_image(image)}"}}
]}
]
payload = {
"model": "AgentCPM-GUI", # モデル名
"temperature": 0.1,
"messages": messages,
"max_tokens": 2048,
}
headers = {
"Content-Type": "application/json",
}
response = requests.post(END_POINT, headers=headers, json=payload)
assistant_msg = response.json()["choices"][0]["message"]["content"]
return assistant_msg
image = __resize__(Image.open("assets/test.jpeg"))
instruction = "请点击屏幕上的‘会员’按钮"
response = predict(instruction, image)
print(response)
アクション空間
各ステップで、エージェントは以下の内容を含む単一のJSONオブジェクトを出力します:
- 以下のリストから選択された1つ(かつ1つだけ)のプリミティブアクション;
- オプションの修飾子(
duration
、thought
)および/またはタスクレベルのフラグ(STATUS
)。
すべてのキーワードは大文字と小文字を区別し、コンパクトなJSON(余分な空白なし)を使用していることに注意してください。これはトークナイザーの動作に影響します。
アクション | 必須フィールド | オプションフィールド | 目的 | 例 |
---|---|---|---|---|
クリック | POINT:[x,y] |
duration ,thought ,STATUS |
正規化された画面座標(0–1000、原点=左上)でのシングルタップ。 | {"POINT":[480,320]} |
長押し | POINT:[x,y] duration:1000 |
duration ,thought ,STATUS |
座標でのタッチアンドホールド(例: 200ミリ秒以上の長いdurationを設定)。 | {"POINT":[480,320],"duration":1000} |
スワイプ | POINT:[x,y] to:"up" | "down" | "left" | "right" または to:[x,y] |
duration ,thought ,STATUS |
開始点から方向または別の座標に向かってスワイプ。 | {"POINT":[500,200],"to":"down"} |
キー押下 | PRESS:"HOME" | "BACK" | "ENTER" |
duration ,thought ,STATUS |
ハードウェア/ナビゲーションボタンをトリガー。 | {"PRESS":"HOME"} |
テキスト入力 | TYPE:"<text>" |
duration ,thought ,STATUS |
現在の入力フォーカスに指定されたテキストを挿入。 | {"TYPE":"Hello, world!"} |
待機 | duration |
thought ,STATUS |
他のアクションなしで指定された時間だけ待機。 | {"duration":500} |
タスクレベルステータス | STATUS:"start" | "continue" | "finish" | "satisfied" | "impossible" | "interrupt" | "need_feedback" |
duration ,thought |
タスクの進捗を報告; 単独またはプリミティブアクションと共に出現可能。 | {"STATUS":"finish"} |
ファインチューニング
SFTとRFTトレーニングのソースコードが提供されています — GitHubを参照してください。
性能評価
グラウンディングベンチマーク
モデル | fun2point | text2point | bbox2text | 平均 |
---|---|---|---|---|
AgentCPM-GUI-8B | 79.1 | 76.5 | 58.2 | 71.3 |
Qwen2.5-VL-7B | 36.8 | 52.0 | 44.1 | 44.3 |
Intern2.5-VL-8B | 17.2 | 24.2 | 45.9 | 29.1 |
Intern2.5-VL-26B | 14.8 | 16.6 | 36.3 | 22.6 |
OS-Genesis-7B | 8.3 | 5.8 | 4.0 | 6.0 |
UI-TARS-7B | 56.8 | 66.7 | 1.4 | 41.6 |
OS-Altas-7B | 53.6 | 60.7 | 0.4 | 38.2 |
Aguvis-7B | 60.8 | 76.5 | 0.2 | 45.8 |
GPT-4o | 22.1 | 19.9 | 14.3 | 18.8 |
GPT-4o with Grounding | 44.3 | 44.0 | 14.3 | 44.2 |
エージェントベンチマーク
データセット | Android Control-Low TM | Android Control-Low EM | Android Control-High TM | Android Control-High EM | GUI-Odyssey TM | GUI-Odyssey EM | AITZ TM | AITZ EM | 中国語アプリ TM | 中国語アプリ EM |
---|---|---|---|---|---|---|---|---|---|---|
AgentCPM-GUI-8B | 94.39 | 90.20 | 77.70 | 69.17 | 90.85 | 74.96 | 85.71 | 76.38 | 96.86 | 91.28 |
Qwen2.5-VL-7B | 92.11 | 82.12 | 69.65 | 57.36 | 55.33 | 40.90 | 73.16 | 57.58 | 68.53 | 48.80 |
UI-TARS-7B | 93.52 | 88.89 | 68.53 | 60.81 | 78.79 | 57.33 | 71.74 | 55.31 | 71.01 | 53.92 |
OS-Genesis-7B | 90.74 | 74.22 | 65.92 | 44.43 | 11.67 | 3.63 | 19.98 | 8.45 | 38.10 | 14.50 |
OS-Atlas-7B | 73.03 | 67.25 | 70.36 | 56.53 | 91.83* | 76.76* | 74.13 | 58.45 | 81.53 | 55.89 |
Aguvis-7B | 93.85 | 89.40 | 65.56 | 54.18 | 26.71 | 13.54 | 35.71 | 18.99 | 67.43 | 38.20 |
OdysseyAgent-7B | 65.10 | 39.16 | 58.80 | 32.74 | 90.83 | 73.67 | 59.17 | 31.60 | 67.56 | 25.44 |
GPT-4o | - | 19.49 | - | 20.80 | - | 20.39 | 70.00 | 35.30 | 3.67 | 3.67 |
Gemini 2.0 | - | 28.50 | - | 60.20 | - | 3.27 | - | - | - | - |
Claude | - | 19.40 | - | 12.50 | 60.90 | - | - | - | - | - |
*異なるトレイン/テスト分割
TMとEMはそれぞれタイプマッチと完全一致を表します。すべての評価データとコードはオープンソースです — 詳細はこちらを参照してください。
すべての評価データとコードはオープンソースです — 詳細はこちらを参照してください。
評価データ
中国語アプリ向けのCAGUIという評価ベンチマークを提供しています。これはグラウンディングとエージェントタスクをカバーしています。 データセットはHugging Faceで公開されています。
ライセンス
- このリポジトリのコードはApache-2.0ライセンスで公開されています。
引用
AgentCPM-GUIが研究に役立った場合は、以下のように引用してください:
@misc{2025,
author = {THUNLP},
title = {AgentCPM-GUI},
year = {2025},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/OpenBMB/AgentCPM-GUI}}
}








