Skip to content

Commit d3a0a6c

Browse files
committed
feat: add qianfan llm provider
1 parent 772860b commit d3a0a6c

File tree

16 files changed

+301
-1
lines changed

16 files changed

+301
-1
lines changed

.env-template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ INTERNAL_KEY=<internal key for worker-to-backend authentication>
99
# GOOGLE_API_KEY=<your-google-api-key>
1010
# GROQ_API_KEY=<your-groq-api-key>
1111
# NOVITA_API_KEY=<your-novita-api-key>
12+
# QIANFAN_API_KEY=<your-qianfan-api-key>
1213
# OPEN_ROUTER_API_KEY=<your-openrouter-api-key>
1314

1415
# Remote Embeddings (Optional - for using a remote embeddings API instead of local SentenceTransformer)

application/core/model_configs.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
OPENROUTER_ATTACHMENTS = IMAGE_ATTACHMENTS
2929

3030
NOVITA_ATTACHMENTS = IMAGE_ATTACHMENTS
31+
QIANFAN_ATTACHMENTS = []
3132

3233

3334
OPENAI_MODELS = [
@@ -234,6 +235,21 @@
234235
),
235236
]
236237

238+
QIANFAN_MODELS = [
239+
AvailableModel(
240+
id="ernie-5.0",
241+
provider=ModelProvider.QIANFAN,
242+
display_name="ERNIE 5.0",
243+
description="Baidu Qianfan flagship text chat model",
244+
capabilities=ModelCapabilities(
245+
supports_tools=False,
246+
supports_structured_output=False,
247+
supported_attachment_types=QIANFAN_ATTACHMENTS,
248+
context_window=128000,
249+
),
250+
),
251+
]
252+
237253

238254
AZURE_OPENAI_MODELS = [
239255
AvailableModel(

application/core/model_settings.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class ModelProvider(str, Enum):
1919
PREMAI = "premai"
2020
SAGEMAKER = "sagemaker"
2121
NOVITA = "novita"
22+
QIANFAN = "qianfan"
2223

2324

2425
@dataclass
@@ -118,6 +119,10 @@ def _load_models(self):
118119
settings.LLM_PROVIDER == "novita" and settings.API_KEY
119120
):
120121
self._add_novita_models(settings)
122+
if settings.QIANFAN_API_KEY or (
123+
settings.LLM_PROVIDER == "qianfan" and settings.API_KEY
124+
):
125+
self._add_qianfan_models(settings)
121126
if settings.HUGGINGFACE_API_KEY or (
122127
settings.LLM_PROVIDER == "huggingface" and settings.API_KEY
123128
):
@@ -264,6 +269,21 @@ def _add_novita_models(self, settings):
264269
for model in NOVITA_MODELS:
265270
self.models[model.id] = model
266271

272+
def _add_qianfan_models(self, settings):
273+
from application.core.model_configs import QIANFAN_MODELS
274+
275+
if settings.QIANFAN_API_KEY:
276+
for model in QIANFAN_MODELS:
277+
self.models[model.id] = model
278+
return
279+
if settings.LLM_PROVIDER == "qianfan" and settings.LLM_NAME:
280+
for model in QIANFAN_MODELS:
281+
if model.id == settings.LLM_NAME:
282+
self.models[model.id] = model
283+
return
284+
for model in QIANFAN_MODELS:
285+
self.models[model.id] = model
286+
267287
def _add_docsgpt_models(self, settings):
268288
model_id = "docsgpt-local"
269289
model = AvailableModel(

application/core/model_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def get_api_key_for_provider(provider: str) -> Optional[str]:
1111
"openai": settings.OPENAI_API_KEY,
1212
"openrouter": settings.OPEN_ROUTER_API_KEY,
1313
"novita": settings.NOVITA_API_KEY,
14+
"qianfan": settings.QIANFAN_API_KEY,
1415
"anthropic": settings.ANTHROPIC_API_KEY,
1516
"google": settings.GOOGLE_API_KEY,
1617
"groq": settings.GROQ_API_KEY,

application/core/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class Settings(BaseSettings):
7979
HUGGINGFACE_API_KEY: Optional[str] = None
8080
OPEN_ROUTER_API_KEY: Optional[str] = None
8181
NOVITA_API_KEY: Optional[str] = None
82+
QIANFAN_API_KEY: Optional[str] = None
8283

8384
OPENAI_API_BASE: Optional[str] = None # azure openai api base url
8485
OPENAI_API_VERSION: Optional[str] = None # azure openai api version
@@ -164,6 +165,7 @@ class Settings(BaseSettings):
164165
"GROQ_API_KEY",
165166
"HUGGINGFACE_API_KEY",
166167
"NOVITA_API_KEY",
168+
"QIANFAN_API_KEY",
167169
"EMBEDDINGS_KEY",
168170
"FALLBACK_LLM_API_KEY",
169171
"QDRANT_API_KEY",

application/llm/handlers/handler_creator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class LLMHandlerCreator:
88
"openai": OpenAILLMHandler,
99
"google": GoogleLLMHandler,
1010
"novita": OpenAILLMHandler, # Novita uses OpenAI-compatible API
11+
"qianfan": OpenAILLMHandler, # Qianfan uses an OpenAI-compatible chat API
1112
"default": OpenAILLMHandler,
1213
}
1314

application/llm/llm_creator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from application.llm.llama_cpp import LlamaCpp
88
from application.llm.novita import NovitaLLM
99
from application.llm.openai import AzureOpenAILLM, OpenAILLM
10+
from application.llm.qianfan import QianfanLLM
1011
from application.llm.premai import PremAILLM
1112
from application.llm.sagemaker import SagemakerAPILLM
1213
from application.llm.open_router import OpenRouterLLM
@@ -26,6 +27,7 @@ class LLMCreator:
2627
"groq": GroqLLM,
2728
"google": GoogleLLM,
2829
"novita": NovitaLLM,
30+
"qianfan": QianfanLLM,
2931
"openrouter": OpenRouterLLM,
3032
}
3133

