对于一些基础的大模型的通病: 

知识滞后性。

目前所有的大模型基本上都可以进行联网查询,解决了这个问题。
无法访问企业内部的数据库、文档、系统

无法主动调用API以及工具。

Function-call正是解决了这些问题。

流程:

第1步:用户提问
└─ "上海明天会下雨吗"

第2步:大模型理解意图
└─ 识别出:这是一个天气查询问题
   ├─ 地点:上海
   ├─ 时间:明天
   ├─ 关注点:是否下雨
   └─ 匹配到工具:queryWeather

第3步:大模型提取参数并调用工具
└─ 执行 queryWeather("上海", "2024-01-15")
   └─ 返回结果:{"rain": true, "rainfall": "5mm", "temperature": "18-22℃"}

第4步:大模型整合结果
└─ 结合原始问题 + 工具返回结果
   └─ 生成自然语言:"上海明天会下雨,预计降雨量5毫米,气温18到22度"

第5步:返回给用户
└─ "上海明天会下雨,预计降雨量5毫米,出门记得带伞哦"

实现:
 

@Service
public class ToolService {
    @Tool("查询天气工具。\n" +
            "    ⚠\uFE0F 重要:只有当用户明确询问天气相关问题时才能调用此工具!\n" +
            "    如果用户只提供地点名称(如\"北京\")而没有提到天气、气温、下雨等关键词,\n" +
            "    绝对不能调用此工具,应该由AI直接回复询问用户意图。\n" +
            "    \"\"\")")
    public String weather() {
        //todo 调用天气api或者其他关于天气的接口
        return "天气晴朗";
    }
}
 public interface Assistant {
        String chat(String message);
        // 流式响应
        TokenStream stream(String message);
    }

    @Bean
    public Assistant assistant(ChatLanguageModel qwenChatModel,
                               StreamingChatLanguageModel qwenStreamingChatModel,
                               ToolsService toolsService) {
        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);


        Assistant assistant = AiServices.builder(Assistant.class)
                .chatLanguageModel(qwenChatModel)
                .streamingChatLanguageModel(qwenStreamingChatModel)
                .tools(toolsService)
                .chatMemory(chatMemory)
                .build();

        return  assistant;
    }

加入预设角色(系统消息SystemMessage)

在langchain4j中实现也非常简单

  • @SystemMessage 系统消息, 一般做一些预设角色的提示词,设置大模型的基本职责
  • 可以通过{{current_date}} 传入参数, 因为预设词中的文本可能需要实时变化
  • @V("current_date"), 通过@V传入{{}}中的参数
  • 一旦参数不止一个, 就需要通过@UserMessage设置用户信息

加入系统的提示词 再次问
 

@SystemMessage("""
    您是一个专业的天气助手,名叫"小天"。请以热情、细致、贴心的方式回复用户。
    
    【核心规则】
    1. 只有当用户【明确提到天气相关词汇】时,才能调用 weather 工具
       天气词汇包括:天气、气温、温度、下雨、下雪、刮风、晴天、阴天、多云、预报、摄氏度、热、冷、暖、凉、雷雨、台风、雾霾
    
    2. 如果用户【只输入城市名称】,没有天气词汇,不要调用任何工具
       正确回复:"请问您想了解[城市名]的天气信息吗?或者需要其他帮助?"
    
    3. 调用 weather 工具前,必须提取到【城市名称】
       如果用户没有明确说城市,默认使用用户当前所在城市(如果知道)或主动询问
    
    4. 获得天气数据后,根据温度给出贴心建议:
       - 30℃以上 → 提醒防晒、多喝水
       - 10℃以下 → 提醒保暖、穿厚衣服
       - 下雨 → 提醒带伞
       - 下雪 → 提醒路滑小心
    
    【示例对话】
    用户:"北京"
    回复:"请问您想了解北京的天气信息吗?或者需要其他帮助?"
    
    用户:"上海天气怎么样"
    调用 weather("上海") → 回复:"上海今天多云,22-28℃,天气不错,适合出门散步哦~"
    
    用户:"今天热不热"
    调用 weather("默认城市") → 回复:"今天杭州33℃,确实比较热,出门记得防晒,多补充水分!"
    
    今天的日期是 {{current_date}}。
    请全程使用中文回复。
    """)
        TokenStream stream(@UserMessage String message,@V("current_date") String currentDate);
    }
@RequestMapping(value = "/memory_stream_chat",produces ="text/stream;charset=UTF-8")
    public Flux<String> memoryStreamChat(@RequestParam(defaultValue="我是谁") String message, HttpServletResponse response) {
        TokenStream stream = assistant.stream(message, LocalDate.now().toString());

        return Flux.create(sink -> {
            stream.onPartialResponse(s -> sink.next(s))
                    .onCompleteResponse(c -> sink.complete())
                    .onError(sink::error)
                    .start();

        });
    }

重写了stream的方法,这个要传入TokenStream stream = assistant.stream(message, LocalDate.now().toString());
你就会发现他已经遵从了你设置的规则了。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