Views
No views yet

<think>...</think> blocks before producing its final response. This thinking process is critical to the model's performance — thinking tokens must be kept in context for multi-turn conversations and agentic loops to function correctly.<think>...</think> blocks| Hyperparameter | Value |
|---|---|
| Total parameters | ~398B |
| Active parameters per token | ~13B |
| Experts | 256 (1 shared) |
| Active experts | 4 |
| Routing strategy | 4-of-256 (1.56% sparsity) |
| Dense layers | 6 |
| Pretraining context length | 8,192 |
| Context length after extension | 512k |
| Architecture | Sparse MoE (AfmoeForCausalLM) |

| Benchmark | Trinity-Large-Thinking | Opus-4.6 | GLM-5 | MiniMax-M2.7 | Kimi-K2.5 |
|---|---|---|---|---|---|
| IFBench | 52.3 | 53.1 | 72.3 | 75.7 | 70.2 |
| GPQA-Diamond | 76.3 | 89.2 | 81.6 | 86.2 | 86.9 |
| Tau2-Airline | 88.0 | 82.0 | 80.5 | 80.0 | 80.0 |
| Tau2-Telecom | 94.7 | 92.1 | 98.2 | 84.8 | 95.9 |
| PinchBench | 91.9 | 93.3 | 86.4 | 89.8 | 84.8 |
| AIME25 | 96.3 | 99.8 | 93.3 | 80.0 | 96.3 |
| BCFLv4 | 70.1 | 77.0 | 70.8 | 70.6 | 68.3 |
| MMLU-Pro | 83.4 | 89.1 | 85.8 | 80.8 | 87.1 |
| SWE-bench Verified* | 63.2 | 75.6 | 72.8 | 75.4 | 70.8 |
<think>...</think> blocks before generating its final response.1// API response structure
2{
3 "message": {
4 "role": "assistant",
5 "reasoning": "The user wants flight information. I need to determine the date for next Tuesday, search for flights SFO → JFK, and filter by price < $300.",
6 "content": "\n",
7 "tool_calls": [{
8 "function": {
9 "name": "search_flights",
10 "arguments": "{\"origin\": \"SFO\", \"destination\": \"JFK\", \"date\": \"2026-04-07\", \"max_price\": 300}"
11 }
12 }]
13 }
14}<think>...</think> tags during tokenization, maintaining the model's chain-of-thought across turns.reasoning_content can vary by version, and some versions only honor reasoning (related issue). For maximum compatibility in multi-turn loops, send assistant reasoning back as reasoning. If your SDK exposes reasoning_content in responses, map it to reasoning when appending assistant turns.reasoning nor reasoning_content), or if content is null, the model can lose prior chain-of-thought context. On simple tasks this may work fine, but on complex multi-step agentic tasks, the model can produce malformed tool calls (e.g., tool call XML appearing inside the reasoning field instead of as structured tool_calls). For best results, always preserve the reasoning field and use "" instead of null for content on tool-call turns.1vllm serve arcee-ai/Trinity-Large-Thinking \
2 --dtype bfloat16 \
3 --reasoning-parser deepseek_r1 \
4 --enable-auto-tool-choice \
5 --tool-call-parser qwen3_coder--reasoning-parser deepseek_r1 — Parses <think>...</think> reasoning blocks and exposes them via the reasoning field in the API response--tool-call-parser qwen3_coder — Parses structured tool calls from the model output into the OpenAI-compatible tool_calls array1from openai import OpenAI
2
3client = OpenAI(api_key="EMPTY", base_url="http://localhost:8000/v1")
4
5response = client.chat.completions.create(
6 model="arcee-ai/Trinity-Large-Thinking",
7 messages=[
8 {"role": "user", "content": "What's the weather like in Paris?"}
9 ],
10 tools=[{
11 "type": "function",
12 "function": {
13 "name": "get_weather",
14 "description": "Get current weather for a location",
15 "parameters": {
16 "type": "object",
17 "properties": {"location": {"type": "string"}},
18 "required": ["location"]
19 }
20 }
21 }],
22)
23
24# Access reasoning (thinking) content
25reasoning = response.choices[0].message.reasoning_content
26
27# Access final response or tool calls
28content = response.choices[0].message.content
29tool_calls = response.choices[0].message.tool_calls1import json
2from openai import OpenAI
3
4client = OpenAI(api_key="EMPTY", base_url="http://localhost:8000/v1")
5MODEL = "arcee-ai/Trinity-Large-Thinking"
6
7tools = [
8 {"type": "function", "function": {
9 "name": "get_customer_by_email",
10 "description": "Look up a customer by email.",
11 "parameters": {"type": "object", "properties": {"email": {"type": "string"}}, "required": ["email"]}
12 }},
13 {"type": "function", "function": {
14 "name": "cancel_subscription",
15 "description": "Cancel a subscription. Requires customer_id.",
16 "parameters": {"type": "object", "properties": {"customer_id": {"type": "string"}, "reason": {"type": "string"}}, "required": ["customer_id"]}
17 }}
18]
19
20def execute_tool(name, arguments):
21 """Simulate tool execution — replace with real implementations."""
22 args = json.loads(arguments)
23 if name == "get_customer_by_email":
24 return json.dumps({"customer_id": "C2001", "name": "Jane Doe", "plan": "Premium", "status": "active"})
25 elif name == "cancel_subscription":
26 return json.dumps({"success": True, "message": f"Subscription cancelled for {args['customer_id']}"})
27
28messages = [
29 {"role": "system", "content": "You are a helpful customer service agent."},
30 {"role": "user", "content": "I want to cancel my subscription. My email is jane@example.com"}
31]
32
33# Agent loop
34while True:
35 response = client.chat.completions.create(
36 model=MODEL, messages=messages, tools=tools,
37 tool_choice="auto", temperature=0, max_tokens=1000
38 )
39 msg = response.choices[0].message
40
41 # Build assistant message — PRESERVE the reasoning field
42 assistant_msg = {"role": "assistant", "content": msg.content}
43 if msg.reasoning_content:
44 assistant_msg["reasoning"] = msg.reasoning_content # ← critical for multi-turn
45 if msg.tool_calls:
46 assistant_msg["tool_calls"] = [
47 {"id": tc.id, "type": "function", "function": {"name": tc.function.name, "arguments": tc.function.arguments}}
48 for tc in msg.tool_calls
49 ]
50 messages.append(assistant_msg)
51
52 # If no tool calls, model gave its final response — done
53 if not msg.tool_calls:
54 print(f"Final response: {msg.content}")
55 break
56
57 # Execute tool calls and append results
58 for tc in msg.tool_calls:
59 result = execute_tool(tc.function.name, tc.function.arguments)
60 print(f" Tool: {tc.function.name}({tc.function.arguments}) → {result}")
61 messages.append({"role": "tool", "tool_call_id": tc.id, "content": result}) Tool: get_customer_by_email({"email": "jane@example.com"}) → {"customer_id": "C2001", ...}
Tool: cancel_subscription({"customer_id": "C2001", ...}) → {"success": true, ...}
Final response: Your subscription has been cancelled successfully.assistant_msg["reasoning"] = msg.reasoning_content # ← pass reasoning back as "reasoning"reasoning_content on the response object, but vLLM 0.18+ expects reasoning on input messages. The chat template then re-wraps it in <think>...</think> tags automatically.main transformers branch or pass trust_remote_code=True with a released version.1from transformers import AutoTokenizer, AutoModelForCausalLM
2import torch
3
4model_id = "arcee-ai/Trinity-Large-Thinking"
5tokenizer = AutoTokenizer.from_pretrained(model_id)
6model = AutoModelForCausalLM.from_pretrained(
7 model_id,
8 torch_dtype=torch.bfloat16,
9 device_map="auto",
10 trust_remote_code=True
11)
12
13messages = [
14 {"role": "user", "content": "Who are you?"},
15]
16
17input_ids = tokenizer.apply_chat_template(
18 messages,
19 add_generation_prompt=True,
20 return_tensors="pt"
21).to(model.device)
22
23outputs = model.generate(
24 input_ids,
25 max_new_tokens=4096,
26 do_sample=True,
27 temperature=0.6,
28 top_k=50,
29 top_p=0.95
30)
31
32response = tokenizer.decode(outputs[0], skip_special_tokens=True)
33print(response)1curl -X POST "https://openrouter.ai/v1/chat/completions" \
2 -H "Authorization: Bearer $OPENROUTER_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "model": "arcee-ai/trinity-large-thinking",
6 "messages": [
7 {
8 "role": "user",
9 "content": "What are some fun things to do in New York?"
10 }
11 ]
12 }'reasoning_details object (their unified reasoning shape). For multi-turn conversations, pass reasoning_details back as-is on assistant messages in subsequent requests — OpenRouter handles model-specific upstream translation (for Trinity, this is sent as reasoning_content on assistant turns upstream). For debugging, enable echo to inspect the upstream API call:{"debug": {"echo_upstream_body": true}}reasoning (not only reasoning_content) and keep assistant content non-null (empty string is fine). If your SDK emits reasoning_content, add a small adapter at your gateway to map it to reasoning before sending requests to vLLM.reasoning + content + tool_callsImportant: Step 4 must include thereasoningfield on the assistant message. The chat template reads this field and re-wraps it in<think>...</think>tags during tokenization. Omitting it degrades multi-step performance — see Preserving reasoning in multi-turn conversations for details.
1@misc{singh2026arceetrinity,
2 title = {Arcee Trinity Large Technical Report},
3 author = {Varun Singh and Lucas Krauss and Sami Jaghouar and Matej Sirovatka and Charles Goddard and Fares Obied and Jack Min Ong and Jannik Straube and Fern and Aria Harley and Conner Stewart and Colin Kealty and Maziyar Panahi and Simon Kirsten and Anushka Deshpande and Anneketh Vij and Arthur Bresnu and Pranav Veldurthi and Raghav Ravishankar and Hardik Bishnoi and DatologyAI Team and Arcee AI Team and Prime Intellect Team and Mark McQuade and Johannes Hagemann and Lucas Atkins},
4 year = {2026},
5 eprint = {2602.17004},
6 archivePrefix= {arXiv},
7 primaryClass = {cs.LG},
8 doi = {10.48550/arXiv.2602.17004},
9 url = {https://arxiv.org/abs/2602.17004}
10}