feat: Add support for OpenAI-compatible LLM endpoints (Groq, Ollama, Azure OpenAI, etc.)
维护者通常 1 天内回复
评估
这个 Issue 还没有评估数据。
描述
🔴 Required Information
Is your feature request related to a specific problem?
Yes. Currently, ADK-Java only supports Google's Gemini and Claude models out of the box. Developers cannot easily use other LLM
providers that implement the OpenAI Chat Completions API format, such as:
- Groq (fast inference with open models)
- Ollama (local models for offline development)
- Azure OpenAI (enterprise deployments)
- Perplexity (search-augmented responses)
- Any custom OpenAI-compatible endpoint
Python ADK supports this via LiteLLM integration, but Java ADK lacks a native solution. This creates friction for developers who
want to:
- Experiment with different model providers
- Reduce inference costs by using alternative providers
- Develop/test locally without external API calls
- Support enterprise requirements (Azure OpenAI)
Describe the Solution You'd Like
Add a new OpenAiCompatibleLlm class that wraps the existing ChatCompletionsHttpClient to support any OpenAI-compatible endpoint
with a simple builder pattern.
Key capabilities:
- Builder pattern for easy configuration (baseUrl, headers, timeout)
- Pattern-based registry integration (e.g.,
groq-.*,ollama-.*) - Reuses existing
ChatCompletionsHttpClientinfrastructure - Non-streaming requests (matches current
ChatCompletionsHttpClientcapabilities) - Comprehensive tests (unit + integration + manual verification)
Impact on your work
Impact Level: High
This feature is critical for:
- My current project: Building a multi-model agent system that needs to switch between Gemini (complex reasoning) and Groq
(fast responses) based on task type - Cost optimization: Groq is 10x cheaper than Gemini for simple tasks
- Local development: Need Ollama support for offline testing without API costs
Timeline: Would like this in the next release if possible. Currently using a workaround with direct HTTP calls, but it's not
maintainable.
Willingness to contribute
Yes - I have already implemented this feature with:
- ✅ Core
OpenAiCompatibleLlmclass with builder pattern - ✅ 13 unit tests (builder validation, registry integration, error handling)
- ✅ Integration tests with Ollama
- ✅ Manual verification with Groq API (tested successfully)
- ✅ README documentation with examples
- ✅ Follows Google Java Style Guide (google-java-format applied)
- ✅ Aligned with CONTRIBUTING.md requirements
Can submit PR immediately if maintainers approve this approach.
🟡 Recommended Information
Describe Alternatives You've Considered
-
Direct HTTP calls: Manually building requests to OpenAI-compatible endpoints
- ❌ Doesn't integrate with
LlmRegistry - ❌ No pattern matching for model resolution
- ❌ Duplicates HTTP client logic
- ❌ Not maintainable
- ❌ Doesn't integrate with
-
Separate library wrapper: Create external library for each provider
- ❌ Fragments ecosystem
- ❌ Each provider needs separate maintenance
- ❌ Doesn't leverage existing ADK infrastructure
-
Use Python ADK instead: Switch to Python for LiteLLM support
- ❌ Not viable for Java-based projects
- ❌ Team expertise is in Java
-
Wait for official provider support: Request Google add each provider individually
- ❌ Slow (requires coordination with each provider)
- ❌ Doesn't scale to custom/internal endpoints
Why the proposed solution is better: Single implementation supports all OpenAI-compatible providers, reuses existing
infrastructure, and allows custom endpoints.
Proposed API / Implementation
// Example 1: Groq (fast inference)
OpenAiCompatibleLlm groq = OpenAiCompatibleLlm.builder()
.baseUrl("https://api.groq.com/openai/v1/")
.headers(ImmutableMap.of("Authorization", "Bearer " + apiKey))
.modelName("llama-3.3-70b-versatile")
.timeoutMillis(30_000)
.build();
// Register pattern for model resolution
groq.registerWithPattern("groq-.*");
// Use with LlmAgent
LlmAgent agent = LlmAgent.builder()
.model("groq-llama-3.3-70b-versatile")
.instruction("You are a helpful assistant.")
.build();
String response = agent.runAsync(invocationContext).blockingFirst();
// Example 2: Ollama (local models)
OpenAiCompatibleLlm ollama = OpenAiCompatibleLlm.builder()
.baseUrl("http://localhost:11434/v1/")
.headers(ImmutableMap.of()) // No auth for local
.modelName("ollama-llama2")
.build();
ollama.registerWithPattern("ollama-.*");
// Example 3: Azure OpenAI (enterprise)
OpenAiCompatibleLlm azure = OpenAiCompatibleLlm.builder()
.baseUrl("https://<resource>.openai.azure.com/openai/deployments/<deployment>/")
.headers(ImmutableMap.of("api-key", azureApiKey))
.modelName("azure-gpt-4")
.build();
azure.registerWithPattern("azure-.*");
Implementation Architecture:
- OpenAiCompatibleLlm extends BaseLlm
- Wraps existing ChatCompletionsHttpClient (no code duplication)
- Uses LlmRegistry.registerLlm(pattern, factory) for pattern matching
- Throws UnsupportedOperationException for live connections (OpenAI API limitation)
Files to be added/modified:
M README.md
A core/src/main/java/com/google/adk/models/OpenAiCompatibleLlm.java
A core/src/test/java/com/google/adk/models/OpenAiCompatibleLlmTest.java
A core/src/test/java/com/google/adk/models/OpenAiCompatibleLlmIntegrationTest.java
A core/src/test/java/com/google/adk/models/ManualGroqTest.java
Additional Context
Testing completed:
- ✅ Unit tests: 13 tests, all passing
- ✅ Integration tests: Ollama-based tests for real endpoints
- ✅ Manual verification: Successfully tested with Groq API (llama-3.3-70b-versatile)
- Simple completion test
- Registry integration test
- Multi-turn conversation with context retention
Design decisions:
- Non-streaming only: Matches ChatCompletionsHttpClient capabilities (streaming can be added in future PR)
- Pattern-based registration: Allows multiple providers with different prefixes (e.g., groq-, ollama-, azure-*)
- No live connections: OpenAI Chat Completions API doesn't support bidirectional live connections
Questions for maintainers:
- Should we add streaming support in a follow-up PR, or include it now?
- Any concerns with the pattern-based registration approach?
- Should integration tests be tagged/skipped in CI (currently requires manual Ollama setup)?
Related: Addresses similar functionality to Python ADK's LiteLLM integration, but using native Java implementation that reuses
existing ADK infrastructure.
Implementation ready: I have a fully tested, working implementation and can submit a PR immediately upon approval of this approach.
- 主要语言
- Java
- 星标
- 1.7k
- 派生
- 433
- 平均合并
- 2 天 23 小时
- 30 天内合并 PR
- 52
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
google/adk-java 的其他 Issue
-
GeminiUtil placeholder user turn ("Continue output. DO NOT look at this line ...") is flagged by prompt injection filters可能已有人在做 @hemasekhar-p 于 6 天前认领。 未关闭needs review
难度 2/5 1-3 小时 新手友好度 76/100
google/adk-java#1628 · 1 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
[spring-ai] Streaming responses ending with CJK punctuation (。!?) are misclassified as partial and never persisted to the session可能已有人在做 @hirematha 于 9 天前认领。 未关闭needs review
难度 2/5 1-3 小时 新手友好度 84/100
google/adk-java#1608 · 3 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
VertexAiSessionService: Event.id differs between the streamed event and getSession (id is not sent to Vertex and the appendEvent response is empty)可能已有人在做 @hemasekhar-p 于 1 天前认领。 未关闭waiting on reporter
难度 4/5 3-5 天 新手友好度 45/100
google/adk-java#1651 · 2 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
runLive passes partial events to appendEvent and never aggregates text chunks, unlike ADK Python可能已有人在做 @hemasekhar-p 于 1 天前认领。 未关闭needs review
难度 4/5 3-5 天 新手友好度 45/100
google/adk-java#1648 · 3 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
FirestoreSessionService compares event timestamps as text, reordering or skipping same-second events可能已有人在做 @hemasekhar-p 于 2 天前认领。 未关闭needs review
难度 3/5 1-2 天 新手友好度 50/100
google/adk-java#1646 · 3 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
相似的 Issue
-
status: waiting-for-triage
难度 2/5 1-3 小时 新手友好度 72/100
-
bug
难度 2/5 1-3 小时 新手友好度 62/100
-
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复
-
AOT compilation fails for derived delete queries returning Set可能已有人在做 @ryujungkyun 今天认领。 未关闭status: waiting-for-triage
难度 2/5 1-3 小时 新手友好度 72/100
spring-projects/spring-data-jpa#4387 ·
维护者通常 3 天内回复
-
[Bug] System alert time picker no longer applies start-only or end-only filters可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
apache/rocketmq-dashboard#6636 ·
维护者通常 3 天内回复