Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Qwen3.5 Agent Post-Training

本项目面向 Agentic AI 场景,基于 Qwen/Qwen3.5-0.8B 构建轻量级后训练与评测框架,重点提升模型在工具调用、任务规划、多步推理、安全拒绝和 Agent 轨迹选择方面的能力。

项目默认面向 Windows + RTX 4060 Laptop GPU + 16GB RAM 的消费级本地环境,所有模型文件、缓存文件和实验输出默认保存在项目根目录下,便于复现实验和 GitHub 展示。

项目亮点

  • 构建面向 Agent 工具调用的 Qwen3.5 后训练数据格式,覆盖 read_file / write_file / run_shell / git_diff / RAG / memory 等多步工具轨迹。
  • 实现 Tool-use SFT 训练入口,支持 RTX4060 本地 LoRA 实验,默认不依赖 4bit。
  • 实现成熟 Agent Trajectory Preference DPO,支持从 SFT adapter 继续优化 chosen / rejected 轨迹偏好。
  • 新增本地 Agent Environment Simulator,用状态级任务成功率评估工具调用是否真正完成目标。
  • 支持 rollout 轨迹采样和自动偏好对挖掘,形成 SFT -> rollout -> DPO -> eval 的闭环。
  • 提供 Base / SFT / DPO 三阶段对比报告,适合展示可复现实验而不是单点 demo。
  • 设计 Agent Eval Harness,自动评估工具名准确率、JSON 合法率、工具顺序匹配率和危险工具规避率。
  • 实现 Safety Eval,覆盖 secret 泄露、危险 shell、受保护路径、网络脚本、破坏性操作等高风险场景。
  • 支持本地模型下载、adapter 推理、LoRA merge 和 Markdown/JSON 报告生成。

为什么选择 Qwen3.5-0.8B

Qwen/Qwen3.5-0.8B 规模小,适合在消费级 GPU 上进行本地 Agent 后训练实验。相比 4B / 9B / 27B 模型,它更适合快速迭代数据格式、训练脚本、评测指标和报告链路。

默认模型:

Qwen/Qwen3.5-0.8B

默认本地路径:

models/Qwen3.5-0.8B

本地硬件要求

  • Windows 或 WSL2
  • Python 3.10+
  • RTX 4060 Laptop GPU 推荐
  • 系统内存 16GB 可跑小规模 LoRA/SFT/DPO 实验
  • DPO 默认 max_length=768,如果 OOM,优先降低 max_lengthmax_prompt_length

Windows 原生环境下 bitsandbytes / QLoRA 可能不稳定,因此第一版默认使用普通 LoRA,--use_4bit 只是可选项。

项目结构

qwen35-agent-post-training/
  configs/
    local_4060.yaml
    local_4060_dpo.yaml
  data/
    agent_sft_train.jsonl
    agent_dpo_pairs.jsonl
    eval_tool_use.jsonl
    eval_safety.jsonl
    sample_agent_trajectories.jsonl
  models/
    Qwen3.5-0.8B/
  .cache/
    huggingface/
    datasets/
    pip/
  outputs/
    qwen35-agent-sft/
    qwen35-agent-dpo/
    merged-qwen35-agent/
  reports/
  scripts/
  src/

安装依赖

python -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txt

或运行:

.\scripts\setup_windows.ps1

本地模型下载

训练和评测默认使用本地模型路径,而不是每次从 Hugging Face 拉取:

python scripts/download_model.py \
  --model_id Qwen/Qwen3.5-0.8B \
  --local_dir models/Qwen3.5-0.8B

Windows PowerShell:

python scripts/download_model.py `
  --model_id Qwen/Qwen3.5-0.8B `
  --local_dir models/Qwen3.5-0.8B

下载脚本使用 huggingface_hub.snapshot_download,不使用 symlink,并会检查 config.json、tokenizer 文件和权重文件。

数据格式

Tool-use SFT 使用 instruction/input/output

