惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
L
LangChain Blog
Jina AI
Jina AI
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
S
Secure Thoughts
T
The Exploit Database - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 聂微东
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
C
Cyber Attacks, Cyber Crime and Cyber Security
Project Zero
Project Zero
T
Threat Research - Cisco Blogs
量子位
G
GRAHAM CLULEY
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
CERT Recently Published Vulnerability Notes
The Hacker News
The Hacker News
C
Cisco Blogs
Scott Helme
Scott Helme
Spread Privacy
Spread Privacy
宝玉的分享
宝玉的分享
V
V2EX
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
P
Proofpoint News Feed
雷峰网
雷峰网
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Vulnerabilities – Threatpost
PCI Perspectives
PCI Perspectives
博客园_首页
L
LINUX DO - 最新话题
IT之家
IT之家
有赞技术团队
有赞技术团队
博客园 - Franky
Hacker News: Ask HN
Hacker News: Ask HN
Last Week in AI
Last Week in AI
The Cloudflare Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
美团技术团队
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Security Archives - TechRepublic
Security Archives - TechRepublic
L
LINUX DO - 热门话题
AWS News Blog
AWS News Blog
S
Security Affairs
T
Tailwind CSS Blog

XINDOO

关于内卷,几个值得深想的洞察 当创作被 Skill 化:我用 AI 写了一部 320 章的长篇网文 AI第一剑,先斩程序员 AI 也会偷懒?这个 PUA 工具专治“摸鱼式编程” Gstack 深度解析:YC CEO 开源的 AI 工程团队 GitHub Trending霸榜!深度解析AI Coding辅助神器 Superpowers 深度探讨:从 OpenClaw 爆火,看 AI Agent 的真相与程序员的未来 我复刻了NotebookLM的信息图功能 我用AI写了部小说,这里是整个过程 [翻译]我在谷歌14年学到的21堂课 2万字吊打40万字:为什么我的“牛马Agent”比“数字分身”更聪明? 最近AI领域爆火的 Agent Skills 是什么? 从计算机科学的视角来看拖延症 一周改6个库后我悟了:AI时代,程序员正在退化成“甲方” 使用n8n做一个自动同步更新的Github项目问答机器人 Agent设计模式——第 20 章:优先级排序 Agent设计模式——第 1 章:提示词链 Agent设计模式——附录 D - 使用 AgentSpace 构建 Agent Agent设计模式——第 19 章:评估和监控 Agent设计模式——第 10 章:模型上下文协议 (MCP) Agent设计模式——第 21 章:探索和发现 Agent设计模式——智能体设计模式 Agent设计模式——第 11 章:目标设定和监控 Agent设计模式——第 9 章:学习和适应 Agent设计模式——第 16 章:资源感知优化 Agent设计模式——附录 G - 编码 Agent Agent设计模式——第 13 章:人机协同 Agent设计模式——第 17 章:推理技术 Agent设计模式——附录 F - 深入剖析:Agent 推理引擎的内部运作机制 Agent设计模式——章节目录 Agent设计模式—— Agent设计模式——第 7 章:多 Agent 协作 Agent设计模式——附录 E - 命令行界面中的 AI Agent Agent设计模式——附录 C - Agentic 框架快速概览 Agent设计模式——第 3 章:并行化 Agent设计模式——**常见问题解答:Agentic 设计模式** Agent设计模式——第 14 章:知识检索(RAG) Agent设计模式——第 18 章:Guardrails/安全模式 Agent设计模式——第 15 章:Agent 间通信(A2A) Agent设计模式——第 8 章:内存管理 Agent设计模式——第 12 章:异常处理和恢复 Agent设计模式——第 4 章:反思 Agent设计模式——附录 B - AI Agentic 交互:从图形界面到现实世界环境 Agent设计模式——第 5 章:工具使用(函数调用) Agent设计模式——结论 Agent设计模式——第 6 章:规划 Agent设计模式——第 2 章:路由 从经验主义到贝叶斯理论:如何排查线上问题 我用AI为自己造了一把安全的开发者“瑞士军刀”” 从LLM和MCP的协同过程看如何做优化 打通Dify与AI工具生态:将Workflow转为MCP工具的实践 一文了解知识库背后的技术RAG AI应用的五个级别:从入门到专家的进阶之路 一文入门AI圈最近爆火的MCP协议 HTTP/3:性能改进(第 2 部分) deepseek-r1祛魅:从过度热捧到理性认知⁠ 为什么AI智能体需要工作流 如何用GPT-4o解读视频 json命令行处理神器jq介绍 OpenAI的结构化浅析 从大模型的原理到提示词优化 从经济学原理看团队分工合作 [翻译]关于人工智能的30个思考 从马斯洛需求层次理论谈职场激励 知识与智慧 如何使用大语言模型绘制专业图表 两个开源项目打造自己的大模型聚合平台 我让gpt4o给我推荐了一千多次书 得到了这些数据 用Langchain创建一个可以总结网页内容的Agent 推荐一个好用的命令行工具ShellGPT 关于ffmpeg height not divisible by 2的错误 使用Certbot解决https证书自动更新的问题 Spring Cache简明教程 软件开发中的抓大放小vs极致细节思维 OpenAI Assistants-API简明教程 OpenAI的多函数调用(Multiple Function Calling)简介 如何使用ffmpeg制作透明背景的视频 spring-kafka中ContainerProperties.AckMode详解 如何在地图上寻找最密集点的位置? IO密集型服务提升性能的三种方法 职场中的基本归因错误和自利归因 使用javax.validation.constraints校验参数合法性 Java Optional:让你的代码更优雅 如何使用ChatGPT提升自己的“码”力? 使用ffmpeg拼接两张图片 ThreadPoolExecutor——高效处理并发任务的必备良器 从CPU的视角看 多线程代码为什么那么难写! 使用ffmpeg缩小视频体积的几种方式 Linux parallel 命令使用手册 为什么说过早优化是万恶之源? Linux xargs命令介绍 深入理解Spring的事件通知机制 Java高并发之CyclicBarrier简介 聊一聊过度设计! 详解Redisson分布式限流的实现原理 Java中使用HashMap时指定初始化容量性能一定会更好吗? 如何用ffmpeg截取视频片段&截取时间不准确的坑 XINDOO的2022年年终总结 使用ffmpeg将视频转成HLS(m3u8)格式 谷歌Guava LoadingCache介绍
ChatGPT函数调用初体验:让ChatGPT具备抓取网页文本的能力
xindoo · 2023-06-18 · via XINDOO

  OpenAI在6月13号升级了ChatGPT,推出了类似其网页版插件的功能——函数调用(Function calling),13号当天我在很多微信公众号就看到了这个消息,甚至有人将函数调用称为杀手级特性,正好周末有空,就写个Demo试用下,验证下它是平平无奇还是真的能让人眼前一亮。

  官网给出的函数调用示例是接入查询天气的能力,我看到第一反应 就这……。但当我写了一个简单抓取网页文本的函数,并将其接入到ChatGPT中后,我突然意识到这确实是一个非常强大的功能。之前的ChatGPT只能用文本交互,文本有个特点就是其规范性非常非常弱,同样的语义两个不同的人表述出来可能就是完全不同的两句话,导致我们很难用自然语言区控制普通的程序。而这次的函数调用能力,让其具备了输出强规范的内容,可以用来调起其他程序。这也意味着ChatGPT具备了和普通程序交互的能力,可想象的空间非常大。

  接下来我就用我实现的ChatGPT网页分析能力作为示例,演示下如何让ChatGPT接入普通的python函数,最后我再总结下函数调用的能力和局限,顺便也畅想下函数调用到底还可以实现什么样的强大功能。

