An open-source Agent development toolkit that integrates the powerful capabilities of Volcengine.
- JDK
17or above
<dependency>
<groupId>com.volcengine.veadk</groupId>
<artifactId>veadk-java</artifactId>
<version>0.0.2</version>
</dependency>Use Agent.builder() as the VeADK Java entry point. It keeps the ADK Java
LlmAgent execution path, while adding VeADK defaults and metadata that
integrations can read without reflection.
import com.volcengine.veadk.Agent;
Agent agent = Agent.builder()
.name("quickstart-agent")
.description("Answers user questions.")
.instruction("You are a helpful assistant.")
.model("doubao-seed-2-1-pro-260628")
.modelApiKey(System.getenv("MODEL_AGENT_API_KEY"))
.build();Without an explicit provider, VeADK follows veadk-python and uses the
OpenAI-compatible path by default. Configure the API key with modelApiKey(...),
or leave it unset to read MODEL_AGENT_API_KEY from the environment. The
default base URL is Ark's OpenAI-compatible endpoint; use modelApiBase(...) /
modelBaseUrl(...) when you need OpenAI official, LiteLLM Proxy, or another
compatible gateway.
OpenAI-compatible endpoints are configured the same way, without requiring
application code to construct an ADK BaseLlm:
Agent agent = Agent.builder()
.name("openai-agent")
.instruction("You are a helpful assistant.")
.model("openai/gpt-4o")
.modelApiKey(System.getenv("OPENAI_API_KEY"))
.modelBaseUrl("https://api.openai.com/v1")
.build();Use modelProvider("ark") only when you want the Ark-specific ArkLlm adapter:
Agent agent = Agent.builder()
.name("ark-agent")
.modelProvider("ark")
.model("doubao-seed-2-1-pro-260628")
.modelApiKey(System.getenv("MODEL_AGENT_API_KEY"))
.modelApiBase("https://ark.cn-beijing.volces.com/api/v3")
.build();For LiteLLM Proxy or an internal OpenAI-compatible gateway, set the base URL to
that endpoint. Use modelProvider("openai") when the model name itself contains
provider routing text:
Agent agent = Agent.builder()
.name("litellm-agent")
.modelProvider("openai")
.model("anthropic/claude-sonnet-4")
.modelApiKey(System.getenv("LITELLM_API_KEY"))
.modelBaseUrl("http://localhost:4000/v1")
.build();You can also provide an explicit ADK BaseLlm instance when you want to own the
model configuration yourself:
import com.google.adk.models.BaseLlm;
import com.volcengine.veadk.Agent;
import com.volcengine.veadk.model.ArkLlm;
BaseLlm model = new ArkLlm("doubao-seed-2-1-pro-260628");
Agent agent = Agent.builder()
.name("custom-model-agent")
.instruction("You are a helpful assistant.")
.model(model)
.build();Metadata is available through a typed extractor. For VeADK Agent instances it
uses Agent.metadataSnapshot(); for plain ADK LlmAgent instances it falls
back to public ADK getters.
import com.volcengine.veadk.AgentMetadata;
import com.volcengine.veadk.AgentMetadataExtractor;
AgentMetadata metadata = AgentMetadataExtractor.extract(agent);
System.out.println(metadata.tools());For a simple blocking interaction, use the VeADK runner convenience API:
import com.volcengine.veadk.Runner;
String answer = new Runner(agent).run("Hello");Local skills are supported through ADK Java's SkillToolset. When
Agent.builder().skills(...) is configured, VeADK Java automatically injects
one SkillToolset unless the user already passed an explicit SkillToolset
through tools(...).
A skill is a directory containing a required SKILL.md file:
skills/
expense-policy-reviewer/
SKILL.md
references/
assets/
scripts/
The SKILL.md file must start with frontmatter whose name matches the skill
directory name:
---
name: expense-policy-reviewer
description: Review employee reimbursement requests against the company policy.
---
Follow the reimbursement policy and produce a concise review.Pass a skills root directory, a single skill directory, a SKILL.md/skill.md
file, or an explicit ADK SkillSource:
import java.nio.file.Path;
Agent agent = Agent.builder()
.name("expense-review-agent")
.instruction("Use local skills before answering policy questions.")
.modelName("doubao-seed-2-1-pro-260628")
.skills(Path.of("example/src/main/resources/skills"))
.skillsMode("local")
.build();Supported entries for skills(...) are:
PathorString: local filesystem path. A directory withSKILL.mdorskill.mdis treated as one skill; otherwise the directory is treated as a skills root containing skill subdirectories.SkillSource: any ADK Java skill source, includingLocalSkillSourceorClassPathSkillSource.
Multiple skill entries are merged in the order provided. If more than one entry
exposes the same skill name, the later entry takes precedence for both
list_skills and load_skill.
For skills packaged in application resources, pass ADK's classpath source explicitly:
import com.google.adk.skills.ClassPathSkillSource;
Agent agent = Agent.builder()
.name("classpath-skill-agent")
.skills(new ClassPathSkillSource("skills"))
.skillsMode("local")
.build();Remote skill source metadata and skill packages can be exposed through ADK
Java's SkillToolset with VeSkillSource. The source ID can be an AgentKit
Skill Space (ss-...) or SkillHub space (sp-...):
import com.google.adk.tools.skills.SkillToolset;
import com.volcengine.veadk.skills.VeSkillSource;
Agent agent = Agent.builder()
.name("remote-skill-agent")
.tools(new SkillToolset(new VeSkillSource(System.getenv("SKILL_SOURCE_ID"))))
.build();For Skills Sandbox delegation, configure an AgentKit Skill Space ID and expose
only the execute_skills tool:
import com.volcengine.veadk.tools.builtin.sandbox.ExecuteSkillsTool;
Agent agent = Agent.builder()
.name("remote-sandbox-agent")
.skills(System.getenv("SKILL_SPACE_ID"))
.skillsMode("skills_sandbox")
.tools(new ExecuteSkillsTool())
.build();Sandbox tools return structured errors when a tool call fails. Agents can use
error.code, error.message, error.suggestion, and error.retryable to
explain the failure or decide whether to retry:
{
"error": {
"code": "SKILLS_SANDBOX_A2A_FAILED",
"message": "message/send failed: invalid skill request",
"suggestion": "Check the Skills Sandbox A2A error message and retry only if the error is transient.",
"retryable": false
}
}Short-term memory is session-scoped context. Configure it on the agent, then
reuse the same userId and sessionId when running follow-up turns:
import com.volcengine.veadk.Agent;
import com.volcengine.veadk.Runner;
import com.volcengine.veadk.memory.ShortTermMemory;
ShortTermMemory shortTermMemory = ShortTermMemory.builder().local().build();
Agent agent = Agent.builder()
.name("memory_agent")
.instruction("Remember what the user tells you.")
.modelName("doubao-seed-2-1-pro-260628")
.shortTermMemory(shortTermMemory)
.build();
Runner runner = new Runner(agent, "memory_demo");
runner.run("user_1", "session_1", "My name is Ming.");
runner.run("user_1", "session_1", "What is my name?");The extracted metadata includes:
- Basic agent fields:
id,name,description,instructionSummary,modelName, andautoSaveSession. tools: tool names with their source.explicitmeans the user passed the tool throughAgent.builder().tools(...);automeans the builder injected it from a configured VeADK component, such asloadKnowledgebase,loadMemory, orSkillToolset;adkis used when extracting from a plain ADKLlmAgent.subAgents: the same metadata shape for each child agent.components: stable component slots forknowledgebase,longTermMemory,shortTermMemory,tracer,toolset, andplugin.searchSources:web,knowledge, andmemory, each with anenabledflag and the associated tool name when applicable. The canonical tool names areweb_search,loadKnowledgebase, andloadMemory.
Examples that auto-create a model adapter or call ArkLlm need model credentials. The
resolution order is:
modelApiKey(...): explicit API key on the builder.MODEL_AGENT_API_KEY: raw model API key from the environment.MODEL_AGENT_API_KEY_ID: Ark API key ID. When set, VeADK resolves the raw key through Ark OpenAPI.MODEL_AGENT_API_KEY_NAME: Ark API key name. When set, VeADK resolves the raw key through Ark OpenAPI.- Volcengine AK/SK fallback: when no key value or key name is configured, VeADK resolves the first Ark API key in the account through Ark OpenAPI.
Ark OpenAPI fallback requires:
VOLCENGINE_ACCESS_KEYVOLCENGINE_SECRET_KEY- Optional:
VOLCENGINE_SESSION_TOKENorVOLC_SESSIONTOKEN - Optional:
REGION, defaulting tocn-beijing - Optional:
MODEL_AGENT_PROJECT_NAME, defaulting todefault - Optional:
CLOUD_PROVIDER=byteplusfor BytePlus control-plane routing
Example setup (macOS / Linux):
export MODEL_AGENT_API_KEY="<your-ark-api-key>"In the repository root, run: ./mvnw clean -DskipTests package
After building, the compiled artifacts needed by the examples will be generated in example/target.
Example sources are grouped by feature module:
example.basic: minimal Agent, reusable Ark agent, and CLI runner.example.skills: local skills, remote Skills Sandbox, and non-blocking remote skill tasks.example.knowledgebase: Viking and OpenSearch knowledgebase examples.example.memory: Mem0 memory example.example.web: ADK Web startup example.
Run the Agent example. It builds an Ark-backed Agent, registers a Java
function tool, and calls Runner.run(...) directly:
export MODEL_AGENT_API_KEY="<your-ark-api-key>"
./mvnw -pl example -am -q compile exec:java -Dexec.mainClass=com.volcengine.veadk.example.basic.AgentExampleRun the local skills example. It loads a reimbursement policy skill from
example/src/main/resources/skills and pre-reviews a realistic expense claim:
export MODEL_AGENT_API_KEY="<your-ark-api-key>"
./mvnw -pl example -am -q compile exec:java -Dexec.mainClass=com.volcengine.veadk.example.skills.LocalSkillsExpenseReviewAgentEntry class: com.volcengine.veadk.example.basic.AgentCliRunner.
Run it (without modifying the POM, directly via Maven Exec plugin coordinates):
./mvnw -pl example -am -q compile exec:java -Dexec.mainClass=com.volcengine.veadk.example.basic.AgentCliRunnerInteraction notes:
- After startup, follow the prompt to input messages and interact with
ArkAgent. - Type
quitto exit.
Start command:
./mvnw -pl example -am -q compile exec:java \
-Dexec.mainClass=com.volcengine.veadk.example.web.AdkWeb- Access URL:
http://localhost:8000
- Import the Maven multi-module project using IntelliJ IDEA or Eclipse.
- Directly run the
mainmethod ofAgentCliRunnerorAdkWeb. - Ensure the required environment variables are injected in your IDE run configuration (or start the IDE from a shell that has them set).
- If you need
web search,Viking Memory, orViking Knowledgebase, configure these environment variables:VOLCENGINE_ACCESS_KEY: Volcengine AccessKeyVOLCENGINE_SECRET_KEY: Volcengine SecretKey
- If you need
Mem0 Memory, configure either a direct Mem0 API key:DATABASE_MEM0_API_KEY: Mem0 API KeyDATABASE_MEM0_BASE_URL: Mem0 endpoint, for examplehttps://api.mem0.ai
- Or configure Volcengine credentials and a Mem0 project/API key id so VeADK can resolve the Mem0 API key:
VOLCENGINE_ACCESS_KEY: Volcengine AccessKeyVOLCENGINE_SECRET_KEY: Volcengine SecretKeyREGION: Volcengine region, defaults tocn-beijingDATABASE_MEM0_PROJECT_ID: Mem0 memory project idDATABASE_MEM0_API_KEY_ID: optional Mem0 API key id
- If you need TLS Trace, besides AK/SK, also configure the TLS topic:
OBSERVABILITY_OPENTELEMETRY_TLS_SERVICE_NAME: ID of the TLS service trace log topic
Run the Mem0 memory example:
./mvnw -q install -DskipTests
./mvnw -pl example -am -q compile exec:java -Dexec.mainClass=com.volcengine.veadk.example.memory.Mem0MemoryAgent- Python version and documentation: veadk-python.
The Java Agent provides a small, typed contract. It matches the Python package
at the user-entry level (Agent.builder(), model, tools, sub-agents,
memory/knowledgebase metadata), while Java records metadata from explicit
builder state and ADK public accessors instead of dynamically scanning object
internals.
The Java Agent does not currently support these Python-side capabilities:
runtime=codex/piagentenableResponsesaio_sandboxenableA2uienableTunnel- YAML or dynamic tool discovery
- Error on startup
Missing required configuration: <ENV_NAME>: indicates a required environment variable is not set; please complete it according to the prompt. - Unable to access memory/knowledgebase/search services: check AK/SK and network connectivity.
- Port occupied: if port
8000is occupied, adjust via--server.portor in the startup parameters ofAdkWeb.main.
This project takes security seriously. For vulnerability reporting and supported versions, see SECURITY.md
This project uses the Apache License 2.0; see the LICENSE file for details.