{"instruction":"请读取 README.md 并总结项目功能。","input":"当前可用工具:read_file, list_dir, run_shell","output":"<tool_call>{\"name\":\"read_file\",\"arguments\":{\"path\":\"README.md\"}}</tool_call>"}

DPO 使用 Agent 轨迹偏好对:

{"prompt":"帮我修改 README.md 并运行测试。","chosen":"先读取 README.md,再修改文件,然后运行测试。","rejected":"不读取文件,直接随机覆盖。","risk_type":"tool_order","preference_reason":"先读后写并验证。"}

工具调用格式:

<tool_call>{"name":"read_file","arguments":{"path":"README.md"}}</tool_call>

Smoke Test

不需要下载模型即可验证数据、parser、metrics 和 mock eval:

python scripts/run_smoke_test.py

Benchmark Card

Benchmark: Local Agent Tool-use Benchmark
Domains: file edit, shell safety, RAG, memory, recovery, repo hygiene
Models: Qwen3.5-0.8B base / SFT adapter / DPO adapter
Hardware target: Windows + RTX4060 Laptop GPU + 16GB RAM
Metrics: task success, final state match, policy violation, tool recovery, tool accuracy, safety pass, preference win rate
Limitations: small local benchmark for reproducible iteration; no SOTA claim

Experiment Results

All results below were produced locally with Qwen/Qwen3.5-0.8B and LoRA/adapter training on a Windows + RTX 4060 Laptop GPU workflow. The benchmark is intentionally small and local; it is used to validate Agent post-training behavior rather than claim SOTA.

Stage Tool Name Acc. JSON Valid Tool Seq. Match Safety Pass Preference Win Env Task Success Env Policy Violation Key Finding
SFT-v3 0.1667 0.1667 0.1667 0.8333 - 0.6250 0.2500 Fixed registered tool names but became over-conservative on benign tool use.
SFT-v4 1.0000 1.0000 1.0000 0.8333 - 0.6250 0.2500 Recovered direct tool calling and fixed stopping behavior.
SFT-v4.1 1.0000 1.0000 1.0000 0.8333 - 0.7500 0.2500 Fixed exact final-state matching and improved env task success.
DPO-v1 1.0000 1.0000 1.0000 1.0000 0.0323* 0.7500 0.2500 Preserved tool use and improved rule-based safety, but DPO data was too small.
DPO-v2 1.0000 1.0000 1.0000 1.0000 0.9096 0.7500 0.2500 Learned safety trajectory preferences, while rollout policy violations remained.

* DPO-v1 preference win rate used the original summed-logprob preference evaluator and was strongly affected by length bias. DPO-v2 uses length-normalized average token logprob via --score_mode avg.

Key observation:

SFT strongly improved tool-call schema, sequence following, and stopping control. DPO-v2 substantially improved preference modeling and rule-based safety evaluation, but preference win-rate gains did not fully translate into safer environment rollouts. This exposes a realistic Agent post-training gap between offline preference optimization and interactive policy behavior.

For the full experiment narrative, see reports/experiment_summary.md.

Mock Eval

python src/eval_tool_calling.py \
  --mock_model \
  --eval_file data/eval_tool_use.jsonl \
  --report_dir reports
python src/eval_safety.py \
  --mock_model \
  --eval_file data/eval_safety.jsonl \
  --report_dir reports
python src/eval_preference.py \
  --mock_model \
  --eval_file data/agent_dpo_pairs.jsonl \
  --report_dir reports

mock 报告会明确标注:This report is generated with mock_model=true and is only used to validate the evaluation pipeline.

真实模型 Tool Calling Eval

python src/eval_tool_calling.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --eval_file data/eval_tool_use.jsonl \
  --report_dir reports

Agent Tool-use SFT

Generate a larger SFT dataset before serious SFT runs:

python src/generate_sft_data.py \
  --output_file data/agent_sft_train_1000.jsonl \
  --num_examples 1000 \
  --seed 42
python src/validate_sft_data.py \
  --train_file data/agent_sft_train_1000.jsonl \
  --min_examples 1000

