v3.1.0 后支持

"知识智能体"，就是有一个知识库 rag 智能体。用到的组件和“联网搜索”差不多。

### 1、设计智能体类参考

智能体是比较抽象的概念，需要按需定制。以下仅为参考

```java
import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.ai.chat.message.ChatMessage;
import org.noear.solon.ai.embedding.EmbeddingModel;
import org.noear.solon.ai.rag.Document;
import org.noear.solon.ai.rag.RepositoryStorable;
import org.noear.solon.ai.rag.loader.TextLoader;
import org.noear.solon.ai.rag.splitter.RegexTextSplitter;
import org.noear.solon.ai.rag.splitter.SplitterPipeline;
import org.noear.solon.ai.rag.splitter.TokenSizeTextSplitter;

import java.io.IOException;
import java.net.URI;
import java.util.List;

public class RagAgent {
    private EmbeddingModel embeddingModel;
    private RepositoryStorable repository;
    private ChatModel chatModel;

    public RagAgent(EmbeddingModel embeddingModel, RepositoryStorable repository, ChatModel chatModel) {
        this.embeddingModel = embeddingModel;
        this.repository = repository;
        this.chatModel = chatModel;
    }

    //加载知识
    public void load(String url) throws IOException {
        load(URI.create(url));
    }

    //加载知识
    public void load(URI uri) throws IOException {
        //1.加载文档
        List<Document> documents = new TextLoader(uri).load();
        //2.分割文档（组合分割）
        documents = new SplitterPipeline()
                .next(new RegexTextSplitter("\n\n")) //先按段分 
                .next(new TokenSizeTextSplitter(500)) //再大小分
                .split(documents);
        //3.入库
        repository.insert(documents); //（推入文档）
    }

    //问答
    public String qa(String question) throws Exception { //接收消息
        //1. 知识库检索，获取最相似的 4条
        List<Document> context = repository.search(question);

        //2. 增强提示语（字符串格式化）
        ChatMessage prompt = ChatMessage.ofUserAugment(question, context); //提示语增强（内部为字符串格式化）

        //3. 提交大模型
        return chatModel.prompt(prompt).call().getMessage().getContent();
    }
}
```


### 2、应用示例

* 初始化三大组件和智能体

```java
//构建 embeddingModel（）
EmbeddingModel  embeddingModel = EmbeddingModel.of(embedding_apiUrl)
        .apiKey(embedding_apiKey)
        .model(embedding_model)
        .build();

//构建 repository （内存矢量知识库） //此例：使用 embeddingModel
InMemoryRepository repository = new InMemoryRepository(embeddingModel);

//构建 chatModel
ChatModel chatModel = ChatModel.of(chat_apiUrl)
        .apiKey(chat_apkKey)
        .model(chat_model)
        .build();

//构建智能体
RagAgent agent = new RagAgent(embeddingModel, repository, chatModel);
```

* 初始化知识库（加载知识）


```java
//加载知识
agent.load("https://solon.noear.org/article/about?format=md");
agent.load("https://h5.noear.org/more.htm");
agent.load("https://h5.noear.org/readme.htm");
agent.load(new File("/data/demo.txt").toURI().toURL());
```


* 应用示例（问答）

```java
String answer = agent.qa(question);
```

