Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/fel-example/05-retrieval/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ node0-->node1{{=}}

## 验证

- 在IDEA中运行`DemoApplication`

- 在浏览器栏输入:`http://localhost:8080/ai/example/chat?query=请介绍一下黑神话悟空`

```json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import modelengine.fitframework.annotation.Component;
import modelengine.fitframework.annotation.Fit;
import modelengine.fitframework.annotation.Value;
import modelengine.fitframework.log.Logger;
import modelengine.fitframework.serialization.ObjectSerializer;
import modelengine.fitframework.util.FileUtils;

Expand All @@ -57,6 +58,7 @@
@Component
@RequestMapping("/ai/example")
public class RetrievalExampleController {
private static final Logger log = Logger.get(RetrievalExampleController.class);
private static final String REWRITE_PROMPT =
"作为一个向量检索助手,你的任务是结合历史记录,为”原问题“生成”检索词“," + "生成的问题要求指向对象清晰明确,并与“原问题语言相同。\n\n"
+ "历史记录:\n---\n" + DEFAULT_HISTORY_KEY + "---\n原问题:{{query}}\n检索词:";
Expand Down Expand Up @@ -85,22 +87,27 @@ public RetrievalExampleController(ChatModel chatModel, EmbedModel embedModel,
.others(node -> node.map(tip -> tip.freeze().get("query").text()))
.retrieve(new DefaultVectorRetriever(vectorStore, SearchOption.custom().topK(1).build()))
.synthesize(docs -> Content.from(docs.stream().map(Document::text).collect(Collectors.joining("\n\n"))))
.close();
.close(__ -> log.info("Retrieve flow completed."));

AiProcessFlow<File, List<Document>> indexFlow = AiFlows.<File>create()
.load(new JsonFileSource(serializer, StringTemplate.create("{{question}}: {{answer}}")))
.index(vectorStore)
.close();
File file = FileUtils.file(this.getClass().getClassLoader().getResource("data.json"));
notNull(file, "The data cannot be null.");
indexFlow.converse().offer(file);
indexFlow.converse()
.doOnError(e -> log.info("Index build error. [error={}]", e.getMessage(), e))
.doOnFinally(() -> log.info("Index build successfully."))
.offer(file);

this.ragFlow = AiFlows.<String>create()
.just(query -> log.info("RAG flow start. [query={}]", query))
.map(query -> Tip.from("query", query))
.runnableParallel(value("context", retrieveFlow), passThrough())
.prompt(Prompts.history(), Prompts.human(CHAT_PROMPT))
.just(__ -> log.info("LLM start generation."))
.generate(chatFlowModel)
.close();
.close(__ -> log.info("RAG flow completed."));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@ public MatchWindow(Window source, UUID id, Object data) {
* @return 返回创建的MatchWindow对象
*/
public static synchronized MatchWindow from(Window source, UUID id, Object data) {
MatchWindow window = all.get(id.toString());
// Use composite key: sessionId + UUID to prevent cross-session pollution
String cacheKey = source.getSession().getId() + ":" + id.toString();
MatchWindow window = all.get(cacheKey);
if (window == null) {
window = new MatchWindow(source, id, data);
FlowSession session = new FlowSession(source.getSession());
session.setWindow(window);
all.put(id.toString(), window);
all.put(cacheKey, window);
Comment thread
CodeCasterX marked this conversation as resolved.
Outdated
}
WindowToken token = window.createToken();
token.beginConsume();
Expand Down