feat(chat): 优化工具调用输出处理,确保兼容性和稳定性
- 在 chat_agent 函数中,确保工具调用输出为字符串类型,避免 SQLite 不支持列表类型的问题 - 更新 load_chat_model 函数,新增 stream_usage 参数以支持流式使用 - 移除不必要的代码,简化 utils.py 文件,提升可读性 - 优化 AgentStatsComponent.vue,移除冗余样式,提升性能和用户体验
This commit is contained in:
parent
52ce5f51bd
commit
f28adaaff8
@ -211,10 +211,16 @@ async def chat_agent(
|
|||||||
name = msg_dict.get("name", "")
|
name = msg_dict.get("name", "")
|
||||||
|
|
||||||
if tool_call_id:
|
if tool_call_id:
|
||||||
|
# 确保tool_output是字符串类型,避免SQLite不支持列表类型
|
||||||
|
if isinstance(content, list):
|
||||||
|
tool_output = json.dumps(content) if content else ""
|
||||||
|
else:
|
||||||
|
tool_output = str(content)
|
||||||
|
|
||||||
# 通过 LangGraph tool_call_id 精确匹配并更新
|
# 通过 LangGraph tool_call_id 精确匹配并更新
|
||||||
updated_tc = conv_mgr.update_tool_call_output(
|
updated_tc = conv_mgr.update_tool_call_output(
|
||||||
langgraph_tool_call_id=tool_call_id,
|
langgraph_tool_call_id=tool_call_id,
|
||||||
tool_output=content,
|
tool_output=tool_output,
|
||||||
status="success",
|
status="success",
|
||||||
)
|
)
|
||||||
if updated_tc:
|
if updated_tc:
|
||||||
|
|||||||
@ -26,6 +26,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
|
|||||||
model=model_name,
|
model=model_name,
|
||||||
api_key=SecretStr(api_key),
|
api_key=SecretStr(api_key),
|
||||||
base_url=base_url,
|
base_url=base_url,
|
||||||
|
stream_usage=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
model_info = config.model_names.get(provider, {})
|
model_info = config.model_names.get(provider, {})
|
||||||
@ -40,6 +41,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
|
|||||||
api_key=SecretStr(api_key),
|
api_key=SecretStr(api_key),
|
||||||
base_url=base_url,
|
base_url=base_url,
|
||||||
api_base=base_url,
|
api_base=base_url,
|
||||||
|
stream_usage=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif provider == "together":
|
elif provider == "together":
|
||||||
@ -49,6 +51,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
|
|||||||
model=model,
|
model=model,
|
||||||
api_key=SecretStr(api_key),
|
api_key=SecretStr(api_key),
|
||||||
base_url=base_url,
|
base_url=base_url,
|
||||||
|
stream_usage=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -59,6 +62,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
|
|||||||
model=model,
|
model=model,
|
||||||
api_key=SecretStr(api_key),
|
api_key=SecretStr(api_key),
|
||||||
base_url=base_url,
|
base_url=base_url,
|
||||||
|
stream_usage=True,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError(f"Model provider {provider} load failed, {e} \n {traceback.format_exc()}")
|
raise ValueError(f"Model provider {provider} load failed, {e} \n {traceback.format_exc()}")
|
||||||
|
|||||||
@ -1,71 +1,8 @@
|
|||||||
import os
|
|
||||||
import traceback
|
|
||||||
from datetime import UTC, datetime
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
from langchain_core.language_models import BaseChatModel
|
|
||||||
from langchain_core.messages import AIMessageChunk, ToolMessage
|
from langchain_core.messages import AIMessageChunk, ToolMessage
|
||||||
from langchain_core.runnables import RunnableConfig
|
from langchain_core.runnables import RunnableConfig
|
||||||
from pydantic import SecretStr
|
|
||||||
|
|
||||||
from src import config
|
|
||||||
from src.agents.common.base import BaseAgent
|
from src.agents.common.base import BaseAgent
|
||||||
from src.models import get_custom_model
|
|
||||||
from src.utils import get_docker_safe_url
|
|
||||||
|
|
||||||
|
|
||||||
def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
|
|
||||||
"""
|
|
||||||
Load a chat model from a fully specified name.
|
|
||||||
"""
|
|
||||||
provider, model = fully_specified_name.split("/", maxsplit=1)
|
|
||||||
|
|
||||||
if provider == "custom":
|
|
||||||
from langchain_openai import ChatOpenAI
|
|
||||||
|
|
||||||
model_info = get_custom_model(model)
|
|
||||||
api_key = model_info.get("api_key") or "custom_model"
|
|
||||||
base_url = get_docker_safe_url(model_info["api_base"])
|
|
||||||
model_name = model_info.get("name") or "custom_model"
|
|
||||||
return ChatOpenAI(
|
|
||||||
model=model_name,
|
|
||||||
api_key=SecretStr(api_key),
|
|
||||||
base_url=base_url,
|
|
||||||
)
|
|
||||||
|
|
||||||
model_info = config.model_names.get(provider, {})
|
|
||||||
api_key = os.getenv(model_info["env"][0], model_info["env"][0])
|
|
||||||
base_url = get_docker_safe_url(model_info["base_url"])
|
|
||||||
|
|
||||||
if provider in ["deepseek", "dashscope"]:
|
|
||||||
from langchain_deepseek import ChatDeepSeek
|
|
||||||
|
|
||||||
return ChatDeepSeek(
|
|
||||||
model=model,
|
|
||||||
api_key=SecretStr(api_key),
|
|
||||||
base_url=base_url,
|
|
||||||
api_base=base_url,
|
|
||||||
)
|
|
||||||
|
|
||||||
elif provider == "together":
|
|
||||||
from langchain_together import ChatTogether
|
|
||||||
|
|
||||||
return ChatTogether(
|
|
||||||
model=model,
|
|
||||||
api_key=SecretStr(api_key),
|
|
||||||
base_url=base_url,
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
try: # 其他模型,默认使用OpenAIBase, like openai, zhipuai
|
|
||||||
from langchain_openai import ChatOpenAI
|
|
||||||
|
|
||||||
return ChatOpenAI(
|
|
||||||
model=model,
|
|
||||||
api_key=SecretStr(api_key),
|
|
||||||
base_url=base_url,
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
raise ValueError(f"Model provider {provider} load failed, {e} \n {traceback.format_exc()}")
|
|
||||||
|
|
||||||
|
|
||||||
async def agent_cli(agent: BaseAgent, config: RunnableConfig | None = None):
|
async def agent_cli(agent: BaseAgent, config: RunnableConfig | None = None):
|
||||||
|
|||||||
@ -63,8 +63,6 @@
|
|||||||
:data-source="topPerformers"
|
:data-source="topPerformers"
|
||||||
size="small"
|
size="small"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:row-class-name="getRowClassName"
|
|
||||||
:scroll="{ y: 240 }"
|
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, record, index }">
|
<template #bodyCell="{ column, record, index }">
|
||||||
<template v-if="column.key === 'rank'">
|
<template v-if="column.key === 'rank'">
|
||||||
@ -190,12 +188,6 @@ const getScoreColor = (score) => {
|
|||||||
return '#a3d8e8'
|
return '#a3d8e8'
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRowClassName = (record, index) => {
|
|
||||||
if (index === 0) return 'top-rank first'
|
|
||||||
if (index === 1) return 'top-rank second'
|
|
||||||
if (index === 2) return 'top-rank third'
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化对话数和工具调用数合并图表
|
// 初始化对话数和工具调用数合并图表
|
||||||
const initConversationToolChart = () => {
|
const initConversationToolChart = () => {
|
||||||
@ -396,18 +388,6 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 排名样式优化
|
|
||||||
:deep(.ant-table-tbody > tr.top-rank.first) {
|
|
||||||
background: linear-gradient(90deg, rgba(255, 215, 0, 0.1) 0%, transparent 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-table-tbody > tr.top-rank.second) {
|
|
||||||
background: linear-gradient(90deg, rgba(192, 192, 192, 0.1) 0%, transparent 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-table-tbody > tr.top-rank.third) {
|
|
||||||
background: linear-gradient(90deg, rgba(205, 127, 50, 0.1) 0%, transparent 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-progress-bg) {
|
:deep(.ant-progress-bg) {
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user