Devstral 是一款專為軟件工程任務設計的代理型大語言模型(LLM),由 Mistral AI 和 All Hands AI 合作開發 🙌。Devstral 擅長使用工具探索代碼庫、編輯多個文件以及驅動軟件工程代理。該模型在 SWE-bench 上表現出色,使其成為該基準測試中排名第一的開源模型。
它基于 Mistral-Small-3.1 進行微調,因此具有長達 128k token 的上下文窗口。作為一款編碼代理,Devstral 僅支持文本處理,且在從 Mistral-Small-3.1
微調之前移除了視覺編碼器。
對于需要特殊能力(如擴展上下文、領域特定知識等)的企業,我們將發布超越 Mistral AI 社區貢獻的商業模型。
了解更多關于 Devstral 的信息,請閱讀我們的博客文章。
主要特點:
- 代理編碼:Devstral 專為代理編碼任務而設計,是軟件工程代理的理想選擇。
- 輕量級:其緊湊的尺寸僅為 240 億參數,輕巧到可以在單個 RTX 4090 或 32GB 內存的 Mac 上運行,使其成為本地部署和設備使用的合適模型。
- Apache 2.0 許可證:開放許可證,允許商業和非商業用途的使用和修改。
- 上下文窗口:128k 的上下文窗口。
- 分詞器:使用詞匯量為 131k 的 Tekken 分詞器。
基準測試結果
SWE-Bench
Devstral 在 SWE-Bench Verified 上取得了 46.8% 的分數,比之前的開源 SoTA 高出 6%。
Model | Scaffold | SWE-Bench Verified (%) |
---|---|---|
Devstral | OpenHands Scaffold | 46.8 |
GPT-4.1-mini | OpenAI Scaffold | 23.6 |
Claude 3.5 Haiku | Anthropic Scaffold | 40.6 |
SWE-smith-LM 32B | SWE-agent Scaffold | 40.2 |
在相同的測試框架(由All Hands AI 🙌提供的OpenHands)下進行評估時,Devstral的表現遠超更大的模型,如Deepseek-V3-0324和Qwen3 232B-A22B。
使用
我們建議將 Devstral 與 OpenHands 腳手架一起使用。您可以通過我們的 API 或本地運行來使用它。
API
按照以下說明創建 Mistral 賬戶并獲取 API 密鑰。
然后運行這些命令以啟動 OpenHands docker 容器。
export MISTRAL_API_KEY=<MY_KEY>docker pull docker.all-hands.dev/all-hands-ai/runtime:0.39-nikolaikmkdir -p ~/.openhands-state && echo '{"language":"en","agent":"CodeActAgent","max_iterations":null,"security_analyzer":null,"confirmation_mode":false,"llm_model":"mistral/devstral-small-2505","llm_api_key":"'$MISTRAL_API_KEY'","remote_runtime_resource_factor":null,"github_token":null,"enable_default_condenser":true}' > ~/.openhands-state/settings.jsondocker run -it --rm --pull=always \-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.39-nikolaik \-e LOG_ALL_EVENTS=true \-v /var/run/docker.sock:/var/run/docker.sock \-v ~/.openhands-state:/.openhands-state \-p 3000:3000 \--add-host host.docker.internal:host-gateway \--name openhands-app \docker.all-hands.dev/all-hands-ai/openhands:0.39
OpenHands(推薦)
啟動服務器以部署 Devstral-Small-2505
確保您已啟動如上所述的 OpenAI 兼容服務器,例如 vLLM 或 Ollama。然后,您可以使用 OpenHands 與 Devstral-Small-2505 進行交互。
在本教程中,我們通過運行以下命令啟動了一個 vLLM 服務器:
vllm serve mistralai/Devstral-Small-2505 --tokenizer_mode mistral --config_format mistral --load_format mistral --tool-call-parser mistral --enable-auto-tool-choice --tensor-parallel-size 2
服務器地址應采用以下格式:http://<your-server-url>:8000/v1
啟動 OpenHands
您可以在此處按照 OpenHands 的安裝步驟進行操作。
啟動 OpenHands 的最簡單方法是使用 Docker 鏡像:
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.38-nikolaikdocker run -it --rm --pull=always \-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.38-nikolaik \-e LOG_ALL_EVENTS=true \-v /var/run/docker.sock:/var/run/docker.sock \-v ~/.openhands-state:/.openhands-state \-p 3000:3000 \--add-host host.docker.internal:host-gateway \--name openhands-app \docker.all-hands.dev/all-hands-ai/openhands:0.38
然后,您可以在 http://localhost:3000
訪問 OpenHands UI。
連接到服務器
當訪問 OpenHands UI 時,系統會提示您連接到服務器。您可以使用高級模式連接到您之前啟動的服務器。
填寫以下字段:
- 自定義模型: openai/mistralai/Devstral-Small-2505
- 基礎 URL: http://:8000/v1
- API 密鑰: token(或您啟動服務器時使用的任何其他令牌,如果有的話)
使用由 Devstral 驅動的 OpenHands
現在,您可以通過開始新對話在 OpenHands 中使用 Devstral Small。讓我們構建一個待辦事項列表應用程序。
To-Do list app
-
讓我們請Devstral用以下提示生成應用程序:
Build a To-Do list app with the following requirements:- Built using FastAPI and React.- Make it a one page app that:- Allows to add a task.- Allows to delete a task.- Allows to mark a task as done.- Displays the list of tasks.- Store the tasks in a SQLite database.
2. 讓我們看看結果
你應該會看到代理構建應用程序,并能夠探索它生成的代碼。
如果它沒有自動完成,請讓 Devstral 部署應用程序或手動完成,然后前往前端部署 URL 查看應用程序。
3. 迭代
現在你已經有了第一個結果,你可以通過讓你的代理改進它來進行迭代。例如,在生成的應用程序中,我們可以點擊任務來標記為已完成,但添加一個復選框會提升用戶體驗。你也可以要求它添加一個編輯任務的功能,或者添加一個按狀態過濾任務的功能。
享受使用 Devstral Small 和 OpenHands 進行構建的樂趣吧!
vLLM(推薦)
我們建議使用此模型與vLLM庫一起實現生產就緒的推理管道。
安裝
確保安裝vLLM >= 0.8.5:
pip install vllm --upgrade
檢查:
python -c "import mistral_common; print(mistral_common.__version__)"
你也可以使用現成的 Docker 鏡像或在 Docker Hub 上查找。
服務器
我們建議您在服務器/客戶端設置中使用 Devstral。
- 啟動服務器:
vllm serve mistralai/Devstral-Small-2505 --tokenizer_mode mistral --config_format mistral --load_format mistral --tool-call-parser mistral --enable-auto-tool-choice --tensor-parallel-size 2
- 要 ping 客戶端,你可以使用一個簡單的 Python 代碼片段。
import requests
import json
from huggingface_hub import hf_hub_downloadurl = "http://<your-server-url>:8000/v1/chat/completions"
headers = {"Content-Type": "application/json", "Authorization": "Bearer token"}model = "mistralai/Devstral-Small-2505"def load_system_prompt(repo_id: str, filename: str) -> str:file_path = hf_hub_download(repo_id=repo_id, filename=filename)with open(file_path, "r") as file:system_prompt = file.read()return system_promptSYSTEM_PROMPT = load_system_prompt(model, "SYSTEM_PROMPT.txt")messages = [{"role": "system", "content": SYSTEM_PROMPT},{"role": "user","content": [{"type": "text","text": "<your-command>",},],},
]data = {"model": model, "messages": messages, "temperature": 0.15}response = requests.post(url, headers=headers, data=json.dumps(data))
print(response.json()["choices"][0]["message"]["content"])
Transformers
為了充分利用我們的模型與變壓器,請確保已安裝 mistral-common >= 1.5.5 以使用我們的分詞器。
pip install mistral-common --upgrade
然后加載我們的分詞器以及模型并生成:
import torchfrom mistral_common.protocol.instruct.messages import (SystemMessage, UserMessage
)
from mistral_common.protocol.instruct.request import ChatCompletionRequest
from mistral_common.tokens.tokenizers.mistral import MistralTokenizer
from mistral_common.tokens.tokenizers.tekken import SpecialTokenPolicy
from huggingface_hub import hf_hub_download
from transformers import AutoModelForCausalLMdef load_system_prompt(repo_id: str, filename: str) -> str:file_path = hf_hub_download(repo_id=repo_id, filename=filename)with open(file_path, "r") as file:system_prompt = file.read()return system_promptmodel_id = "mistralai/Devstral-Small-2505"
tekken_file = hf_hub_download(repo_id=model_id, filename="tekken.json")
SYSTEM_PROMPT = load_system_prompt(model_id, "SYSTEM_PROMPT.txt")tokenizer = MistralTokenizer.from_file(tekken_file)model = AutoModelForCausalLM.from_pretrained(model_id)tokenized = tokenizer.encode_chat_completion(ChatCompletionRequest(messages=[SystemMessage(content=SYSTEM_PROMPT),UserMessage(content="<your-command>"),],)
)output = model.generate(input_ids=torch.tensor([tokenized.tokens]),max_new_tokens=1000,
)[0]decoded_output = tokenizer.decode(output[len(tokenized.tokens):])
print(decoded_output)