danaaubakirova HF Staff commited on
Commit
dbe3aaf
·
verified ·
1 Parent(s): 3f93234

Model card: how to use Carbon-X as a tool for an agent

Browse files

Adds a 'Using Carbon-X as a tool for an agent' subsection under How to use: wrapping the vLLM endpoint in a function, an OpenAI-style tool schema that passes DNA by reference, a minimal agent loop, a note on coding-agent skills, and tips. The snippets were tested end to end against the Carbon v26.00 endpoint with Kimi K3 as the agent.

Files changed (1) hide show
  1. README.md +87 -0
README.md CHANGED
@@ -24,6 +24,7 @@ An open 14B language model for DNA understanding and generation, from the **Carb
24
 
25
  1. [Model Summary](#model-summary)
26
  2. [How to use](#how-to-use)
 
27
  3. [Evaluation](#evaluation)
28
  4. [Training](#training)
29
  5. [Limitations](#limitations)
@@ -109,6 +110,92 @@ print(response.choices[0].message.content)
109
 
110
  vLLM also applies the sampling defaults from `generation_config.json` unless you override them in the request.
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  ### Tokenizer: working with DNA inputs
113
 
114
  The tokenizer switches between BPE for text and 6-mers for DNA. You can paste sequences directly into a message:
 
24
 
25
  1. [Model Summary](#model-summary)
26
  2. [How to use](#how-to-use)
27
+ - [Using Carbon-X as a tool for an agent](#using-carbon-x-as-a-tool-for-an-agent)
28
  3. [Evaluation](#evaluation)
29
  4. [Training](#training)
30
  5. [Limitations](#limitations)
 
110
 
111
  vLLM also applies the sampling defaults from `generation_config.json` unless you override them in the request.
112
 
113
+ ### Using Carbon-X as a tool for an agent
114
+
115
+ A general-purpose assistant can call Carbon-X when a question involves DNA. Serve Carbon-X with vLLM as above, wrap it in a function, and give that function to any chat model that supports tool calling.
116
+
117
+ **1. Wrap Carbon-X in a function.** The function takes a question and named DNA sequences, and returns Carbon-X's answer.
118
+
119
+ ```python
120
+ from openai import OpenAI
121
+
122
+ carbon = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
123
+
124
+
125
+ def ask_carbon(question: str, sequences: dict[str, str], context: str = "") -> str:
126
+ """Ask Carbon-X a question about one or more named DNA sequences."""
127
+ parts = [context, question] if context else [question]
128
+ parts += [f"{name}: <dna>{seq}</dna>" for name, seq in sequences.items()]
129
+ response = carbon.chat.completions.create(
130
+ model="HuggingFaceBio/Carbon-X",
131
+ messages=[{"role": "user", "content": "\n\n".join(parts)}],
132
+ max_tokens=4096,
133
+ extra_body={"chat_template_kwargs": {"enable_thinking": False}},
134
+ )
135
+ return response.choices[0].message.content
136
+ ```
137
+
138
+ **2. Describe it to the agent as a tool.** Let the agent refer to sequences by name, and have your code look up the DNA. Language models often miscopy long sequences, so the agent should never retype them.
139
+
140
+ ```python
141
+ import json
142
+
143
+ sequences = {"reference.fa": "ATGGTGCATCTGACTCCTGAGGAGAAGTCTGCCGTTACTGCCCTGTGGGGCAAGG",
144
+ "variant.fa": "ATGGTGCATCTGACTCCTGTGGAGAAGTCTGCCGTTACTGCCCTGTGGGGCAAGG"}
145
+
146
+ carbon_tool = {
147
+ "type": "function",
148
+ "function": {
149
+ "name": "ask_carbon",
150
+ "description": (
151
+ "Ask Carbon-X, a DNA language model, a question about DNA sequences: variant effects, "
152
+ "regulatory elements, organism of origin, sequence features. Refer to sequences by name; "
153
+ "do not paste DNA. Its answers are model predictions, not verified facts."
154
+ ),
155
+ "parameters": {
156
+ "type": "object",
157
+ "properties": {
158
+ "question": {"type": "string", "description": "One self-contained question."},
159
+ "sequences": {"type": "array", "items": {"type": "string", "enum": list(sequences)}},
160
+ "context": {"type": "string", "description": "Known gene, coordinates or annotations, if any."},
161
+ },
162
+ "required": ["question", "sequences"],
163
+ },
164
+ },
165
+ }
166
+ ```
167
+
168
+ **3. Run the agent loop.** Any OpenAI-compatible chat model with tool calling works as the agent.
169
+
170
+ ```python
171
+ agent = OpenAI() # the agent model's provider
172
+ messages = [
173
+ {"role": "system", "content": "For questions about DNA, consult Carbon-X with the ask_carbon tool before answering."},
174
+ {"role": "user", "content": "variant.fa differs from reference.fa by one base. Is the change likely benign or pathogenic?"},
175
+ ]
176
+ while True:
177
+ reply = agent.chat.completions.create(model="<agent model>", messages=messages, tools=[carbon_tool])
178
+ message = reply.choices[0].message
179
+ messages.append(message)
180
+ if not message.tool_calls:
181
+ break
182
+ for call in message.tool_calls:
183
+ args = json.loads(call.function.arguments)
184
+ answer = ask_carbon(args["question"], {name: sequences[name] for name in args["sequences"]}, args.get("context", ""))
185
+ messages.append({"role": "tool", "tool_call_id": call.id, "content": answer})
186
+ print(message.content)
187
+ ```
188
+
189
+ Coding agents such as Claude Code or Codex CLI can use the same function as a skill: a short `SKILL.md` that says when to consult Carbon-X, plus a script that calls `ask_carbon` on sequence files in the workspace.
190
+
191
+ Tips for agent use:
192
+
193
+ - **Pass DNA by reference.** Keep sequences in files or a lookup table and let the agent name them.
194
+ - **Ask for Carbon-X explicitly.** Agents often answer DNA questions on their own instead of calling a tool. If you want Carbon-X's view, say so in the system prompt.
195
+ - **Send only A, C, G and T.** Trim padding such as leading or trailing `N`s. Other characters become `<oov>` tokens.
196
+ - **Leave exact operations to code.** Counting, coordinates and edits are more reliable in Python than in either model. For variants, compute the position and the reference and alternate bases in code and pass them as `context`.
197
+ - **Cap generation length.** For next-base and continuation questions, set `max_tokens` to what you need and a client timeout, since long DNA generations are slow (see [Limitations](#limitations)).
198
+
199
  ### Tokenizer: working with DNA inputs
200
 
201
  The tokenizer switches between BPE for text and 6-mers for DNA. You can paste sequences directly into a message: