MindSearch允许llm生成类似jupyter notebook的代码片段自主的规划搜索路径,形成搜索图可以自由的控制最大迭代步数,这种灵活的特性使得的MindSearch搜索效果相比写死的代码要效果好很多。
MindSearch代码不多,但是调用很复杂,不行请看这个时序图,请格外关注WebSearchGraph
和MindSearchAgent
两个类,MindSearchAgent
是一切代理的总主管,WebSearchGraph
是通过llm生成自主规划的搜索路径的小主管,由llm生成的代码就是通过WebSearchGraph
规划搜索路径的。
MindSearch的llm调用库lagent
是他们团队手搓原创的,连siliconflow调用qwen模型都不支持,为了调通只能魔改lagent
,这里就不赘述。文档里支持的四个搜索API:GoogleSearch
、DuckDuckGoSearch
、BraveSearch
、BingSearch
,推荐用GoogleSearch
和DuckDuckGoSearch
,DuckDuckGoSearch
免费需要设置proxy,GoogleSearch
是通过serper.dev绑卡赠送一次性额度,BraveSearch
绑卡有免费月额度但是并发1,BingSearch
要开通azure绑定Visa卡。
如果单纯调用LLM的API,不需要本地推理,可以把requirements.txt
里面的lmdeploy
、transformers
注释掉不用安装。
用原版的提示词效果最好的是GPT4o和internlm2.5,为了让qwen和deepseek也能跑通,需要修改提示词文件mindsearch_prompt.py
,修改GRAPH_PROMPT_CN
给llm增加一个示例,下面是我改的:
## 注意事项
1. 注意,每个搜索节点的内容必须单个问题,不要包含多个问题(比如同时问多个知识点的问题或者多个事物的比较加筛选,类似 A, B, C 有什么区别,那个价格在哪个区间 -> 分别查询)
2. 不要杜撰搜索结果,要等待代码返回结果
3. 同样的问题不要重复提问,可以在已有问题的基础上继续提问
4. 一次输出中,不要包含多个代码块,每次只能有一个代码块
5. 每个代码块应该放置在一个代码块标记中,同时生成完代码后添加一个<|action_end|>标志,如下所示:
<|action_start|><|interpreter|>```python
# 你的代码块
```<|action_end|>
6. 一个代码块中,一个节点必须和一条边相连,并最后调用node方法获取结果。
7. 整个图构建最后一次回复应该是添加node_name为'response'的 response 节点,必须添加 response 节点,不要添加其他节点。 添加 response 节点的时候,要单独添加,不要和其他节点一起添加,不能同时添加 response 节点和其他节点
示例(注意这是多次的回答而不是单次的):
<|action_start|><|interpreter|>```python
graph = WebSearchGraph()
# 添加根节点
graph.add_root_node(node_content="人工智能的最新进展有哪些?\", node_name="root")
# 添加搜索节点
graph.add_node(node_name="key_areas", node_content="人工智能研究的关键领域有哪些?")
# 添加边,表示搜索节点之间的关系
graph.add_edge(start_node="key_areas", end_node="trends")
# 读取节点的查询结果并打印出来
graph.node("key_areas")
```<|action_end|>
<|action_start|><|interpreter|>```python
# 添加根节点
graph.add_node(node_name="trends", node_content="机器学习的最新趋势是什么?")
graph.add_edge(start_node="key_areas", end_node="trends")
graph.node("trends")
```<|action_end|>
<|action_start|><|interpreter|>```python
graph.add_response_node(node_name="response")
graph.add_edge(start_node="trends", end_node="response")
```<|action_end|>
从这个例子可以看出,graph.node()
方法必须调用,否则llm就获取不到搜索代理返回的信息,导致结果瞎编乱造。顺带一提,internlm2.5竟然把from ilagent.agents.python_web import WebSearchGraph
炼在模型里,光靠提示词大模型是不可能写出这行代码的,怪不得配合MindSearch效果好。
我还碰到一个奇怪的问题,有的时候只会执行一次搜索就结束了,但是代码明显没跑完,因为他没有走到最后一个response节点,我怀疑是mindsearch_agent.py
代码导致的,这里修改确保graph已经创建成功在执行后续操作。
@@ -373,6 +402,20 @@ class MindSearchAgent(BaseAgent):
args=(command, ))
producer_thread.start()
+ # 等待确保 graph 对象被创建
+ max_retries = 10
+ retry_count = 0
+ while retry_count < max_retries:
+ graph = self.local_dict.get('graph')
+ if graph is not None:
+ break
+ time.sleep(0.1) # 短暂等待
+ retry_count += 1
+ logger.info(f"Waiting for graph object, attempt {retry_count}")
+
+ if self.local_dict.get('graph') is None:
+ raise RuntimeError("Failed to initialize graph object")
+
responses = defaultdict(list)
ordered_nodes = []
active_node = None
标签:MindSearchAgent,node,WebSearchGraph,graph,MindSearch,ActionExecutor,心得,response
From: https://www.cnblogs.com/mesopotamiaa/p/18521422