伪代码教学skill用法配合一下iflow 功能吧

其实我一直都想做一下,哈哈哈,刚好这个点,我们先看看最关键的一点
1.其实我今天再看skill中关注到其中一点有一个web search 功能,哈哈哈,大家能猜到了对吧
我试图想要去建一个MCP功能;
这个工作流:
1.建一个临时工作库
2.开始搜索关键词内容
3,开始结合关键词得到的内容来整合,但不上传内容
4.随后清理临时知识库
5.Agent开始执行

2.其实整个过程使用iflow cli来配置setting.json 利用的硅基流动API功能。
目标就是实现web search 和 web fetch功能嘛

哈哈哈,只是


一直显示无法使用真的很可惜,arg 参数设定到那个需要的脚本:
我喜欢用.py 经过规划和分析仅仅只需要实现web search功能,因此我没有想那么多


虽然没有办法使用哈

脚本:
#!/usr/bin/env python3
“”"
iflow Web Search MCP 服务器(简化版)
仅实现联网搜索功能,不导入知识库,直接返回结果供 Agent 使用

安装依赖:
pip install mcp

配置:
在 settings.json 的 “mcpServers” 中添加:
{
“iflow-web-search”: {
“command”: “python”,
“args”: [“D:\iflow_nb\iflow_web_search_mcp_simple.py”],
“env”: {
“IFLOW_API_KEY”: “your_api_key_here”
},
“disabled”: false,
“autoApprove”: [“web_search”]
}
}
“”"
import asyncio
import json
import os
import sys
import time
from typing import Any, Dict, List, Optional

import requests

尝试导入 mcp 库

try:
from mcp.server import Server, InitializationOptions, NotificationOptions
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
except ImportError:
print(“错误: 未安装 mcp 库。请运行: pip install mcp”, file=sys.stderr)
sys.exit(1)

将 iflow-nb 脚本目录加入路径

sys.path.insert(0, os.path.join(os.path.dirname(file), “.gemini”, “skills”, “iflow-nb”, “scripts”))

尝试导入 iflow_common