Step1:实现普通函数

  首先就是要定义好普通的python函数,我这里写了一个简单的网页爬取的功能,给定url就可以抓取到网页上面的文本内容。这里只是一个简单实现,可能部分网页无法正常抓取。

import requests
from bs4 import BeautifulSoup

def is_target_tag(tag):
    target_tags = ['p', 'code', 'h1', 'h2', 'h2', 'h3', 'h4', 'h5']
    return tag.name in target_tags

def get_text_from_url(url):
    response = requests.get(url, headers=headers)
    html = response.text
    soup = BeautifulSoup(html, 'html.parser')
    extracted_tags = soup.find_all(is_target_tag)
    res_text = '' 
    for tag in extracted_tags:
        res_text = res_text + tag.get_text(strip=True) + '\n'
    return res_text

  这里使用的是request包发起请求,使用bs4的BeautifulSoup来解析html标签,代码将html中所有的段落、代码、标题内容都抓取出来。

Step2: 用json-schema格式将函数描述出来

  这一步的作用就是把可以调用的普通函数信息用ChatGPT可以识别的格式描述出来,这里OpenAI直接采用了JSON-Schema。也比较简单,就是描述出来有哪些函数可以用、函数分别实现了什么样的功能、每个函数有哪些参数、哪些是必填参数、哪些是选填参数…… 这里我用来抓取url对应文本的函数描述如下:

functions = [
    {
        "name": "getText",
        "description": "抓取url对应的网页里的文本内容",
        "parameters": {
            "type": "object",
            "properties": {
                "url": {
                    "type": "string",
                    "description": "网址url",
                }
            },
            "required": ["url"],
        },
    }
]

  注意,这里functions可以有不止一个,只要你能准确将函数功能及入参格式用json-schema描述出来,ChatGPT就能给你调起。 另外这里为了方便调起,我们还需要保存一个方法名到实际方法的映射关系,具体如下:

available_functions = {
    "get_text_from_url": get_text_from_url,
} 

Step3: 调用ChatGPT的时候带上函数信息

  接下来我们只需要在原有Api的参数中增加functions,让ChatGPT知晓有哪些函数可以调用,然后让他决定要不要调。完整的代码及注释如下:

import os
import openai
import json
openai.api_key = os.getenv("OPENAI_API_KEY")

