2024-05-20T06:42:22.290321Z INFO actix_server::builder: starting 8 workers 2024-05-20T06:42:22.290339Z INFO actix_server::server: Actix runtime found; starting in Actix runtime 2024-05-20T06:42:31.820935Z INFO HTTP request{method=POST host="127.0.0.1:7700" route=/indexes/movies/documents query_parameters= user_agent=Meilisearch Go (v0.26.3) status_code=202}: meilisearch: close time.busy=13.3ms time.idle=327ms 2024-05-20T06:42:31.824691Z INFO milli::update::index_documents::enrich: Primary key was not specified in index. Inferred to 'id' 2024-05-20T06:42:35.533861Z INFO index_scheduler::batch: document indexing done indexing_result=DocumentAdditionResult { indexed_documents: 15309, number_of_documents: 15309 } 2024-05-20T06:42:35.700474Z INFO index_scheduler: A batch of tasks was successfully completed with 1 successful tasks and 0 failed tasks.
准备 AI 模型服务
这里你可以选择参考之前的博客内容,自己搭建一个模型服务,并将 API 接入 Dify 使用。也可以选择更简单易一些,在你能够轻松获取的大模型服务中选择一家的大模型 API 使用。
我个人推荐最近刚刚更新了大参数量版本的,使用成本低、效果还不错的零一万物
yi-medium
或
yi-large
,你可以
在这里申请 API Keys
[9]
。
{ "id":10515, "title":"Castle in the Sky", "overview":"A young boy and a girl with a magic crystal must race against pirates and foreign agents in a search for a legendary floating castle.", "genres":["Adventure","Fantasy","Animation","Action","Family","Romance"], "poster":"https://image.tmdb.org/t/p/w500/npOnzAbLh6VOIu3naU5QaEcTepo.jpg", "release_date":523324800 }
buf, err := os.ReadFile("data/movies.json") if err !=nil{ fmt.Println(err) os.Exit(1) } var documents []Movie err = json.Unmarshal(buf,&documents) if err !=nil{ fmt.Println(err) os.Exit(1)
}
task, err := index.AddDocuments(documents) if err !=nil{ fmt.Println(err) os.Exit(1) }
fmt.Println(task.TaskUID) }
当我们使用
go run main.go
运行程序的时候,一切顺利,将得到一个包含了正在执行的索引任务的数字 ID 结果:
# go run main.go 0
如果此时我们在观察日志,将能够看到搜索引擎一秒就完成了这个数据的索引工作:
2024-05-20T06:30:40.771571Z INFO HTTP request{method=POST host="127.0.0.1:7700" route=/indexes/movies/documents query_parameters= user_agent=MeilisearchGo(v0.26.3) status_code=202}: meilisearch: close time.busy=3.46ms time.idle=4.30ms 2024-05-20T06:30:40.776351Z INFO milli::update::index_documents::enrich:Primary key was not specified in index.Inferred to 'id' 2024-05-20T06:30:40.807314Z INFO index_scheduler::batch: document indexing done indexing_result=DocumentAdditionResult{ indexed_documents:1, number_of_documents:1} 2024-05-20T06:30:40.809256Z INFO index_scheduler: A batch of tasks was successfully completed with 1 successful tasks and 0 failed tasks.
{"results":[{"indexUid":"movies","hits":[{"id":101031,"title":"Sky Captain and the World of Tomorrow","overview":"When gigantic robots attack New York City, \"Sky Captain\" uses his private air force to fight them off. His ex-girlfriend, reporter Polly Perkins, has been investigating the recent disappearance of prominent scientists. Suspecting a link between the global robot attacks and missing men, Sky Captain and Polly decide to work together. They fly to the Himalayas in pursuit of the mysterious Dr. Totenkopf, the mastermind behind the robots.","genres":["Mystery","Action","Thriller","Science Fiction","Adventure"],"poster":"https://image.tmdb.org/t/p/w500/ceW9Zi43hEQPdxkPkohVCcG1CuT.jpg","release_date":1095379200},{"id":102112,"title":"Sky Fighters","overview":"Les Chevaliers du ciel (English: Sky Fighters) is a 2005 French film directed by Gérard Pirès about two air force pilots preventing a terrorist attack on the Bastille Day celebrations in Paris. It is based on Tanguy et Laverdure, a comics series by Jean-Michel Charlier and Albert Uderzo – of Astérix fame, which was also made into a hugely successful TV series from 1967 to 1969 making Tanguy and Laverdure, the two main heroes, part of popular Francophone culture.","genres":["Action","Adventure"],"poster":"https://image.tmdb.org/t/p/w500/fXyIF7W059RtNwSZViVUR9bUXWX.jpg","release_date":1129334400},{"id":102368,"title":"Sky High","overview":"Set in a world where superheroes are commonly known and accepted, young Will Stronghold, the son of the Commander and Jetstream, tries to find a balance between being a normal teenager and an extraordinary being.","genres":["Adventure","Comedy","Family"],"poster":"https://image.tmdb.org/t/p/w500/yk51E2OxA9zUdRqK0YvPTx6lfa7.jpg","release_date":1122595200}],"query":"sky","processingTimeMs":4,"limit":3,"offset":0,"estimatedTotalHits":113}]}
如果你不需要 “AI 之外的访问方式”,那么只需要记住上面的使用 API 调用搜索引擎的方法和搜索引擎返回的接口结果格式即可。
步骤二:实现一个简单的接口
除了上一篇文章《
使用 Dify 和 Moonshot API 做一个懒人 AI 阅读工具(二):轻量 RAG 应用
[17]
》中提到的,借用“内容审查”扩展接口,来完成 AI 生成使用的资料扩展外。
完成代码修改后,我们使用
go run main.go
重新启动程序,然后在 Dify 中随便搜索一个关键词(我使用的是
sky
),然后对 AI 提问:“为什么推荐这几部电影?”
向 AI 提问,获取 Dify 请求信息
虽然我们已经将我们的 API 服务和 Dify 连接了起来,但是目前 API 服务和搜索引擎还没有连接起来,所以我们可以忽略这个时候的模型回答。只关注 API 服务的日志信息:
{"point":"app.external_data_tool.query","params":{"app_id":"55f2f15b-3731-494b-b034-240cd169d0cb","tool_variable":"movies_data","inputs":{"keywords":"sky"},"query":"为什么推荐这几部电影?"}} [GIN]2024/05/20-21:56:17|200|1.08275ms|10.11.12.90| POST "/new-api-for-dify"
var result string for _, movie :=range movies.Results{ for _, hit :=range movie.Hits{ result += fmt.Sprintf("- 标题:%s\n", hit.Title) result += fmt.Sprintf("- 简介:%s\n\n", hit.Overview) } }