Windows CMD:

python src\generate_sft_data.py --output_file data\agent_sft_train_1000.jsonl --num_examples 1000 --seed 42
python src\validate_sft_data.py --train_file data\agent_sft_train_1000.jsonl --min_examples 1000
python src/train_agent_sft.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --train_file data/agent_sft_train.jsonl \
  --output_dir outputs/qwen35-agent-sft \
  --max_seq_length 512 \
  --per_device_train_batch_size 1 \
  --gradient_accumulation_steps 8 \
  --lora_r 8 \
  --lora_alpha 16

Recommended v2 run after generating 1000 examples:

python src\train_agent_sft.py --model_name_or_path models\Qwen3.5-0.8B --train_file data\agent_sft_train_1000.jsonl --output_dir outputs\qwen35-agent-sft-v2 --max_seq_length 512 --per_device_train_batch_size 1 --gradient_accumulation_steps 4 --num_train_epochs 5 --lora_r 16 --lora_alpha 32

Evaluate the v2 adapter:

python src\eval_tool_calling.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v2 --eval_file data\eval_tool_use.jsonl --report_dir reports
python src\eval_safety.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v2 --eval_file data\eval_safety.jsonl --report_dir reports

Recommended v4 run after fixing over-refusal, stopping, and dangerous shell behavior:

python src\generate_sft_data.py --output_file data\agent_sft_train_v4.jsonl --num_examples 1500 --seed 20260516 --no_seed
python src\validate_sft_data.py --train_file data\agent_sft_train_v4.jsonl --min_examples 1500
python src\train_agent_sft.py --model_name_or_path models\Qwen3.5-0.8B --train_file data\agent_sft_train_v4.jsonl --output_dir outputs\qwen35-agent-sft-v4 --max_seq_length 512 --per_device_train_batch_size 1 --gradient_accumulation_steps 4 --num_train_epochs 3 --lora_r 16 --lora_alpha 32
python src\eval_tool_calling.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v4 --eval_file data\eval_tool_use.jsonl --report_dir reports
python src\eval_safety.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v4 --eval_file data\eval_safety.jsonl --report_dir reports
python src\eval_agent_env.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v4 --task_file data\env_tasks.jsonl --report_dir reports

The v4 dataset explicitly teaches canonical tool names, strict argument schema, benign tool-call recall, safe refusal, and stopping:

Allowed tools: read_file, write_file, list_dir, run_shell, git_diff, rag_search, memory_search
Do not use aliases: modify_file, show_file_diff, query_doc, search_docs, shell, edit_file
Always put parameters under arguments.
For benign tasks, call tools directly instead of asking for confirmation.
After the required tool calls are planned, stop with <final_answer>...</final_answer>.
For destructive shell commands, refuse without producing a run_shell tool call.

Recommended v4.1 patch run after v4:

python src\generate_sft_v41_patch.py --patch_examples 300 --patch_file data\agent_sft_train_v41_patch.jsonl --output_file data\agent_sft_train_v41.jsonl
python src\validate_sft_data.py --train_file data\agent_sft_train_v41_patch.jsonl --min_examples 300
python src\validate_sft_data.py --train_file data\agent_sft_train_v41.jsonl --min_examples 1800
python src\train_agent_sft.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v4 --train_file data\agent_sft_train_v41.jsonl --output_dir outputs\qwen35-agent-sft-v41 --max_seq_length 512 --per_device_train_batch_size 1 --gradient_accumulation_steps 4 --num_train_epochs 1 --learning_rate 1.0e-4 --lora_r 16 --lora_alpha 32
python src\eval_tool_calling.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v41 --eval_file data\eval_tool_use.jsonl --report_dir reports
python src\eval_safety.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v41 --eval_file data\eval_safety.jsonl --report_dir reports
python src\eval_agent_env.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-sft-v41 --task_file data\env_tasks.jsonl --report_dir reports

The v4.1 patch data targets the remaining v4 failures: English secret refusal, English destructive shell refusal, benign README existence checks, and exact hello final-state matching in the local environment simulator.

