add support for Anthropic (#2148)
Browse files### What problem does this PR solve?
#1853 add support for Anthropic
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
---------
Co-authored-by: Zhedong Cen <[email protected]>
Co-authored-by: Kevin Hu <[email protected]>
- conf/llm_factories.json +50 -0
- rag/llm/__init__.py +2 -1
- rag/llm/chat_model.py +68 -4
- requirements.txt +1 -0
- requirements_arm.txt +1 -0
- web/src/assets/svg/llm/anthropic.svg +1 -0
- web/src/pages/user-setting/setting-model/constant.ts +1 -0
conf/llm_factories.json
CHANGED
@@ -3240,6 +3240,56 @@
|
|
3240 |
"tags": "SPEECH2TEXT",
|
3241 |
"status": "1",
|
3242 |
"llm": []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3243 |
}
|
3244 |
]
|
3245 |
}
|
|
|
3240 |
"tags": "SPEECH2TEXT",
|
3241 |
"status": "1",
|
3242 |
"llm": []
|
3243 |
+
},
|
3244 |
+
{
|
3245 |
+
"name": "Anthropic",
|
3246 |
+
"logo": "",
|
3247 |
+
"tags": "LLM",
|
3248 |
+
"status": "1",
|
3249 |
+
"llm": [
|
3250 |
+
{
|
3251 |
+
"llm_name": "claude-3-5-sonnet-20240620",
|
3252 |
+
"tags": "LLM,CHAT,200k",
|
3253 |
+
"max_tokens": 204800,
|
3254 |
+
"model_type": "chat"
|
3255 |
+
},
|
3256 |
+
{
|
3257 |
+
"llm_name": "claude-3-opus-20240229",
|
3258 |
+
"tags": "LLM,CHAT,200k",
|
3259 |
+
"max_tokens": 204800,
|
3260 |
+
"model_type": "chat"
|
3261 |
+
},
|
3262 |
+
{
|
3263 |
+
"llm_name": "claude-3-sonnet-20240229",
|
3264 |
+
"tags": "LLM,CHAT,200k",
|
3265 |
+
"max_tokens": 204800,
|
3266 |
+
"model_type": "chat"
|
3267 |
+
},
|
3268 |
+
{
|
3269 |
+
"llm_name": "claude-3-haiku-20240307",
|
3270 |
+
"tags": "LLM,CHAT,200k",
|
3271 |
+
"max_tokens": 204800,
|
3272 |
+
"model_type": "chat"
|
3273 |
+
},
|
3274 |
+
{
|
3275 |
+
"llm_name": "claude-2.1",
|
3276 |
+
"tags": "LLM,CHAT,200k",
|
3277 |
+
"max_tokens": 204800,
|
3278 |
+
"model_type": "chat"
|
3279 |
+
},
|
3280 |
+
{
|
3281 |
+
"llm_name": "claude-2.0",
|
3282 |
+
"tags": "LLM,CHAT,100k",
|
3283 |
+
"max_tokens": 102400,
|
3284 |
+
"model_type": "chat"
|
3285 |
+
},
|
3286 |
+
{
|
3287 |
+
"llm_name": "claude-instant-1.2",
|
3288 |
+
"tags": "LLM,CHAT,100k",
|
3289 |
+
"max_tokens": 102400,
|
3290 |
+
"model_type": "chat"
|
3291 |
+
}
|
3292 |
+
]
|
3293 |
}
|
3294 |
]
|
3295 |
}
|
rag/llm/__init__.py
CHANGED
@@ -104,7 +104,8 @@ ChatModel = {
|
|
104 |
"Replicate": ReplicateChat,
|
105 |
"Tencent Hunyuan": HunyuanChat,
|
106 |
"XunFei Spark": SparkChat,
|
107 |
-
"BaiduYiyan": BaiduYiyanChat
|
|
|
108 |
}
|
109 |
|
110 |
|
|
|
104 |
"Replicate": ReplicateChat,
|
105 |
"Tencent Hunyuan": HunyuanChat,
|
106 |
"XunFei Spark": SparkChat,
|
107 |
+
"BaiduYiyan": BaiduYiyanChat,
|
108 |
+
"Anthropic": AnthropicChat
|
109 |
}
|
110 |
|
111 |
|
rag/llm/chat_model.py
CHANGED
@@ -1132,7 +1132,7 @@ class SparkChat(Base):
|
|
1132 |
class BaiduYiyanChat(Base):
|
1133 |
def __init__(self, key, model_name, base_url=None):
|
1134 |
import qianfan
|
1135 |
-
|
1136 |
key = json.loads(key)
|
1137 |
ak = key.get("yiyan_ak","")
|
1138 |
sk = key.get("yiyan_sk","")
|
@@ -1149,7 +1149,7 @@ class BaiduYiyanChat(Base):
|
|
1149 |
if "max_tokens" in gen_conf:
|
1150 |
gen_conf["max_output_tokens"] = gen_conf["max_tokens"]
|
1151 |
ans = ""
|
1152 |
-
|
1153 |
try:
|
1154 |
response = self.client.do(
|
1155 |
model=self.model_name,
|
@@ -1159,7 +1159,7 @@ class BaiduYiyanChat(Base):
|
|
1159 |
).body
|
1160 |
ans = response['result']
|
1161 |
return ans, response["usage"]["total_tokens"]
|
1162 |
-
|
1163 |
except Exception as e:
|
1164 |
return ans + "\n**ERROR**: " + str(e), 0
|
1165 |
|
@@ -1173,7 +1173,7 @@ class BaiduYiyanChat(Base):
|
|
1173 |
gen_conf["max_output_tokens"] = gen_conf["max_tokens"]
|
1174 |
ans = ""
|
1175 |
total_tokens = 0
|
1176 |
-
|
1177 |
try:
|
1178 |
response = self.client.do(
|
1179 |
model=self.model_name,
|
@@ -1193,3 +1193,67 @@ class BaiduYiyanChat(Base):
|
|
1193 |
return ans + "\n**ERROR**: " + str(e), 0
|
1194 |
|
1195 |
yield total_tokens
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1132 |
class BaiduYiyanChat(Base):
|
1133 |
def __init__(self, key, model_name, base_url=None):
|
1134 |
import qianfan
|
1135 |
+
|
1136 |
key = json.loads(key)
|
1137 |
ak = key.get("yiyan_ak","")
|
1138 |
sk = key.get("yiyan_sk","")
|
|
|
1149 |
if "max_tokens" in gen_conf:
|
1150 |
gen_conf["max_output_tokens"] = gen_conf["max_tokens"]
|
1151 |
ans = ""
|
1152 |
+
|
1153 |
try:
|
1154 |
response = self.client.do(
|
1155 |
model=self.model_name,
|
|
|
1159 |
).body
|
1160 |
ans = response['result']
|
1161 |
return ans, response["usage"]["total_tokens"]
|
1162 |
+
|
1163 |
except Exception as e:
|
1164 |
return ans + "\n**ERROR**: " + str(e), 0
|
1165 |
|
|
|
1173 |
gen_conf["max_output_tokens"] = gen_conf["max_tokens"]
|
1174 |
ans = ""
|
1175 |
total_tokens = 0
|
1176 |
+
|
1177 |
try:
|
1178 |
response = self.client.do(
|
1179 |
model=self.model_name,
|
|
|
1193 |
return ans + "\n**ERROR**: " + str(e), 0
|
1194 |
|
1195 |
yield total_tokens
|
1196 |
+
|
1197 |
+
|
1198 |
+
class AnthropicChat(Base):
|
1199 |
+
def __init__(self, key, model_name, base_url=None):
|
1200 |
+
import anthropic
|
1201 |
+
|
1202 |
+
self.client = anthropic.Anthropic(api_key=key)
|
1203 |
+
self.model_name = model_name
|
1204 |
+
self.system = ""
|
1205 |
+
|
1206 |
+
def chat(self, system, history, gen_conf):
|
1207 |
+
if system:
|
1208 |
+
self.system = system
|
1209 |
+
if "max_tokens" not in gen_conf:
|
1210 |
+
gen_conf["max_tokens"] = 4096
|
1211 |
+
|
1212 |
+
try:
|
1213 |
+
response = self.client.messages.create(
|
1214 |
+
model=self.model_name,
|
1215 |
+
messages=history,
|
1216 |
+
system=self.system,
|
1217 |
+
stream=False,
|
1218 |
+
**gen_conf,
|
1219 |
+
).json()
|
1220 |
+
ans = response["content"][0]["text"]
|
1221 |
+
if response["stop_reason"] == "max_tokens":
|
1222 |
+
ans += (
|
1223 |
+
"...\nFor the content length reason, it stopped, continue?"
|
1224 |
+
if is_english([ans])
|
1225 |
+
else "路路路路路路\n鐢变簬闀垮害鐨勫師鍥狅紝鍥炵瓟琚埅鏂簡锛岃缁х画鍚楋紵"
|
1226 |
+
)
|
1227 |
+
return (
|
1228 |
+
ans,
|
1229 |
+
response["usage"]["input_tokens"] + response["usage"]["output_tokens"],
|
1230 |
+
)
|
1231 |
+
except Exception as e:
|
1232 |
+
return ans + "\n**ERROR**: " + str(e), 0
|
1233 |
+
|
1234 |
+
def chat_streamly(self, system, history, gen_conf):
|
1235 |
+
if system:
|
1236 |
+
self.system = system
|
1237 |
+
if "max_tokens" not in gen_conf:
|
1238 |
+
gen_conf["max_tokens"] = 4096
|
1239 |
+
|
1240 |
+
ans = ""
|
1241 |
+
total_tokens = 0
|
1242 |
+
try:
|
1243 |
+
response = self.client.messages.create(
|
1244 |
+
model=self.model_name,
|
1245 |
+
messages=history,
|
1246 |
+
system=self.system,
|
1247 |
+
stream=True,
|
1248 |
+
**gen_conf,
|
1249 |
+
)
|
1250 |
+
for res in response.iter_lines():
|
1251 |
+
res = res.decode("utf-8")
|
1252 |
+
if "content_block_delta" in res and "data" in res:
|
1253 |
+
text = json.loads(res[6:])["delta"]["text"]
|
1254 |
+
ans += text
|
1255 |
+
total_tokens += num_tokens_from_string(text)
|
1256 |
+
except Exception as e:
|
1257 |
+
yield ans + "\n**ERROR**: " + str(e)
|
1258 |
+
|
1259 |
+
yield total_tokens
|
requirements.txt
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
arxiv==2.1.3
|
2 |
Aspose.Slides==24.2.0
|
3 |
BCEmbedding==0.1.3
|
|
|
1 |
+
anthropic===0.34.1
|
2 |
arxiv==2.1.3
|
3 |
Aspose.Slides==24.2.0
|
4 |
BCEmbedding==0.1.3
|
requirements_arm.txt
CHANGED
@@ -2,6 +2,7 @@ accelerate==0.27.2
|
|
2 |
aiohttp==3.9.4
|
3 |
aiosignal==1.3.1
|
4 |
annotated-types==0.6.0
|
|
|
5 |
anyio==4.3.0
|
6 |
argon2-cffi==23.1.0
|
7 |
argon2-cffi-bindings==21.2.0
|
|
|
2 |
aiohttp==3.9.4
|
3 |
aiosignal==1.3.1
|
4 |
annotated-types==0.6.0
|
5 |
+
anthropic===0.34.1
|
6 |
anyio==4.3.0
|
7 |
argon2-cffi==23.1.0
|
8 |
argon2-cffi-bindings==21.2.0
|
web/src/assets/svg/llm/anthropic.svg
ADDED
|
web/src/pages/user-setting/setting-model/constant.ts
CHANGED
@@ -37,6 +37,7 @@ export const IconMap = {
|
|
37 |
BaiduYiyan: 'yiyan',
|
38 |
'Fish Audio': 'fish-audio',
|
39 |
'Tencent Cloud': 'tencent-cloud',
|
|
|
40 |
};
|
41 |
|
42 |
export const BedrockRegionList = [
|
|
|
37 |
BaiduYiyan: 'yiyan',
|
38 |
'Fish Audio': 'fish-audio',
|
39 |
'Tencent Cloud': 'tencent-cloud',
|
40 |
+
Anthropic: 'anthropic',
|
41 |
};
|
42 |
|
43 |
export const BedrockRegionList = [
|