def chat(content):
    messages = [
        {"role": "user", "content": content}
    ]
    response1 = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
        functions=functions,
        function_call="auto"
    )
    response_message = response1["choices"][0]["message"]
    rtn_message = response1["choices"][0]["message"]
    # 如果ChatGPT返回结果会告诉你,是否需要调用函数,我们只需要根据它返回的函数名、参数调起对应的函数
    # 然后将函数的返回结果再给到ChatGPT,让他进行下一步的操作  
    if response_message.get("function_call"):
        # 找到需要调用的函数,并将ChatGPT给的参数传进去 
        function_name = response_message["function_call"]["name"]
        fuction_to_call = available_functions[function_name]
        function_args = json.loads(response_message["function_call"]["arguments"])
        # 用这种方式可以调起任意python函数,不用像官网那样还要指定参数名  
        function_response = fuction_to_call(**function_args)
        # 获取到函数调用结果后,需要将结果拼接到对话记录里,并再次调用ChatGPT
        messages.append(response_message) 
        messages.append(
            {
                "role": "function",
                "name": function_name,
                "content": function_response,
            }
        ) 
        # 二次调用的返回结果里就是我们预期的结果了 
        response2 = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=messages,
        )
        rtn_message = response2["choices"][0]["message"]
    return rtn_message['content']

我们简单验证下效果:

chat('总结下这篇文章,将其中的要点提炼出来 https://zxs.io/article/1924')

返回结果如下:

这篇文章总结了使用ChatGPT提升程序员编程能力的方法和场景。作者经过两个月的使用发现,虽然ChatGPT目前还无法完全替代程序员在一些强上下文的编程场景下的能力,但在一些通用化的编程场景下,它的表现仍然可行。作者提炼出以下利用ChatGPT的场景:

1. 代码评审:ChatGPT可以检测代码的语法错误、代码风格问题、潜在的bug和性能问题,但需要注意辅助工具的局限性,建议与其他代码审查工具和人工审查相结合使用。  
2. 代码优化:除了代码评审,ChatGPT还可以帮助优化并重写代码,但同样需要结合其他专业人士的建议进行综合优化。  
3. 代码释义:使用ChatGPT生成代码释义,以减轻维护老代码的负担。  
4. 提供解决方案:描述遇到的问题,让ChatGPT给出建议和解决方案。  
5. 代码生成:ChatGPT可以直接生成相关代码,如分布式锁注解的代码,在实际使用中需要自行甄别和识别生成的代码。  
6. 设计模式和架构建议:ChatGPT可以提供在代码设计和架构设计上的建议。  
7. 学习新知识:在不熟悉的领域使用ChatGPT帮助学习。  

文章提到了一些使用ChatGPT的实例,并强调了在使用过程中需要注意甄别数据的时效性和准确性。最后,作者认为虽然ChatGPT无法替代程序员的大部分技能,但可以作为一个工具来提升工作效率。

  可以看到对于我博客的网址还是非常好用的,我也测试了CSDN、掘金等技术网站,也可以正常使用。但有些网站拿不到结果,不是ChatGPT不行,而是我get_text_from_url方法写的太low了,有些情况下确实没法抓取到内容。

备注:使用函数调用时需要升级最新的openai包,另外目前也只有gpt-3.5-turbo-0613和gpt-4-0613两个模型才支持函数调用,其他模型还不支持。

总结

   不管是从官网查询天气的示例,还是从我这个抓取网页的示例来看,接入函数调用的能力并不复杂。另外需要注意到的一点,虽然这个功能叫函数调用,但ChatGPT并不会帮你去调这些函数,而是帮你判断何时去调用这些函数,给你调用函数所需要的参数,最终肯定得是由你自己去调用函数的。从它的返回数据格式可以看出,当前版本的函数调用还有个局限点,就是当前版本只能在一次对话中调起一个函数,如果遇到那种需要多次调用的操作,就只能通过多轮对话的方式实现了。

   虽然函数调用这个功能看似简单,但我觉得这个功能让ChatGPT拥有了和现有程序打通的能力,以前它只能帮你做决策、给建议,但现在它还可以去帮你执行。举个很实际的例子,现在ChatGPT用的最多的地方就是客服之类的问答场景,现在的系统只能做一些信息交换,比如商品咨询、退换货信息咨询……,但如果接入函数调用功能,用户就可以直接在对话的过程中完成整个流程,这现在是完全可以做到的,不过这个东西刚出来,其决策的可靠性还需要验证,连OpenAI在官网上都提示:

We strongly recommend building in user confirmation flows before taking actions that impact the world on behalf of users (sending an email, posting something online, making a purchase, etc).
我们强烈建议在代表用户采取影响世界的动作(发送电子邮件、在线发布内容、进行购买等)之前,先由用户确认。

  如果你还意识不到函数调用的强大能力,我再举一些简单的例子:如果ChatGPT和你的日历打通,那它是不是就可以帮你管理日程了; 如果和你的笔记打通,那它是不是就可以帮你整理笔记了;甚至是和你的股票账号打通,是不是就可以帮你炒股了;如果和脑机接口打通,那它是不是就可以控制……