Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Pangea-Agent
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Gavin-Group
Pangea-Agent
Commits
9e67a5c4
Commit
9e67a5c4
authored
Dec 08, 2025
by
Gavin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完善ReAct Agent功能:1. 添加enable_react字段到数据库 2. 更新前端界面支持ReAct配置 3. 完善工具调用实现 4. 添加时间工具用于测试
parents
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1276 additions
and
0 deletions
+1276
-0
ReActAgentService.java
...c/main/java/pangea/hiagent/service/ReActAgentService.java
+228
-0
TimeToolService.java
...src/main/java/pangea/hiagent/service/TimeToolService.java
+51
-0
ToolService.java
...end/src/main/java/pangea/hiagent/service/ToolService.java
+260
-0
data.sql
backend/src/main/resources/data.sql
+14
-0
schema.sql
backend/src/main/resources/schema.sql
+198
-0
AgentManagement.vue
frontend/src/pages/AgentManagement.vue
+159
-0
ToolManagement.vue
frontend/src/pages/ToolManagement.vue
+175
-0
init-db.sql
init-db.sql
+191
-0
No files found.
backend/src/main/java/pangea/hiagent/service/ReActAgentService.java
0 → 100644
View file @
9e67a5c4
package
pangea
.
hiagent
.
service
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.ai.chat.messages.AssistantMessage
;
import
org.springframework.ai.chat.messages.Message
;
import
org.springframework.ai.chat.messages.SystemMessage
;
import
org.springframework.ai.chat.messages.UserMessage
;
import
org.springframework.ai.chat.model.ChatModel
;
import
org.springframework.ai.chat.model.ChatResponse
;
import
org.springframework.ai.chat.prompt.Prompt
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
pangea.hiagent.model.Agent
;
import
pangea.hiagent.model.Tool
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.HashMap
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* ReAct Agent服务类
* 负责实现ReAct Agent的核心逻辑
*/
@Slf4j
@Service
public
class
ReActAgentService
{
@Autowired
private
ChatModel
chatModel
;
@Autowired
private
ToolService
toolService
;
@Autowired
private
AgentService
agentService
;
/**
* 处理用户请求的主方法
*
* @param agent Agent对象
* @param userMessage 用户消息
* @return 处理结果
*/
public
String
processRequest
(
Agent
agent
,
String
userMessage
)
{
log
.
info
(
"开始处理ReAct Agent请求,Agent ID: {}, 用户消息: {}"
,
agent
.
getId
(),
userMessage
);
// 初始化对话历史
List
<
Message
>
conversationHistory
=
new
ArrayList
<>();
// 添加系统提示词
String
systemPrompt
=
agent
.
getSystemPrompt
()
!=
null
?
agent
.
getSystemPrompt
()
:
"You are a helpful AI assistant that can use tools to help answer questions. "
+
"Use the following format to think through problems step by step:\n\n"
+
"Thought: Think about what to do.\n"
+
"Action: Call a tool with parameters.\n"
+
"Observation: Observe the result of the tool call.\n\n"
+
"Continue this process until you have enough information to answer the question.\n"
+
"Finally, provide your answer in the format:\n"
+
"Final Answer: [Your answer here]"
;
conversationHistory
.
add
(
new
SystemMessage
(
systemPrompt
));
// 添加用户消息
conversationHistory
.
add
(
new
UserMessage
(
userMessage
));
// 执行ReAct循环
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
// 最多执行5轮
log
.
info
(
"执行ReAct循环第 {} 轮"
,
i
+
1
);
// 构建Prompt
Prompt
prompt
=
new
Prompt
(
conversationHistory
);
// 调用模型
ChatResponse
response
=
chatModel
.
call
(
prompt
);
String
aiResponse
=
response
.
getResult
().
getOutput
().
getText
();
log
.
info
(
"模型响应: {}"
,
aiResponse
);
// 检查是否需要工具调用
if
(
needsToolCall
(
aiResponse
))
{
log
.
info
(
"检测到需要工具调用"
);
// 解析工具调用
ToolCall
toolCall
=
parseToolCall
(
aiResponse
);
if
(
toolCall
!=
null
)
{
log
.
info
(
"解析到工具调用: 工具名称={}, 参数={}"
,
toolCall
.
getToolName
(),
toolCall
.
getParameters
());
// 执行工具调用
String
toolResult
=
toolService
.
executeTool
(
toolCall
.
getToolName
(),
toolCall
.
getParameters
());
log
.
info
(
"工具执行结果: {}"
,
toolResult
);
// 将工具结果添加到对话历史
conversationHistory
.
add
(
new
AssistantMessage
(
aiResponse
));
conversationHistory
.
add
(
new
UserMessage
(
"Observation: "
+
toolResult
));
}
else
{
log
.
warn
(
"工具调用解析失败,结束ReAct循环"
);
break
;
}
}
else
{
log
.
info
(
"无需工具调用,返回最终答案"
);
// 返回最终结果
String
finalAnswer
=
extractFinalAnswer
(
aiResponse
);
log
.
info
(
"最终答案: {}"
,
finalAnswer
);
return
finalAnswer
;
}
}
log
.
warn
(
"达到最大执行轮次限制"
);
return
"达到最大执行轮次限制"
;
}
/**
* 判断是否需要工具调用
*
* @param response 模型响应
* @return 是否需要工具调用
*/
private
boolean
needsToolCall
(
String
response
)
{
return
response
.
contains
(
"Action:"
);
}
/**
* 解析工具调用
*
* @param response 模型响应
* @return 工具调用对象
*/
private
ToolCall
parseToolCall
(
String
response
)
{
// 使用正则表达式解析Action行
// 支持多种格式:Action: tool_name(param1=value1, param2=value2) 或 Action: tool_name()
Pattern
actionPattern
=
Pattern
.
compile
(
"Action:\\s*(\\w+)\\s*\\(([^)]*)\\)"
);
Matcher
matcher
=
actionPattern
.
matcher
(
response
);
if
(
matcher
.
find
())
{
String
toolName
=
matcher
.
group
(
1
);
String
paramsStr
=
matcher
.
group
(
2
);
// 解析参数
Map
<
String
,
Object
>
parameters
=
parseParameters
(
paramsStr
);
return
new
ToolCall
(
toolName
,
parameters
);
}
return
null
;
}
/**
* 解析参数字符串
*
* @param paramsStr 参数字符串
* @return 参数Map
*/
private
Map
<
String
,
Object
>
parseParameters
(
String
paramsStr
)
{
Map
<
String
,
Object
>
parameters
=
new
HashMap
<>();
// 如果参数字符串为空,直接返回空Map
if
(
paramsStr
==
null
||
paramsStr
.
trim
().
isEmpty
())
{
return
parameters
;
}
// 解析参数,支持带引号和不带引号的值
// 格式: key1=value1, key2="value with spaces", key3='another value'
String
[]
paramPairs
=
paramsStr
.
split
(
","
);
// 简化处理,按逗号分割
for
(
String
paramPair
:
paramPairs
)
{
String
[]
parts
=
paramPair
.
split
(
"="
);
if
(
parts
.
length
==
2
)
{
String
key
=
parts
[
0
].
trim
();
String
value
=
parts
[
1
].
trim
();
// 移除引号(如果存在)
if
((
value
.
startsWith
(
"\""
)
&&
value
.
endsWith
(
"\""
))
||
(
value
.
startsWith
(
"'"
)
&&
value
.
endsWith
(
"'"
)))
{
value
=
value
.
substring
(
1
,
value
.
length
()
-
1
);
}
parameters
.
put
(
key
,
value
);
}
}
return
parameters
;
}
/**
* 提取最终答案
*
* @param response 模型响应
* @return 最终答案
*/
private
String
extractFinalAnswer
(
String
response
)
{
// 查找Final Answer:后面的文本
Pattern
answerPattern
=
Pattern
.
compile
(
"Final Answer:\\s*(.*)"
,
Pattern
.
DOTALL
);
Matcher
matcher
=
answerPattern
.
matcher
(
response
);
if
(
matcher
.
find
())
{
return
matcher
.
group
(
1
).
trim
();
}
// 如果没有找到Final Answer格式,返回整个响应
return
response
;
}
/**
* 工具调用内部类
*/
private
static
class
ToolCall
{
private
final
String
toolName
;
private
final
Map
<
String
,
Object
>
parameters
;
public
ToolCall
(
String
toolName
,
Map
<
String
,
Object
>
parameters
)
{
this
.
toolName
=
toolName
;
this
.
parameters
=
parameters
;
}
public
String
getToolName
()
{
return
toolName
;
}
public
Map
<
String
,
Object
>
getParameters
()
{
return
parameters
;
}
}
}
\ No newline at end of file
backend/src/main/java/pangea/hiagent/service/TimeToolService.java
0 → 100644
View file @
9e67a5c4
package
pangea
.
hiagent
.
service
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
pangea.hiagent.model.Tool
;
import
java.time.LocalDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.util.Map
;
/**
* 时间工具服务类
* 提供获取当前时间的功能
*/
@Slf4j
@Service
public
class
TimeToolService
{
/**
* 执行时间工具调用
*
* @param tool 工具信息
* @param parameters 工具参数
* @return 当前时间的字符串表示
*/
public
String
executeTimeTool
(
Tool
tool
,
Map
<
String
,
Object
>
parameters
)
{
log
.
info
(
"执行时间工具调用: {}"
,
tool
.
getName
());
try
{
// 获取当前时间
LocalDateTime
now
=
LocalDateTime
.
now
();
// 格式化时间
DateTimeFormatter
formatter
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
);
String
formattedTime
=
now
.
format
(
formatter
);
// 构造返回结果
return
"{\n"
+
" \"currentTime\": \""
+
formattedTime
+
"\",\n"
+
" \"timestamp\": "
+
System
.
currentTimeMillis
()
+
"\n"
+
"}"
;
}
catch
(
Exception
e
)
{
log
.
error
(
"时间工具调用失败: {}"
,
tool
.
getName
(),
e
);
return
"{\n"
+
" \"error\": \"时间工具调用失败\",\n"
+
" \"message\": \""
+
e
.
getMessage
()
+
"\"\n"
+
"}"
;
}
}
}
\ No newline at end of file
backend/src/main/java/pangea/hiagent/service/ToolService.java
0 → 100644
View file @
9e67a5c4
package
pangea
.
hiagent
.
service
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.http.HttpEntity
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.HttpStatus
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
pangea.hiagent.model.Tool
;
import
pangea.hiagent.repository.ToolRepository
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.HashMap
;
import
java.net.URI
;
/**
* Tool服务类
* 负责工具的注册、管理和调用
*/
@Slf4j
@Service
public
class
ToolService
{
private
final
ToolRepository
toolRepository
;
private
final
RestTemplate
restTemplate
;
private
final
ObjectMapper
objectMapper
;
private
final
TimeToolService
timeToolService
;
public
ToolService
(
ToolRepository
toolRepository
,
TimeToolService
timeToolService
)
{
this
.
toolRepository
=
toolRepository
;
this
.
restTemplate
=
new
RestTemplate
();
this
.
objectMapper
=
new
ObjectMapper
();
this
.
timeToolService
=
timeToolService
;
}
/**
* 注册工具
*/
@Transactional
public
Tool
registerTool
(
Tool
tool
)
{
log
.
info
(
"注册工具: {}"
,
tool
.
getName
());
toolRepository
.
insert
(
tool
);
return
tool
;
}
/**
* 更新工具
*/
@Transactional
public
Tool
updateTool
(
Tool
tool
)
{
log
.
info
(
"更新工具: {}"
,
tool
.
getId
());
toolRepository
.
updateById
(
tool
);
return
tool
;
}
/**
* 删除工具
*/
@Transactional
public
void
deleteTool
(
String
id
)
{
log
.
info
(
"删除工具: {}"
,
id
);
toolRepository
.
deleteById
(
id
);
}
/**
* 获取工具详情
*/
public
Tool
getTool
(
String
id
)
{
return
toolRepository
.
selectById
(
id
);
}
/**
* 获取工具列表
*/
public
List
<
Tool
>
listTools
()
{
log
.
debug
(
"开始获取工具列表"
);
try
{
LambdaQueryWrapper
<
Tool
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
Tool:
:
getStatus
,
"active"
);
List
<
Tool
>
tools
=
toolRepository
.
selectList
(
wrapper
);
log
.
debug
(
"成功获取工具列表,共 {} 条记录"
,
tools
.
size
());
return
tools
;
}
catch
(
Exception
e
)
{
log
.
error
(
"获取工具列表时发生异常"
,
e
);
throw
e
;
}
}
/**
* 分页获取工具列表
*/
public
IPage
<
Tool
>
pageTools
(
Long
current
,
Long
size
,
String
name
,
String
category
)
{
Page
<
Tool
>
page
=
new
Page
<>(
current
,
size
);
LambdaQueryWrapper
<
Tool
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
Tool:
:
getStatus
,
"active"
);
if
(
name
!=
null
)
{
wrapper
.
like
(
Tool:
:
getName
,
name
);
}
if
(
category
!=
null
)
{
wrapper
.
eq
(
Tool:
:
getCategory
,
category
);
}
return
toolRepository
.
selectPage
(
page
,
wrapper
);
}
/**
* 按分类获取工具列表
*/
public
List
<
Tool
>
getToolsByCategory
(
String
category
)
{
LambdaQueryWrapper
<
Tool
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
Tool:
:
getCategory
,
category
);
wrapper
.
eq
(
Tool:
:
getStatus
,
"active"
);
return
toolRepository
.
selectList
(
wrapper
);
}
/**
* 执行工具调用
*
* @param toolName 工具名称
* @param parameters 工具参数
* @return 工具执行结果
*/
public
String
executeTool
(
String
toolName
,
Map
<
String
,
Object
>
parameters
)
{
log
.
info
(
"执行工具调用: {}, 参数: {}"
,
toolName
,
parameters
);
// 根据工具名称获取工具信息
LambdaQueryWrapper
<
Tool
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
Tool:
:
getName
,
toolName
);
wrapper
.
eq
(
Tool:
:
getStatus
,
"active"
);
Tool
tool
=
toolRepository
.
selectOne
(
wrapper
);
if
(
tool
==
null
)
{
log
.
warn
(
"工具未找到或未激活: {}"
,
toolName
);
return
"工具未找到或未激活: "
+
toolName
;
}
// 根据工具类型执行不同的调用逻辑
// 这里根据工具的具体类型来执行不同的逻辑
switch
(
tool
.
getCategory
())
{
case
"API"
:
return
executeApiTool
(
tool
,
parameters
);
case
"FUNCTION"
:
// 检查是否为特殊的时间工具
if
(
"get_current_time"
.
equals
(
tool
.
getName
()))
{
return
timeToolService
.
executeTimeTool
(
tool
,
parameters
);
}
return
executeFunctionTool
(
tool
,
parameters
);
default
:
return
executeDefaultTool
(
tool
,
parameters
);
}
}
/**
* 执行API工具调用
*/
private
String
executeApiTool
(
Tool
tool
,
Map
<
String
,
Object
>
parameters
)
{
log
.
info
(
"执行API工具调用: {}"
,
tool
.
getName
());
try
{
// 构建请求URL
String
apiUrl
=
tool
.
getApiEndpoint
();
if
(
apiUrl
==
null
||
apiUrl
.
isEmpty
())
{
return
"工具配置错误:API端点未设置"
;
}
// 解析HTTP方法
HttpMethod
httpMethod
=
HttpMethod
.
GET
;
if
(
tool
.
getHttpMethod
()
!=
null
)
{
try
{
httpMethod
=
HttpMethod
.
valueOf
(
tool
.
getHttpMethod
().
toUpperCase
());
}
catch
(
IllegalArgumentException
e
)
{
log
.
warn
(
"无效的HTTP方法: {}, 使用GET作为默认方法"
,
tool
.
getHttpMethod
());
}
}
// 构建请求头
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
set
(
"Content-Type"
,
"application/json"
);
headers
.
set
(
"User-Agent"
,
"HiAgent/1.0"
);
// 构建请求体
HttpEntity
<
Map
<
String
,
Object
>>
requestEntity
=
new
HttpEntity
<>(
parameters
,
headers
);
// 发送HTTP请求
ResponseEntity
<
String
>
response
=
restTemplate
.
exchange
(
apiUrl
,
httpMethod
,
requestEntity
,
String
.
class
);
// 检查响应状态
if
(
response
.
getStatusCode
()
==
HttpStatus
.
OK
)
{
return
response
.
getBody
();
}
else
{
return
"API调用失败,状态码: "
+
response
.
getStatusCode
();
}
}
catch
(
Exception
e
)
{
log
.
error
(
"API工具调用失败: {}"
,
tool
.
getName
(),
e
);
return
"API工具调用失败: "
+
e
.
getMessage
();
}
}
/**
* 执行函数工具调用
*/
private
String
executeFunctionTool
(
Tool
tool
,
Map
<
String
,
Object
>
parameters
)
{
log
.
info
(
"执行函数工具调用: {}"
,
tool
.
getName
());
// 这里应该实现实际的函数调用逻辑
// 例如通过反射调用指定的Java方法
// 目前返回模拟结果
Map
<
String
,
Object
>
result
=
new
HashMap
<>();
result
.
put
(
"tool"
,
tool
.
getName
());
result
.
put
(
"status"
,
"success"
);
result
.
put
(
"message"
,
"函数工具调用成功"
);
result
.
put
(
"parameters"
,
parameters
);
result
.
put
(
"result"
,
"这是函数执行的结果"
);
try
{
return
objectMapper
.
writeValueAsString
(
result
);
}
catch
(
Exception
e
)
{
log
.
error
(
"序列化函数调用结果失败"
,
e
);
return
result
.
toString
();
}
}
/**
* 执行默认工具调用
*/
private
String
executeDefaultTool
(
Tool
tool
,
Map
<
String
,
Object
>
parameters
)
{
log
.
info
(
"执行默认工具调用: {}"
,
tool
.
getName
());
// 默认的工具执行逻辑
Map
<
String
,
Object
>
result
=
new
HashMap
<>();
result
.
put
(
"tool"
,
tool
.
getName
());
result
.
put
(
"status"
,
"success"
);
result
.
put
(
"message"
,
"默认工具调用成功"
);
result
.
put
(
"parameters"
,
parameters
);
result
.
put
(
"result"
,
"这是默认工具执行的结果"
);
try
{
return
objectMapper
.
writeValueAsString
(
result
);
}
catch
(
Exception
e
)
{
log
.
error
(
"序列化默认工具调用结果失败"
,
e
);
return
result
.
toString
();
}
}
}
\ No newline at end of file
backend/src/main/resources/data.sql
0 → 100644
View file @
9e67a5c4
-- 插入默认数据
INSERT
INTO
sys_user
(
id
,
username
,
password
,
email
,
nickname
,
status
,
role
)
VALUES
(
'default-user-id'
,
'admin'
,
'$2a$10$N.zmdr9k7uOCQb0bta/OauRxaOKSr.QhqyD2R5FKvMQjmHoLkm5Sy'
,
'admin@hiagent.com'
,
'Admin'
,
'active'
,
'admin'
);
INSERT
INTO
agent
(
id
,
name
,
description
,
status
,
default_model
,
owner
)
VALUES
(
'default-agent-1'
,
'客服助手'
,
'处理客户咨询的AI助手'
,
'active'
,
'deepseek-chat'
,
'default-user-id'
),
(
'default-agent-2'
,
'技术支持'
,
'提供技术支持服务的AI助手'
,
'active'
,
'gpt-3.5-turbo'
,
'default-user-id'
);
INSERT
INTO
tool
(
id
,
name
,
display_name
,
description
,
category
,
status
,
timeout
,
http_method
)
VALUES
(
'default-tool-1'
,
'search'
,
'搜索工具'
,
'进行网络搜索查询'
,
'API'
,
'active'
,
30000
,
'GET'
),
(
'default-tool-2'
,
'calculator'
,
'计算器'
,
'进行数学计算'
,
'FUNCTION'
,
'active'
,
5000
,
'POST'
),
(
'default-tool-3'
,
'weather'
,
'天气查询'
,
'查询天气信息'
,
'API'
,
'active'
,
10000
,
'GET'
),
(
'default-tool-4'
,
'get_current_time'
,
'获取当前时间'
,
'获取当前系统时间'
,
'FUNCTION'
,
'active'
,
1000
,
'GET'
);
\ No newline at end of file
backend/src/main/resources/schema.sql
0 → 100644
View file @
9e67a5c4
-- HiAgent数据库表结构初始化脚本
-- 用户表
CREATE
TABLE
IF
NOT
EXISTS
sys_user
(
id
varchar
(
36
)
NOT
NULL
,
username
varchar
(
50
)
NOT
NULL
UNIQUE
,
password
varchar
(
255
)
NOT
NULL
,
email
varchar
(
100
),
nickname
varchar
(
100
),
status
varchar
(
20
)
DEFAULT
'active'
,
role
varchar
(
50
)
DEFAULT
'user'
,
avatar
varchar
(
255
),
last_login_time
bigint
,
api_key
varchar
(
255
),
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
CREATE
INDEX
IF
NOT
EXISTS
idx_username
ON
sys_user
(
username
);
-- Agent表
CREATE
TABLE
IF
NOT
EXISTS
agent
(
id
varchar
(
36
)
NOT
NULL
,
name
varchar
(
100
)
NOT
NULL
,
description
text
,
status
varchar
(
20
)
DEFAULT
'active'
,
default_model
varchar
(
50
),
system_prompt
text
,
prompt_template
text
,
temperature
decimal
(
3
,
2
)
DEFAULT
0
.
7
,
max_tokens
int
DEFAULT
4096
,
top_p
decimal
(
3
,
2
)
DEFAULT
0
.
9
,
top_k
int
DEFAULT
50
,
presence_penalty
decimal
(
3
,
2
)
DEFAULT
0
,
frequency_penalty
decimal
(
3
,
2
)
DEFAULT
0
,
history_length
int
DEFAULT
10
,
tools
json
,
rag_collection_id
varchar
(
36
),
enable_rag
tinyint
DEFAULT
0
,
enable_react
tinyint
DEFAULT
0
,
owner
varchar
(
36
),
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
CREATE
INDEX
IF
NOT
EXISTS
idx_owner
ON
agent
(
owner
);
-- 工具表
CREATE
TABLE
IF
NOT
EXISTS
tool
(
id
varchar
(
36
)
NOT
NULL
,
name
varchar
(
100
)
NOT
NULL
,
display_name
varchar
(
100
),
description
text
,
category
varchar
(
50
),
status
varchar
(
20
)
DEFAULT
'active'
,
parameters
json
,
return_type
varchar
(
50
),
return_schema
json
,
implementation
text
,
timeout
bigint
,
api_endpoint
varchar
(
255
),
http_method
varchar
(
20
),
owner
varchar
(
36
),
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
-- 文档表
CREATE
TABLE
IF
NOT
EXISTS
document
(
id
varchar
(
36
)
NOT
NULL
,
name
varchar
(
255
)
NOT
NULL
,
type
varchar
(
20
),
size
bigint
,
status
varchar
(
20
)
DEFAULT
'uploading'
,
chunks
int
DEFAULT
0
,
collection_id
varchar
(
36
),
file_path
varchar
(
255
),
author
varchar
(
100
),
source
varchar
(
100
),
tags
json
,
metadata
json
,
embedding_model
varchar
(
100
),
error_message
text
,
owner
varchar
(
36
),
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
-- 文档片段表
CREATE
TABLE
IF
NOT
EXISTS
document_chunk
(
id
varchar
(
36
)
NOT
NULL
,
document_id
varchar
(
36
)
NOT
NULL
,
content
longtext
,
page_number
int
,
score
decimal
(
3
,
2
),
sequence
int
,
vector_id
bigint
,
metadata
json
,
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
CREATE
INDEX
IF
NOT
EXISTS
idx_document_id
ON
document_chunk
(
document_id
);
-- Agent对话表
CREATE
TABLE
IF
NOT
EXISTS
agent_dialogue
(
id
varchar
(
36
)
NOT
NULL
,
agent_id
varchar
(
36
)
NOT
NULL
,
context_id
varchar
(
36
),
user_message
longtext
,
agent_response
longtext
,
prompt_tokens
int
,
completion_tokens
int
,
total_tokens
int
,
processing_time
bigint
,
finish_reason
varchar
(
50
),
tool_calls
json
,
user_id
varchar
(
36
),
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
CREATE
INDEX
IF
NOT
EXISTS
idx_agent_id
ON
agent_dialogue
(
agent_id
);
CREATE
INDEX
IF
NOT
EXISTS
idx_user_id
ON
agent_dialogue
(
user_id
);
-- 系统日志表
CREATE
TABLE
IF
NOT
EXISTS
sys_log
(
id
varchar
(
36
)
NOT
NULL
,
operation_type
varchar
(
50
),
resource_type
varchar
(
50
),
resource_id
varchar
(
36
),
user_id
varchar
(
36
),
description
text
,
request_params
json
,
response_result
json
,
success
tinyint
DEFAULT
1
,
error_message
text
,
ip_address
varchar
(
50
),
execution_time
bigint
,
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
-- LLM配置表
CREATE
TABLE
IF
NOT
EXISTS
llm_config
(
id
varchar
(
36
)
NOT
NULL
,
name
varchar
(
100
)
NOT
NULL
UNIQUE
,
description
text
,
provider
varchar
(
50
),
model_name
varchar
(
100
),
api_key
varchar
(
255
),
base_url
varchar
(
255
),
temperature
decimal
(
3
,
2
)
DEFAULT
0
.
7
,
max_tokens
int
DEFAULT
4096
,
top_p
decimal
(
3
,
2
)
DEFAULT
0
.
9
,
enabled
tinyint
DEFAULT
1
,
owner
varchar
(
36
),
created_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
updated_at
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
created_by
varchar
(
36
),
updated_by
varchar
(
36
),
deleted
int
DEFAULT
0
,
remark
text
,
PRIMARY
KEY
(
id
)
);
CREATE
INDEX
IF
NOT
EXISTS
idx_user_id
ON
sys_log
(
user_id
);
CREATE
INDEX
IF
NOT
EXISTS
idx_created_at
ON
sys_log
(
created_at
);
\ No newline at end of file
frontend/src/pages/AgentManagement.vue
0 → 100644
View file @
9e67a5c4
<
template
>
<div
class=
"management-page"
>
<h2>
Agent管理
</h2>
<el-button
type=
"primary"
@
click=
"dialogVisible = true"
style=
"margin-bottom: 20px"
>
创建Agent
</el-button>
<el-table
:data=
"agents"
stripe
style=
"width: 100%"
>
<el-table-column
prop=
"name"
label=
"名称"
/>
<el-table-column
prop=
"description"
label=
"描述"
/>
<el-table-column
prop=
"defaultModel"
label=
"默认模型"
/>
<el-table-column
prop=
"status"
label=
"状态"
>
<template
#
default=
"
{ row }">
<el-tag
:type=
"row.status === 'active' ? 'success' : 'warning'"
>
{{
row
.
status
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
>
<
template
#
default=
"{ row }"
>
<el-button
link
type=
"primary"
@
click=
"editAgent(row)"
>
编辑
</el-button>
<el-button
link
type=
"danger"
@
click=
"deleteAgent(row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<el-dialog
v-model=
"dialogVisible"
:title=
"isEdit ? '编辑Agent' : '创建Agent'"
>
<el-form
:model=
"form"
>
<el-form-item
label=
"名称"
>
<el-input
v-model=
"form.name"
/>
</el-form-item>
<el-form-item
label=
"描述"
>
<el-input
v-model=
"form.description"
type=
"textarea"
/>
</el-form-item>
<el-form-item
label=
"默认模型"
>
<el-select
v-model=
"form.defaultModel"
placeholder=
"请选择默认模型"
>
<el-option
label=
"DeepSeek-Chat"
value=
"deepseek-chat"
/>
<el-option
label=
"GPT-3.5 Turbo"
value=
"gpt-3.5-turbo"
/>
<el-option
label=
"Llama2"
value=
"llama2"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"状态"
>
<el-select
v-model=
"form.status"
>
<el-option
label=
"活跃"
value=
"active"
/>
<el-option
label=
"非活跃"
value=
"inactive"
/>
<el-option
label=
"草稿"
value=
"draft"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"启用ReAct模式"
>
<el-switch
v-model=
"form.enableReAct"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"saveAgent"
>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
script
setup
>
import
{
ref
,
onMounted
}
from
'vue'
import
{
useAuthStore
}
from
'@/stores/auth'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
request
from
'@/utils/request'
import
{
handleGlobalError
,
withErrorHandling
}
from
'@/utils/errorHandler'
const
authStore
=
useAuthStore
()
const
agents
=
ref
([])
const
dialogVisible
=
ref
(
false
)
const
isEdit
=
ref
(
false
)
const
form
=
ref
({
name
:
''
,
description
:
''
,
defaultModel
:
'deepseek-chat'
,
status
:
'active'
,
enableReAct
:
false
})
onMounted
(()
=>
{
loadAgents
()
})
const
loadAgents
=
async
()
=>
{
try
{
const
res
=
await
authStore
.
get
(
'/agent'
)
agents
.
value
=
res
.
data
.
data
||
[]
}
catch
(
error
)
{
console
.
error
(
'获取Agent列表失败:'
,
error
)
console
.
error
(
'错误详情:'
,
{
message
:
error
.
message
,
response
:
error
.
response
,
status
:
error
.
response
?.
status
,
statusText
:
error
.
response
?.
statusText
,
data
:
error
.
response
?.
data
})
ElMessage
.
error
(
'获取Agent列表失败: '
+
(
error
.
response
?.
data
?.
message
||
error
.
message
||
'未知错误'
))
}
}
const
editAgent
=
(
agent
)
=>
{
isEdit
.
value
=
true
form
.
value
=
{
...
agent
}
dialogVisible
.
value
=
true
}
const
saveAgent
=
async
()
=>
{
try
{
if
(
isEdit
.
value
)
{
// 使用更安全的方式调用 PUT 请求
await
authStore
.
put
(
`/agent/
${
form
.
value
.
id
}
`
,
form
.
value
)
ElMessage
.
success
(
'更新成功'
)
}
else
{
// 使用更安全的方式调用 POST 请求
await
authStore
.
post
(
'/agent'
,
form
.
value
)
ElMessage
.
success
(
'创建成功'
)
}
dialogVisible
.
value
=
false
loadAgents
()
}
catch
(
error
)
{
console
.
error
(
'保存Agent失败:'
,
error
)
let
errorMessage
=
'操作失败'
if
(
error
.
response
&&
error
.
response
.
data
&&
error
.
response
.
data
.
message
)
{
errorMessage
+=
`:
${
error
.
response
.
data
.
message
}
`
}
ElMessage
.
error
(
errorMessage
)
}
}
const
deleteAgent
=
(
agent
)
=>
{
ElMessageBox
.
confirm
(
'确认删除该Agent吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(
async
()
=>
{
try
{
// 使用更安全的方式调用 DELETE 请求
await
authStore
.
del
(
`/agent/
${
agent
.
id
}
`
)
ElMessage
.
success
(
'删除成功'
)
loadAgents
()
}
catch
(
error
)
{
console
.
error
(
'删除Agent失败:'
,
error
)
let
errorMessage
=
'删除失败'
if
(
error
.
response
&&
error
.
response
.
data
&&
error
.
response
.
data
.
message
)
{
errorMessage
+=
`:
${
error
.
response
.
data
.
message
}
`
}
ElMessage
.
error
(
errorMessage
)
}
}).
catch
(()
=>
{})
}
</
script
>
<
style
scoped
>
.management-page
{
padding
:
20px
;
}
</
style
>
\ No newline at end of file
frontend/src/pages/ToolManagement.vue
0 → 100644
View file @
9e67a5c4
<
template
>
<div
class=
"management-page"
>
<h2>
工具管理
</h2>
<el-button
type=
"primary"
@
click=
"openDialog()"
style=
"margin-bottom: 20px"
>
注册工具
</el-button>
<el-table
:data=
"tools"
stripe
style=
"width: 100%"
>
<el-table-column
prop=
"name"
label=
"工具名称"
/>
<el-table-column
prop=
"displayName"
label=
"显示名称"
/>
<el-table-column
prop=
"description"
label=
"描述"
/>
<el-table-column
prop=
"category"
label=
"分类"
/>
<el-table-column
prop=
"status"
label=
"状态"
>
<template
#
default=
"
{ row }">
<el-tag
:type=
"row.status === 'active' ? 'success' : 'warning'"
>
{{
row
.
status
===
'active'
?
'活跃'
:
'非活跃'
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
>
<
template
#
default=
"{ row }"
>
<el-button
link
type=
"primary"
@
click=
"openDialog(row)"
>
编辑
</el-button>
<el-button
link
type=
"danger"
@
click=
"handleDelete(row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<el-dialog
v-model=
"dialogVisible"
:title=
"isEdit ? '编辑工具' : '注册工具'"
width=
"600px"
>
<el-form
:model=
"form"
label-width=
"120px"
>
<el-form-item
label=
"工具名称"
>
<el-input
v-model=
"form.name"
placeholder=
"请输入工具名称"
/>
</el-form-item>
<el-form-item
label=
"显示名称"
>
<el-input
v-model=
"form.displayName"
placeholder=
"请输入显示名称"
/>
</el-form-item>
<el-form-item
label=
"描述"
>
<el-input
v-model=
"form.description"
type=
"textarea"
placeholder=
"请输入工具描述"
/>
</el-form-item>
<el-form-item
label=
"分类"
>
<el-select
v-model=
"form.category"
placeholder=
"请选择分类"
>
<el-option
label=
"API"
value=
"API"
/>
<el-option
label=
"函数"
value=
"FUNCTION"
/>
<el-option
label=
"默认"
value=
"DEFAULT"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"状态"
>
<el-select
v-model=
"form.status"
placeholder=
"请选择状态"
>
<el-option
label=
"活跃"
value=
"active"
/>
<el-option
label=
"非活跃"
value=
"inactive"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"API端点"
>
<el-input
v-model=
"form.apiEndpoint"
placeholder=
"请输入API端点URL"
/>
</el-form-item>
<el-form-item
label=
"请求方式"
>
<el-select
v-model=
"form.httpMethod"
placeholder=
"请选择请求方式"
>
<el-option
label=
"GET"
value=
"GET"
/>
<el-option
label=
"POST"
value=
"POST"
/>
<el-option
label=
"PUT"
value=
"PUT"
/>
<el-option
label=
"DELETE"
value=
"DELETE"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"超时时间(毫秒)"
>
<el-input-number
v-model=
"form.timeout"
:min=
"1000"
:max=
"60000"
placeholder=
"请输入超时时间"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"saveTool"
>
保存
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
script
setup
>
import
{
ref
,
onMounted
}
from
'vue'
import
{
useAuthStore
}
from
'@/stores/auth'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
const
authStore
=
useAuthStore
()
const
tools
=
ref
([])
const
dialogVisible
=
ref
(
false
)
const
isEdit
=
ref
(
false
)
const
form
=
ref
({
name
:
''
,
displayName
:
''
,
description
:
''
,
category
:
'API'
,
status
:
'active'
,
apiEndpoint
:
''
,
httpMethod
:
'GET'
,
timeout
:
10000
})
const
toolId
=
ref
(
''
)
onMounted
(
async
()
=>
{
await
loadTools
()
})
const
loadTools
=
async
()
=>
{
try
{
const
res
=
await
authStore
.
get
(
'/tools'
)
tools
.
value
=
res
.
data
.
data
||
[]
}
catch
(
error
)
{
console
.
error
(
'获取工具列表失败:'
,
error
)
ElMessage
.
error
(
'获取工具列表失败: '
+
(
error
.
response
?.
data
?.
message
||
error
.
message
||
'未知错误'
))
}
}
const
openDialog
=
(
tool
)
=>
{
if
(
tool
)
{
isEdit
.
value
=
true
toolId
.
value
=
tool
.
id
form
.
value
=
{
...
tool
}
}
else
{
isEdit
.
value
=
false
toolId
.
value
=
''
form
.
value
=
{
name
:
''
,
displayName
:
''
,
description
:
''
,
category
:
'API'
,
status
:
'active'
,
apiEndpoint
:
''
,
httpMethod
:
'GET'
,
timeout
:
10000
}
}
dialogVisible
.
value
=
true
}
const
saveTool
=
async
()
=>
{
try
{
if
(
isEdit
.
value
)
{
await
authStore
.
put
(
`/tools/
${
toolId
.
value
}
`
,
form
.
value
)
ElMessage
.
success
(
'工具更新成功'
)
}
else
{
await
authStore
.
post
(
'/tools'
,
form
.
value
)
ElMessage
.
success
(
'工具注册成功'
)
}
dialogVisible
.
value
=
false
await
loadTools
()
}
catch
(
error
)
{
console
.
error
(
'保存工具失败:'
,
error
)
ElMessage
.
error
(
'保存工具失败: '
+
(
error
.
response
?.
data
?.
message
||
error
.
message
||
'未知错误'
))
}
}
const
handleDelete
=
(
tool
)
=>
{
ElMessageBox
.
confirm
(
`确认删除工具 "
${
tool
.
name
}
" 吗?`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(
async
()
=>
{
try
{
await
authStore
.
del
(
`/tools/
${
tool
.
id
}
`
)
ElMessage
.
success
(
'工具删除成功'
)
await
loadTools
()
}
catch
(
error
)
{
console
.
error
(
'删除工具失败:'
,
error
)
ElMessage
.
error
(
'删除工具失败: '
+
(
error
.
response
?.
data
?.
message
||
error
.
message
||
'未知错误'
))
}
}).
catch
(()
=>
{
ElMessage
.
info
(
'已取消删除'
)
})
}
</
script
>
<
style
scoped
>
.management-page
{
padding
:
20px
;
}
</
style
>
\ No newline at end of file
init-db.sql
0 → 100644
View file @
9e67a5c4
-- HiAgent数据库初始化脚本
USE
hiagent
;
-- 用户表
CREATE
TABLE
IF
NOT
EXISTS
`sys_user`
(
`id`
varchar
(
36
)
NOT
NULL
,
`username`
varchar
(
50
)
NOT
NULL
UNIQUE
,
`password`
varchar
(
255
)
NOT
NULL
,
`email`
varchar
(
100
),
`nickname`
varchar
(
100
),
`status`
varchar
(
20
)
DEFAULT
'active'
,
`role`
varchar
(
50
)
DEFAULT
'user'
,
`avatar`
varchar
(
255
),
`last_login_time`
bigint
,
`api_key`
varchar
(
255
),
`created_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
`updated_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
`created_by`
varchar
(
36
),
`updated_by`
varchar
(
36
),
`deleted`
int
DEFAULT
0
,
`remark`
text
,
PRIMARY
KEY
(
`id`
),
KEY
`idx_username`
(
`username`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
;
-- Agent表
CREATE
TABLE
IF
NOT
EXISTS
`agent`
(
`id`
varchar
(
36
)
NOT
NULL
,
`name`
varchar
(
100
)
NOT
NULL
,
`description`
text
,
`status`
varchar
(
20
)
DEFAULT
'active'
,
`default_model`
varchar
(
50
),
`system_prompt`
text
,
`prompt_template`
text
,
`temperature`
decimal
(
3
,
2
)
DEFAULT
0
.
7
,
`max_tokens`
int
DEFAULT
4096
,
`top_p`
decimal
(
3
,
2
)
DEFAULT
0
.
9
,
`top_k`
int
DEFAULT
50
,
`presence_penalty`
decimal
(
3
,
2
)
DEFAULT
0
,
`frequency_penalty`
decimal
(
3
,
2
)
DEFAULT
0
,
`history_length`
int
DEFAULT
10
,
`tools`
json
,
`rag_collection_id`
varchar
(
36
),
`enable_rag`
tinyint
DEFAULT
0
,
`enable_react`
tinyint
DEFAULT
0
,
`owner`
varchar
(
36
),
`created_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
`updated_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
`created_by`
varchar
(
36
),
`updated_by`
varchar
(
36
),
`deleted`
int
DEFAULT
0
,
`remark`
text
,
PRIMARY
KEY
(
`id`
),
KEY
`idx_owner`
(
`owner`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
;
-- 工具表
CREATE
TABLE
IF
NOT
EXISTS
`tool`
(
`id`
varchar
(
36
)
NOT
NULL
,
`name`
varchar
(
100
)
NOT
NULL
,
`display_name`
varchar
(
100
),
`description`
text
,
`category`
varchar
(
50
),
`status`
varchar
(
20
)
DEFAULT
'active'
,
`parameters`
json
,
`return_type`
varchar
(
50
),
`return_schema`
json
,
`implementation`
text
,
`timeout`
bigint
,
`api_endpoint`
varchar
(
255
),
`http_method`
varchar
(
20
),
`owner`
varchar
(
36
),
`created_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
`updated_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
`created_by`
varchar
(
36
),
`updated_by`
varchar
(
36
),
`deleted`
int
DEFAULT
0
,
`remark`
text
,
PRIMARY
KEY
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
;
-- 文档表
CREATE
TABLE
IF
NOT
EXISTS
`document`
(
`id`
varchar
(
36
)
NOT
NULL
,
`name`
varchar
(
255
)
NOT
NULL
,
`type`
varchar
(
20
),
`size`
bigint
,
`status`
varchar
(
20
)
DEFAULT
'uploading'
,
`chunks`
int
DEFAULT
0
,
`collection_id`
varchar
(
36
),
`file_path`
varchar
(
255
),
`author`
varchar
(
100
),
`source`
varchar
(
100
),
`tags`
json
,
`metadata`
json
,
`embedding_model`
varchar
(
100
),
`error_message`
text
,
`owner`
varchar
(
36
),
`created_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
`updated_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
`created_by`
varchar
(
36
),
`updated_by`
varchar
(
36
),
`deleted`
int
DEFAULT
0
,
`remark`
text
,
PRIMARY
KEY
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
;
-- 文档片段表
CREATE
TABLE
IF
NOT
EXISTS
`document_chunk`
(
`id`
varchar
(
36
)
NOT
NULL
,
`document_id`
varchar
(
36
)
NOT
NULL
,
`content`
longtext
,
`page_number`
int
,
`score`
decimal
(
3
,
2
),
`sequence`
int
,
`vector_id`
bigint
,
`metadata`
json
,
`created_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
`updated_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
`created_by`
varchar
(
36
),
`updated_by`
varchar
(
36
),
`deleted`
int
DEFAULT
0
,
`remark`
text
,
PRIMARY
KEY
(
`id`
),
KEY
`idx_document_id`
(
`document_id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
;
-- Agent对话表
CREATE
TABLE
IF
NOT
EXISTS
`agent_dialogue`
(
`id`
varchar
(
36
)
NOT
NULL
,
`agent_id`
varchar
(
36
)
NOT
NULL
,
`context_id`
varchar
(
36
),
`user_message`
longtext
,
`agent_response`
longtext
,
`prompt_tokens`
int
,
`completion_tokens`
int
,
`total_tokens`
int
,
`processing_time`
bigint
,
`finish_reason`
varchar
(
50
),
`tool_calls`
json
,
`user_id`
varchar
(
36
),
`created_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
`updated_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
`created_by`
varchar
(
36
),
`updated_by`
varchar
(
36
),
`deleted`
int
DEFAULT
0
,
`remark`
text
,
PRIMARY
KEY
(
`id`
),
KEY
`idx_agent_id`
(
`agent_id`
),
KEY
`idx_user_id`
(
`user_id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
;
-- 系统日志表
CREATE
TABLE
IF
NOT
EXISTS
`sys_log`
(
`id`
varchar
(
36
)
NOT
NULL
,
`operation_type`
varchar
(
50
),
`resource_type`
varchar
(
50
),
`resource_id`
varchar
(
36
),
`user_id`
varchar
(
36
),
`description`
text
,
`request_params`
json
,
`response_result`
json
,
`success`
tinyint
DEFAULT
1
,
`error_message`
text
,
`ip_address`
varchar
(
50
),
`execution_time`
bigint
,
`created_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
,
`updated_at`
timestamp
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
,
`created_by`
varchar
(
36
),
`updated_by`
varchar
(
36
),
`deleted`
int
DEFAULT
0
,
`remark`
text
,
PRIMARY
KEY
(
`id`
),
KEY
`idx_user_id`
(
`user_id`
),
KEY
`idx_created_at`
(
`created_at`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_unicode_ci
;
-- 插入默认数据
INSERT
INTO
`sys_user`
(
id
,
username
,
password
,
email
,
nickname
,
status
,
role
)
VALUES
(
'default-user-id'
,
'admin'
,
'$2a$10$N.zmdr9k7uOCQb0bta/OauRxaOKSr.QhqyD2R5FKvMQjmHoLkm5Sy'
,
'admin@hiagent.com'
,
'Admin'
,
'active'
,
'admin'
);
INSERT
INTO
`agent`
(
id
,
name
,
description
,
status
,
default_model
,
owner
)
VALUES
(
'default-agent-1'
,
'客服助手'
,
'处理客户咨询的AI助手'
,
'active'
,
'deepseek-v2'
,
'default-user-id'
),
(
'default-agent-2'
,
'技术支持'
,
'提供技术支持服务的AI助手'
,
'active'
,
'gpt-3.5-turbo'
,
'default-user-id'
);
INSERT
INTO
`tool`
(
id
,
name
,
display_name
,
description
,
category
,
status
,
timeout
,
http_method
)
VALUES
(
'default-tool-1'
,
'search'
,
'搜索工具'
,
'进行网络搜索查询'
,
'API'
,
'active'
,
30000
,
'GET'
),
(
'default-tool-2'
,
'calculator'
,
'计算器'
,
'进行数学计算'
,
'FUNCTION'
,
'active'
,
5000
,
'POST'
),
(
'default-tool-3'
,
'weather'
,
'天气查询'
,
'查询天气信息'
,
'API'
,
'active'
,
10000
,
'GET'
),
(
'default-tool-4'
,
'get_current_time'
,
'获取当前时间'
,
'获取当前系统时间'
,
'FUNCTION'
,
'active'
,
1000
,
'GET'
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment