ReMe/benchmark/bfcl/run_bfcl.py
zouyingcao 65971bafe3
Update: check the code&docs for evaluation on bfcl&appworld (#141)
* fix: df.columns bug

* fix: await for asynchronous method

* update: docs for bfcl&appworld quickstart

* update: benchmark/bfcl for new version quickstart

* slightly revise bfcl cookbook

* update for pre-commit

* handle boolean flags in split_into_trainval.py

* fix typo in faq.md
2026-03-06 16:11:39 +08:00

151 lines
4.4 KiB
Python

"""Run evaluation on BFCL-V3-Multi-Turn-Base dataset."""
import time
import json
from pathlib import Path
import ray
import requests
from loguru import logger
from dotenv import load_dotenv
from bfcl_agent import BFCLAgent
load_dotenv("../../.env")
def run_agent(
max_workers: int,
dataset_name: str,
experiment_suffix: str,
model_name: str = "qwen3-8b",
enable_thinking: bool = False,
data_path: str = "data/multiturn_data_base_val.jsonl",
answer_path: Path = Path("data/possible_answer"),
num_trials: int = 1,
use_memory: bool = False,
memory_base_url: str = "http://0.0.0.0:8002/",
use_memory_addition: bool = True,
use_memory_deletion: bool = False,
delete_freq: int = 10,
freq_threshold: int = 5,
utility_threshold: float = 0.5,
):
"""Run the agent"""
experiment_name = dataset_name + "_" + experiment_suffix
path: Path = Path(
f"./exp_result/{model_name}/with_think" if enable_thinking else f"./exp_result/{model_name}/no_think",
)
path.mkdir(parents=True, exist_ok=True)
with open(data_path, "r", encoding="utf-8") as f:
task_ids = [json.loads(line)["id"] for line in f]
result: list = []
def dump_file():
with open(path / f"{experiment_name}.jsonl", "a", encoding="utf-8") as f:
for x in result:
f.write(json.dumps(x) + "\n")
future_list: list = []
for i in range(max_workers):
actor = BFCLAgent.remote(
index=i,
model_name=model_name,
task_ids=task_ids[i::max_workers],
experiment_name=experiment_name,
data_path=data_path,
answer_path=answer_path,
num_trials=num_trials,
use_memory=use_memory,
memory_base_url=memory_base_url,
use_memory_addition=use_memory_addition,
use_memory_deletion=use_memory_deletion,
delete_freq=delete_freq,
freq_threshold=freq_threshold,
utility_threshold=utility_threshold,
enable_thinking=enable_thinking,
)
future = actor.execute.remote()
future_list.append(future)
time.sleep(1)
logger.info("submit complete")
for i, future in enumerate(future_list):
t_result = ray.get(future)
if t_result:
if isinstance(t_result, list):
result.extend(t_result)
else:
result.append(t_result)
logger.info(f"{i + 1}/{len(task_ids)} complete")
dump_file()
def handle_api_response(response: requests.Response):
"""Handle API response with proper error checking"""
if response.status_code != 200:
print(f"Error: {response.status_code}")
print(response.text)
return None
return response.json()
def load_memory(path: str = "docs/library", api_url: str = "http://0.0.0.0:8002/"):
"""Load memories from disk into the vector store"""
response = requests.post(
url=f"{api_url}load_memory",
json={
"load_file_path": path,
"clear_existing": True,
},
)
result = handle_api_response(response)
if result:
print(f"Memory loaded from {path}")
def main():
"""Main function"""
max_workers = 4
if max_workers > 1:
ray.init(num_cpus=max_workers)
num_runs = 4
num_trials = 1
model_name = "qwen3-8b"
enable_thinking = True
use_memory = True
use_memory_addition = False
use_memory_deletion = False
memory_base_url = "http://0.0.0.0:8003/"
if use_memory:
load_file_path = "docs/library/paper_data/task/bfcl_qwen3_8b.jsonl"
load_memory(load_file_path, memory_base_url)
for _ in range(num_runs):
run_agent(
max_workers=max_workers,
model_name=model_name,
dataset_name="bfcl-multi-turn-base-val",
experiment_suffix="w-fixed-memory",
data_path="data/multiturn_data_base_val.jsonl",
answer_path=Path("data/possible_answer"),
enable_thinking=enable_thinking,
num_trials=num_trials,
use_memory=use_memory,
memory_base_url=memory_base_url,
use_memory_addition=use_memory_addition,
use_memory_deletion=use_memory_deletion,
delete_freq=5,
freq_threshold=5,
utility_threshold=0.5,
)
if __name__ == "__main__":
main()