application/llm/qianfan.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from application.core.settings import settings
2+
from application.llm.openai import OpenAILLM
3+
4+
QIANFAN_BASE_URL = "https://qianfan.baidubce.com/v2"
5+
6+
7+
class QianfanLLM(OpenAILLM):
8+
def __init__(self, api_key=None, user_api_key=None, base_url=None, *args, **kwargs):
9+
super().__init__(
10+
api_key=api_key or settings.QIANFAN_API_KEY or settings.API_KEY,
11+
user_api_key=user_api_key,
12+
base_url=base_url or QIANFAN_BASE_URL,
13+
*args,
14+
**kwargs,
15+
)
16+
17+
def get_supported_attachment_types(self):
18+
"""Keep the first Qianfan integration text-only until attachment support is verified."""
19+
return []
20+
21+
def _supports_tools(self):
22+
"""Disable tools until Qianfan tool-calling is verified end-to-end."""
23+
return False
24+
25+
def _supports_structured_output(self):
26+
"""Disable structured output until JSON schema support is verified end-to-end."""
27+
return False

application/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def get_gpt_model() -> str:
3535
"anthropic": "claude-2",
3636
"groq": "llama3-8b-8192",
3737
"novita": "deepseek/deepseek-r1",
38+
"qianfan": "ernie-5.0",
3839
}
3940
return settings.LLM_NAME or model_map.get(settings.LLM_PROVIDER, "")
4041

docs/content/Deploying/DocsGPT-Settings.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Here are some of the most fundamental settings you'll likely want to configure:
4545
- `google`: Use Google's Vertex AI or Gemini models.
4646
- `anthropic`: Use Anthropic's Claude models.
4747
- `groq`: Use Groq's models.
48+
- `qianfan`: Use Baidu Qianfan models.
4849
- `huggingface`: Use HuggingFace Inference API.
4950
- `azure_openai`: Use Azure OpenAI Service.
5051
- `openai` (when using local inference engines like Ollama, Llama.cpp, TGI, etc.): This signals DocsGPT to use an OpenAI-compatible API format, even if the actual LLM is running locally.
@@ -54,8 +55,26 @@ Here are some of the most fundamental settings you'll likely want to configure:
5455
- **Examples:**
5556
- For `LLM_PROVIDER=openai`: `gpt-4o`
5657
- For `LLM_PROVIDER=google`: `gemini-2.0-flash`
58+
- For `LLM_PROVIDER=qianfan`: `ernie-5.0`
5759
- For local models (e.g., Ollama): `llama3.2:1b` (or any model name available in your setup).
5860

61+
### Example for Cloud API Provider (Baidu Qianfan)
62+
63+
To use Baidu Qianfan's `ernie-5.0` model, configure your `.env` file like this:
64+
65+
```env
66+
LLM_PROVIDER=qianfan
67+
QIANFAN_API_KEY=YOUR_QIANFAN_API_KEY
68+
LLM_NAME=ernie-5.0
69+
```
70+
71+
You can also reuse the generic `API_KEY` variable with `LLM_PROVIDER=qianfan`, but `QIANFAN_API_KEY` is clearer when you configure multiple providers in the same deployment.
72+
73+
The first Qianfan integration is intentionally conservative:
74+
75+
- Text chat is supported.
76+
- Attachments, tool calling, and structured output are left disabled until they are verified end-to-end against the Qianfan API.
77+
5978
- **`EMBEDDINGS_NAME`**: This setting defines which embedding model DocsGPT will use to generate vector embeddings for your documents. Embeddings are numerical representations of text that allow DocsGPT to understand the semantic meaning of your documents for efficient search and retrieval.
6079

6180
- **Default value:** `huggingface_sentence-transformers/all-mpnet-base-v2` (a good general-purpose embedding model).

0 commit comments

Comments
 (0)