try:
from iflow_common import load_credentials, start_search, poll_search, log # type: ignore
except ImportError:
# 如果导入失败,定义简化版本
def load_credentials():
“”“加载 iflow API 凭证”“”
key = os.environ.get(“IFLOW_API_KEY”, “”)
if not key:
config_path = os.path.expanduser(“~/.config/iflow-nb/api-key”)
if os.path.exists(config_path):
with open(config_path, “r”) as f:
key = f.read().strip()
if not key:
raise ValueError(“IFLOW_API_KEY 未配置”)
base_url = os.environ.get(“IFLOW_BASE_URL”, “https://platform.iflow.cn”)
return key, base_url

def log(msg):
    print(f">>> {msg}", file=sys.stderr)

配置

BASE_URL = “https://platform.iflow.cn

创建 MCP 服务器

server = Server(“iflow-web-search-simple”)

定义工具

TOOLS = [
Tool(
name=“web_search”,
description=“联网搜索功能。使用 iflow API 进行网络搜索,返回搜索结果供 Agent 分析和提取关键内容。支持快速搜索(FAST_SEARCH,约4秒)和深度研究(DEEP_RESEARCH,约2-5分钟)。”,
inputSchema={
“type”: “object”,
“properties”: {
“query”: {
“type”: “string”,
“description”: “搜索关键词(必填)”
},
“search_type”: {
“type”: “string”,
“enum”: [“FAST_SEARCH”, “DEEP_RESEARCH”],
“description”: “搜索类型:FAST_SEARCH(快速,约4秒)或 DEEP_RESEARCH(深度,约2-5分钟)”,
“default”: “FAST_SEARCH”
},
“max_results”: {
“type”: “integer”,
“description”: “返回的最大结果数量(0=全部)”,
“default”: 10
}
},
“required”: [“query”]
}
)
]

@server.list_tools()
async def handle_list_tools() → List[Tool]:
“”“列出可用工具”“”
return TOOLS

@server.call_tool()
async def handle_call_tool(name: str, arguments: Dict[str, Any]) → List[TextContent]:
“”“处理工具调用”“”
if name == “web_search”:
return await handle_web_search(**arguments)
else:
raise ValueError(f"未知工具: {name}")

async def handle_web_search(
query: str,
search_type: str = “FAST_SEARCH”,
max_results: int = 10
) → List[TextContent]:
“”“执行联网搜索”“”
try:
# 1. 验证凭证
try:
api_key, base_url = load_credentials()
except ValueError as e:
return [TextContent(
type=“text”,
text=f"错误: {str(e)}\n\n请设置 IFLOW_API_KEY 环境变量或创建 ~/.config/iflow-nb/api-key 文件"
)]

    headers = {"Authorization": f"Bearer {api_key}"}
    
    # 2. 创建临时知识库
    temp_kb_name = f"temp_search_{int(time.time())}"
    log(f"创建临时知识库: {temp_kb_name}")
    
    resp = requests.post(
        f"{base_url}/api/v1/knowledge/createNotebook",
        headers=headers,
        json={"name": temp_kb_name, "description": "临时搜索知识库"}
    )
    
    if not resp.json().get("success"):
        return [TextContent(type="text", text="创建临时知识库失败")]
    
    kb_id = resp.json().get("data", {}).get("id")
    
    try:
        # 3. 发起搜索
        log(f"发起搜索: {query} ({search_type})")
        body = {
            "query": query,
            "type": search_type,
            "source": "WEB",
            "notebookId": kb_id
        }
        
        resp = requests.post(
            f"{base_url}/api/v1/knowledge/startSearch",
            headers=headers,
            json=body
        )
        
        if not resp.json().get("success"):
            code = resp.json().get("code", "")
            if code == "40010":
                return [TextContent(type="text", text="错误: 深度研究并发限制,已有一个深度研究任务正在处理中,请稍后再试")]
            return [TextContent(type="text", text=f"搜索发起失败: {resp.json().get('message', '未知错误')}")]
        
        search_id = resp.json().get("data", "")
        
        # 4. 轮询搜索结果
        if search_type == "FAST_SEARCH":
            max_wait, interval = 60, 3
        else:  # DEEP_RESEARCH
            max_wait, interval = 600, 10
        
        log(f"轮询搜索结果 (最多等待 {max_wait} 秒)...")
        elapsed = 0
        search_data = None
        
        while elapsed < max_wait:
            time.sleep(interval)
            elapsed += interval
            
            resp = requests.get(
                f"{base_url}/api/v1/knowledge/getSearchResult?notebookId={kb_id}&id={search_id}",
                headers=headers
            )
            
            data = resp.json().get("data", {})
            status = data.get("status", "unknown")
            
            if status == "completed":
                search_data = data
                break
            elif status in ("failed", "dismissed"):
                return [TextContent(type="text", text=f"搜索失败: status={status}")]
        
        if not search_data:
            return [TextContent(type="text", text="搜索超时")]
        
        # 5. 处理结果
        results = search_data.get("results", [])
        result_count = len(results)
        
        if max_results > 0:
            results = results[:max_results]
        
        # 6. 构建返回文本
        result_text = f"""# 联网搜索结果

搜索信息

  • 查询词: {query}
  • 搜索类型: {search_type}
  • 总结果数: {result_count}
  • 返回结果数: {len(results)}

搜索结果

“”"

        for i, item in enumerate(results, 1):
            title = item.get("title", "无标题")
            url = item.get("url", "")
            snippet = item.get("snippet", item.get("content", "无摘要"))
            content_type = item.get("contentType", "WEBSITE")
            score = item.get("score")
            
            result_text += f"### {i}. {title}\n"
            result_text += f"- **URL**: {url}\n"
            result_text += f"- **类型**: {content_type}\n"
            if score is not None:
                result_text += f"- **相关性**: {score:.2f}\n"
            result_text += f"- **摘要**: {snippet}\n\n"
        
        return [TextContent(type="text", text=result_text)]
        
    finally:
        # 7. 删除临时知识库
        log(f"删除临时知识库: {kb_id}")
        requests.post(
            f"{base_url}/api/v1/knowledge/deleteNotebook",
            headers=headers,
            json={"id": kb_id}
        )

except Exception as e:
    return [TextContent(
        type="text",
        text=f"搜索过程中发生错误: {str(e)}\n\n请检查:\n1. IFLOW_API_KEY 是否正确配置\n2. 网络连接是否正常\n3. API 服务是否可用"
    )]

async def main():
“”“启动 MCP 服务器”“”
# 检查凭证
try:
load_credentials()
log(“凭证验证成功”)
except ValueError as e:
log(f"凭证错误: {e}")
log(“请设置 IFLOW_API_KEY 环境变量或创建 ~/.config/iflow-nb/api-key 文件”)
sys.exit(1)

# 启动服务器
async with stdio_server() as (read_stream, write_stream):
    await server.run(
        read_stream,
        write_stream,
        InitializationOptions(
            server_name="iflow-web-search-simple",
            server_version="0.1.0",
            capabilities=server.get_capabilities(
                notification_options=NotificationOptions(),
                experimental_capabilities={}
            )
        )
    )

if name == “main”:
asyncio.run(main())

但是这是一个思路哈

这种skill 拆分,很好的实现功能获取,功能拆解,功能获取,定制功能的功能

好啦,我们直接到核心的pipeline 6 的伪代码分享吧;

Pipeline 6: 网络搜索并导入知识库

功能说明

进行网络搜索,将搜索结果导入知识库,可选择生成内容。

命令示例

python pipeline_web_search.py --name “搜索结果库” --query “Python教程” --num 10 --output-type PDF
python pipeline_web_search.py --search-only --query “天气”

伪代码流程

步骤 1: 接收参数

  • –name: 知识库名称(必填,如果不使用–search-only)
  • –query: 搜索查询(必填)
  • –num: 搜索结果数量(默认10)
  • –output-type: 输出类型(默认PDF)
  • –query-for-generate: 创作的查询要求(可选)
  • –search-only: 仅搜索不导入(可选)
  • –poll-creation: 等待创作完成(可选)

步骤 2: 网络搜索

  1. 调用API: POST /api/v1/search
  2. 传递参数: query, num
  3. 获取搜索结果列表

步骤 3: 输出搜索结果

  • 打印每个结果: 标题、URL、摘要

步骤 4: 导入知识库(如果不使用–search-only)

如果使用–search-only,跳过此步骤

  1. 创建知识库(如果–name提供):

    • 调用API: POST /api/v1/knowledge/saveCollection
    • 获取collectionId
  2. 导入搜索结果:

    • 遍历搜索结果
    • 调用api_upload上传URL
    • 收集contentId
  3. 轮询解析状态:

    • 循环直到解析完成或超时(300秒)

步骤 5: 生成内容(如果设置–output-type且非–search-only)

  1. 调用submit_creation提交创作任务
  2. 如果设置–poll-creation,轮询创作状态

核心API

api_post, api_upload, poll_parsing, submit_creation, poll_creation
但是通过步骤1-3可以看出其实本skill功能即可实现网络搜索功能,对吧,哈哈哈很有意思
就是容易出现
哈哈哈,这个问题可以等待许愿神灯呀

2 个赞

可以可以,这么快就尝鲜了,但是没太明白为什么要建mcp呢,直接用iflow search skill + iflow-nb skill不是更方便吗

1 个赞

哈哈哈,我在试图补上iflow cli接入第三方api的时候缺少的哪两个功能
web search web fetch。哈哈哈所以建一个mcp,全局使用,不需要每个项目加一次

哦哦,你还没发现这个 https://platform.iflow.cn/

不过你是习惯用硅基流动的搜索嘛~

1 个赞

嘿嘿,其实,我已经注意上了,只是还没有用上 :nerd_face:
我是用硅基流动,但是硅基流动的模型也需要外带搜索工具。 :nerd_face:

扫噶,现在有100积分,可以试用一下,就是平台没完善好。后面我们会做调研,赠送1000积分~

没问题