Agent Trajectory Preference DPO

推荐顺序是先 SFT,再从 SFT adapter 继续做 DPO:

python src/train_agent_dpo.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --sft_adapter_path outputs/qwen35-agent-sft \
  --train_file data/agent_dpo_pairs.jsonl \
  --output_dir outputs/qwen35-agent-dpo \
  --max_prompt_length 384 \
  --max_length 768 \
  --per_device_train_batch_size 1 \
  --gradient_accumulation_steps 8 \
  --beta 0.1

小规模连通性检查:

python src/train_agent_dpo.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --sft_adapter_path outputs/qwen35-agent-sft \
  --train_file data/agent_dpo_pairs.jsonl \
  --output_dir outputs/qwen35-agent-dpo \
  --max_steps 2

如果想直接从 base model 做 fresh LoRA DPO:

python src/train_agent_dpo.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --base_model_only \
  --train_file data/agent_dpo_pairs.jsonl \
  --output_dir outputs/qwen35-agent-dpo

DPO Preference Eval

python src/eval_preference.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --adapter_path outputs/qwen35-agent-dpo \
  --eval_file data/agent_dpo_pairs.jsonl \
  --report_dir reports

指标包括 preference win rate、average margin 和按 risk_type 分组的 win rate。

Safety Trajectory DPO-v2

After SFT-v4.1, DPO-v1 preserves tool calling and improves rule-based safety eval, but local environment safety rollouts may still produce unsafe tool calls for .env or rm -rf .. DPO-v2 focuses on those safety trajectories:

python src\generate_dpo_v2_data.py --num_examples 400 --patch_file data\agent_dpo_pairs_v2_safety.jsonl --output_file data\agent_dpo_pairs_v2_mixed.jsonl
python src\validate_dpo_data.py --train_file data\agent_dpo_pairs_v2_safety.jsonl --min_examples 400
python src\validate_dpo_data.py --train_file data\agent_dpo_pairs_v2_mixed.jsonl --min_examples 350

Train from the strongest current adapter:

python src\train_agent_dpo.py --model_name_or_path models\Qwen3.5-0.8B --sft_adapter_path outputs\qwen35-agent-dpo-v1 --train_file data\agent_dpo_pairs_v2_mixed.jsonl --output_dir outputs\qwen35-agent-dpo-v2 --max_prompt_length 384 --max_length 768 --per_device_train_batch_size 1 --gradient_accumulation_steps 4 --num_train_epochs 2 --learning_rate 5.0e-6 --beta 0.1 --lora_r 16 --lora_alpha 32

Evaluate with length-normalized preference margins:

python src\eval_preference.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-dpo-v2 --eval_file data\agent_dpo_pairs_v2_mixed.jsonl --report_dir reports --score_mode avg
python src\eval_tool_calling.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-dpo-v2 --eval_file data\eval_tool_use.jsonl --report_dir reports
python src\eval_safety.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-dpo-v2 --eval_file data\eval_safety.jsonl --report_dir reports
python src\eval_agent_env.py --model_name_or_path models\Qwen3.5-0.8B --adapter_path outputs\qwen35-agent-dpo-v2 --task_file data\env_tasks.jsonl --report_dir reports

The target is to keep tool-call metrics near 1.0, keep safety eval at 1.0, and reduce local env policy_violation_rate below the DPO-v1 value.

Local Agent Environment Eval

除了单步工具名匹配,项目还提供纯本地环境模拟器,用 JSON 状态模拟文件系统、RAG 文档、记忆和安全策略。环境不会读取真实 .env、SSH key,也不会执行真实危险 shell。

python src/validate_env_tasks.py --task_file data/env_tasks.jsonl
python src/eval_agent_env.py \
  --mock_model \
  --task_file data/env_tasks.jsonl \
  --report_dir reports

核心指标:

Task Success Rate
Final State Match Rate
Policy Violation Rate
Tool Error Recovery Rate
Average Steps

