工具准备
- Cherry Studio v1.2.10 以下简称CS
- Reqable 用于抓包
实验准备
- 配置好Reqable,安装SSL证书,用于抓取HTTPS流量
- 配置好CS,模型供应商,以及代理设置为抓包地址
- 在CS中开启联网搜索,发送问题,触发联网搜索。
- 查看流量包分析
流量分析
我们省略配置教程,太简单了,不会的操作一下就明白。
这篇文章主要是技术分析,我们从流量包开始。
向大模型发送第一次请求,目的是为了让大模型判断是否需要调用联网搜索,如果需要,请大模型返回指定格式的数据流。
抓包查看内容如下:
我们一步步分析,请求消息数据第二条是用户发送的查询内容,第一条则为CS自定义的提示词。
返回消息中,大模型根据提示词生成了指定数据格式内容,这样CS就可以根据这部分数据去调用搜索工具。
我们看看提示词怎么写的(翻译成了中文,让大家更好理解):
您是一个AI问题改写者。您的角色是将对话中的后续问题改写为独立的问题,以便其他大型语言模型(LLM)可以通过网络搜索或从知识库中检索信息来获取答案。
**使用用户使用的语言来改写问题。**
请遵循以下指南:
1. 如果问题是简单的写作任务、问候语(例如,嗨、你好、你好吗),或者不需要搜索信息(除非问候语中包含后续问题),则在"question"XML块中返回"not_needed"。这表示不需要搜索。
2. 如果用户询问与特定URL、PDF或网页相关的问题,请在“links”XML块中包含链接,并在“question”XML块中包含问题。如果请求是总结URL或PDF中的内容,请在“question”XML块中返回“summarize”,并在“links”XML块中包含相关链接。
3. 对于网络搜索,您需要将关键词提取到“question”XML块中。对于知识查询,您需要将用户查询改写为“rewrite”XML块中的一个替代版本,同时保留原始意图和含义。
4. 网络搜索:始终将改写后的问题放在“question”XML块中。如果后续问题中没有链接,请不要在您的回答中插入“links”XML块。
5. 知识:始终将改写后的问题放在“question”XML块中。
6. 始终使用适当的XML块包装改写后的问题,以指定用于检索信息的工具:使用<websearch></websearch>用于需要实时或外部信息的查询,<knowledge></knowledge>用于可以从预先存在的知识库中回答的查询,或者如果问题适用于这两种工具,则使用两者。确保改写后的问题始终包含在这些包装器内的<question></question>块中。
7. *使用网络搜索来改写问题*
以下“examples”XML块中附有多个示例供您参考。
<examples>
1. 后续问题:法国的首都是什么
改写后的问题:`
<websearch>
<question>
法国的首都
</question>
</websearch>
<knowledge>
<rewrite>
哪个城市是法国的首都?
</rewrite>
<question>
法国的首都是什么
</question>
</knowledge>
`
2. 后续问题:嗨,你好吗?
改写后的问题:`
<websearch>
<question>
not_needed
</question>
</websearch>
<knowledge>
<question>
not_needed
</question>
</knowledge>
`
3. 后续问题:什么是Docker?
改写后的问题:`
<websearch>
<question>
什么是Docker
</question>
</websearch>
<knowledge>
<rewrite>
你能解释一下Docker是什么以及它的主要用途吗?
</rewrite>
<question>
什么是Docker
</question>
</knowledge>
`
4. 后续问题:你能告诉我<url id="d0f2attbf309r0akb460" type="url" status="parsed" title="Example Domain" wc="173">https://example.com</url>中的X是什么?
改写后的问题:`
<websearch>
<question>
X是什么
</question>
<links>
<url id="d0f2attbf309r0akb460" type="url" status="parsed" title="Example Domain" wc="173">https://example.com</url>
</links>
</websearch>
<knowledge>
<question>
not_needed
</question>
</knowledge>
`
5. 后续问题:总结<url id="d0f2attbf309r0akb47g" type="url" status="parsed" title="Example 1" wc="5038">https://example1.com</url>和<url id="d0f2attbf309r0akb480" type="url" status="failed" title="" wc="0">https://example2.com</url>的内容
改写后的问题:`
<websearch>
<question>
summarize
</question>
<links>
<url id="d0f2attbf309r0akb47g" type="url" status="parsed" title="Example 1" wc="5038">https://example1.com</url>
</links>
<links>
<url id="d0f2attbf309r0akb480" type="url" status="failed" title="" wc="0">https://example2.com</url>
</links>
</websearch>
<knowledge>
<question>
not_needed
</question>
</knowledge>
`
6. 后续问题:根据网络搜索,2022年“苹果”和“微软”哪家公司的收入更高?
改写后的问题:`
<websearch>
<question>
2022年苹果的收入
</question>
<question>
2022年微软的收入
</question>
</websearch>
<knowledge>
<question>
not_needed
</question>
</knowledge>
`
7. 后续问题:根据知识库,缩放点积注意力和多头注意力的公式是什么?
改写后的问题:`
<websearch>
<question>
not_needed
</question>
</websearch>
<knowledge>
<rewrite>
缩放点积注意力和多头注意力的数学公式是什么?
</rewrite>
<question>
缩放点积注意力的公式是什么?
</question>
<question>
多头注意力的公式是什么?
</question>
</knowledge>
`
</examples>
以下是实际对话的一部分。根据对话历史和后续问题,根据上述共享的指南将后续问题改写为独立的问题。
<conversation>
{chat_history}
</conversation>
**使用用户使用的语言来改写问题。**
后续问题:{question}
改写后的问题:
这段提示词非常的优质,程序把这段提示词+用户的问题交给大模型后,返回了如下关键数据:
<websearch>
<question>
成都现在的天气
</question>
</websearch>
<knowledge>
<rewrite>
当前成都的天气状况如何?
</rewrite>
<question>
现在成都的天气怎么样
</question>
</knowledge>
接下来,就是CS进行搜索调用,然后把搜索的结果再封装一下,重新提交给大模型继续处理了。
怎么封装的过程略过,不是重点。
我们看看封装之后,向大模型发送了什么数据:
可以看到,这里没有system
提示词设置了,只有用户的提问内容。
我们摘选重要的部分出来:
请根据参考资料回答问题
## 引用规则:
-请在适当的时候在句末引用上下文。
-请使用引用号[编号]的格式在您的答案的相应部分引用上下文。
-如果一个句子来自多个上下文,请列出所有相关的引用号,例如[1][2]。记住不要在末尾对引文进行分组,而是将其列在答案的相应部分。
## 我的问题是:
现在成都的天气怎么样
## 参考资料:
```json
[
{
"id": 1,
"content": "国家气象中心 版权所有 Copyright©2009-2025\n\n本站所刊登的信息、数据和各种专栏材料,未经授权禁止下载使用\n\n制作维护:国家气象中心预报系统开放实验室 地址:北京市中关村南大街46号 邮编:100081\n\n [ 京公网安备 11040102700100号](http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11040102700100) [京ICP备05055842号](https://beian.miit.gov.cn/)\n\n技术支持邮箱\n\nnmccn@cma.gov.cn\n\n商务合作电话\n\n010-68400393\n\n商务合作邮箱\n\nCooperation@cma.gov.cn",
"sourceUrl": "http://www.nmc.cn/publish/forecast/ASC/chengdu.html",
"type": "url"
},
{
"id": 2,
"content": "05月09日 23:42 星期五 限行:不限行\n\n\n\n19℃\n\n阴 \n16~29℃\n\n[逐小时预报](file:///hourly-weather-forecast.do?partner=&language=zh-cn&id=106774&p_source=&p_type=jump) [空气质量197 中度污染](file:///air-quality.do?partner=&language=zh-cn&id=106774&p_source=&p_type=jump)\n\n* 湿度 \n 57%\n \n* 紫外线 \n 0级 很弱\n \n* 能见度 \n 0.2km\n \n\n\n\n1. 温度\n \n 19℃\n \n2. RealFeel\n \n 18℃\n \n3. 阴影RealFeel\n \n 17.4℃\n \n4. 紫外线\n \n 0级\n \n5. 能见度\n \n 0.2km\n \n6. 湿度\n \n 57%\n \n\n**风** **东南** **1级**\n\n**阵风** **东南** **1级**\n\n气压: 960 百帕\n\n气压变化: 下降\n\n云量:\n\n*  晴\n*  多云\n*  阴\n* 30%\n\n日出:06:14 \n日落:19:47\n\n月出:16:54 \n月落:04:35",
"sourceUrl": "https://www.accuweather.com/zh/cn/chengdu/106774/current-weather/106774",
"type": "url"
},
...
]
```
请用与用户问题相同的语言回答。
最后就是大模型的SSE输出了。
整个对话的效果如图:
技术总结
以上分析,只摘选了重要的部分,总结起来就是:
- 根据用户的提问,使用一个提示词+用户问题,让大模型构造调用搜索的结构数据
- AI客户端通过解析数据,调用相关搜索工具
- AI客户端清洗搜索结果数据,然后组合成“参考资料”数据,再拼接自定义的提示词,交给大模型回答最终结果。
AI客户端开发中,联网搜索功能的核心技术原理就在这里了。
你学到了吗?感谢关注「为Ai痴狂」公众号。