签到工具新增检查功能:修复状态误判问题
问题:
- 用户询问'我今天签到了吗'时,AI基于对话历史判断而非查询数据库
- 导致明明没签到,AI却说已经签到了(误判)
解决方案:
- 新增 action=check 操作,专门用于检查当前节点今天是否已签到
- 直接调用 HasSignedOnDay 查询数据库,返回准确的签到状态
- AI 现在会强制调用工具查询,而不是根据记忆猜测
改动内容:
- 工具定义中添加 check 操作类型
- 实现 executeCheck 方法,查询数据库并返回明确状态
- 添加完整的单元测试(未签到/已签到两种场景)
- 更新文档说明 check 操作的使用
使用示例:
- 用户:'我今天签到了吗?'
- AI 调用:{"action": "check"}
- 返回:'XXX 今天还没有签到。' 或 'XXX 今天已经签到过了。'
测试:
- ✅ 未签到场景测试通过
- ✅ 已签到场景测试通过
- ✅ 所有签到工具测试通过
- ✅ 项目编译成功
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,9 +45,10 @@ func (t *Tool) Enabled() bool { return t.enabled && t.store != nil }
|
||||
|
||||
// ToolDefinition returns the OpenAI tool definition
|
||||
func (t *Tool) ToolDefinition(description string) *model.Tool {
|
||||
desc := "签到工具。支持签到和查询两种操作:\n" +
|
||||
desc := "签到工具。支持三种操作:\n" +
|
||||
"1. 签到操作(action=sign):记录节点今日签到信息,每个节点每天只能签到一次。必填参数:地区、名字、设备\n" +
|
||||
"2. 查询操作(action=query):查询签到统计。可按日期范围查询,默认查询今天。返回签到总数和按天的统计数据"
|
||||
"2. 查询操作(action=query):查询签到统计。可按日期范围查询,默认查询今天。返回签到总数和按天的统计数据\n" +
|
||||
"3. 检查操作(action=check):检查当前节点今天是否已签到。用于回答用户'我今天签到了吗'之类的问题"
|
||||
if description != "" {
|
||||
desc = description
|
||||
}
|
||||
@@ -61,8 +62,8 @@ func (t *Tool) ToolDefinition(description string) *model.Tool {
|
||||
"properties": map[string]any{
|
||||
"action": map[string]any{
|
||||
"type": "string",
|
||||
"enum": []string{"sign", "query"},
|
||||
"description": "操作类型:sign=签到,query=查询签到统计",
|
||||
"enum": []string{"sign", "query", "check"},
|
||||
"description": "操作类型:sign=签到,query=查询签到统计,check=检查今天是否已签到",
|
||||
},
|
||||
"region": map[string]any{
|
||||
"type": "string",
|
||||
@@ -122,10 +123,12 @@ func (t *Tool) Execute(ctx context.Context, args string, runtime agenttool.Runti
|
||||
switch strings.ToLower(strings.TrimSpace(params.Action)) {
|
||||
case "query":
|
||||
return t.executeQuery(ctx, params, runtime)
|
||||
case "check":
|
||||
return t.executeCheck(ctx, params, runtime)
|
||||
case "sign", "":
|
||||
return t.executeSign(ctx, params, runtime)
|
||||
default:
|
||||
return "", fmt.Errorf("无效的操作类型:%s,只支持 sign 或 query", params.Action)
|
||||
return "", fmt.Errorf("无效的操作类型:%s,只支持 sign、query 或 check", params.Action)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +179,31 @@ func (t *Tool) executeSign(ctx context.Context, params signParams, runtime agent
|
||||
return fmt.Sprintf("签到成功!%s\n签到内容:%s", displayName(node), record.SignText), nil
|
||||
}
|
||||
|
||||
// executeCheck 检查当前节点今天是否已签到
|
||||
func (t *Tool) executeCheck(ctx context.Context, params signParams, runtime agenttool.Runtime) (string, error) {
|
||||
// 节点身份来自消息上下文
|
||||
node, ok := agenttool.NodeContextFromContext(ctx)
|
||||
if !ok || strings.TrimSpace(node.NodeID) == "" {
|
||||
return "", fmt.Errorf("缺少发送节点上下文,无法检查签到状态")
|
||||
}
|
||||
|
||||
now := runtime.Now
|
||||
if now.IsZero() {
|
||||
now = time.Now()
|
||||
}
|
||||
|
||||
// 查询数据库检查今天是否已签到
|
||||
signed, err := t.store.HasSignedOnDay(node.NodeID, now)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("检查签到状态失败:%w", err)
|
||||
}
|
||||
|
||||
if signed {
|
||||
return fmt.Sprintf("%s 今天已经签到过了。", displayName(node)), nil
|
||||
}
|
||||
return fmt.Sprintf("%s 今天还没有签到。", displayName(node)), nil
|
||||
}
|
||||
|
||||
// executeQuery 执行查询操作
|
||||
func (t *Tool) executeQuery(ctx context.Context, params signParams, runtime agenttool.Runtime) (string, error) {
|
||||
now := runtime.Now
|
||||
|
||||
Reference in New Issue
Block a user