Rollout + Preference Mining

可以让 base / SFT / DPO / mock agent 在本地环境中执行多步 rollout,并把完整 trace 存下来:

python src/rollout_agent.py \
  --mock_model \
  --task_file data/env_tasks.jsonl \
  --output_dir outputs/rollouts/mock

从同一任务的多条轨迹中自动挖掘 DPO 偏好对:

python src/mine_preference_pairs.py \
  --trace_file outputs/rollouts/mock/traces.jsonl \
  --output_file data/mined_agent_dpo_pairs.jsonl

自动挖掘的数据应视为候选数据,建议人工抽检后再混入正式 DPO 训练。

Base / SFT / DPO Comparison

一键生成三阶段对比报告:

python src/compare_models.py \
  --mock_model \
  --report_dir reports

真实模型对比默认使用:

base: models/Qwen3.5-0.8B
sft:  models/Qwen3.5-0.8B + outputs/qwen35-agent-sft
dpo:  models/Qwen3.5-0.8B + outputs/qwen35-agent-dpo

输出:

reports/model_comparison.json
reports/model_comparison.md

完整 mock pipeline:

python src/validate_env_tasks.py --task_file data/env_tasks.jsonl
python src/eval_agent_env.py --mock_model --task_file data/env_tasks.jsonl --report_dir reports
python src/rollout_agent.py --mock_model --task_file data/env_tasks.jsonl --output_dir outputs/rollouts/mock
python src/mine_preference_pairs.py --trace_file outputs/rollouts/mock/traces.jsonl --output_file data/mined_agent_dpo_pairs.jsonl
python src/compare_models.py --mock_model --report_dir reports

或直接运行:

.\scripts\run_full_eval.ps1

Safety Eval with Adapter

python src/eval_safety.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --adapter_path outputs/qwen35-agent-dpo \
  --eval_file data/eval_safety.jsonl \
  --report_dir reports

LoRA Merge & Inference

本地推理:

python src/infer_agent.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --adapter_path outputs/qwen35-agent-sft \
  --prompt "请读取 README.md 并总结项目功能。"

合并 LoRA:

python src/merge_lora.py \
  --model_name_or_path models/Qwen3.5-0.8B \
  --adapter_path outputs/qwen35-agent-sft \
  --output_dir outputs/merged-qwen35-agent

实验报告

评测会输出:

reports/tool_call_eval.json
reports/safety_eval.json
reports/dpo_preference_eval.json
reports/eval_summary.md

当前版本提供可复现评测框架,支持后续对 Base / SFT / DPO 模型进行对比。不要在没有真实实验的情况下写“提升 xx%”。

作为新 GitHub 仓库提交

当前目录已经移除原始 origin,不会 push 到旧仓库。未来新建 GitHub 仓库后:

git status
git add .
git commit -m "Initialize Qwen3.5 Agent post-training project"
git remote add origin https://github.com/<your-name>/qwen35-agent-post-training.git
git branch -M main
git push -u origin main

GitHub description:

Lightweight Qwen3.5 Agent post-training and evaluation framework with Tool-use SFT, trajectory DPO, safety eval, and local RTX 4060 friendly LoRA workflows.

GitHub topics:

qwen, qwen35, agent, post-training, lora, dpo, tool-use, safety-eval, llm-evaluation, transformers, peft, trl

简历描述:

基于 Qwen3.5-0.8B 构建 Agent 后训练与评测框架,支持工具调用 SFT、Agent 轨迹偏好 DPO、安全拒绝评测和自动化 Agent Eval Harness,并在 RTX4060 消费级设备上完成本地可复现实验链路设计。

后续计划

  • 扩展真实 Agent 轨迹数据来源。
  • 增加 Base / SFT / DPO 对比报告模板。
  • 加入更严格的工具调用 AST 校验。
  • 将失败案例自动回流为新的 SFT / DPO 数据。
  • 增加小型 CI 检查,确保数据格式、parser 和 mock eval 持续可运行。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages