LlamaIndex 结构化输出

我们和大模型是通过 prompt 进行交互的,我们提示什么,大模型就输出什么。

假如我们要求大模型输出结构化的数据如 JSON,yaml 是不是也可以?

第一个例子

先建一个索引:
from llama_index.core import VectorStoreIndex,SimpleDirectoryReaderdocuments = SimpleDirectoryReader("./data").load_data()
# build index
index = VectorStoreIndex.from_documents(documents)
定义输出格式
from typing import List
from pydantic import BaseModelclass Biography(BaseModel):"""Data model for a biography."""name: strbest_known_for: List[str]extra_info: str
定义一个 query_engine
query_engine = index.as_query_engine(response_mode="tree_summarize", output_cls=Biography
)response = query_engine.query("Who is Paul Graham?")print(response.name)
# > 'Paul Graham'
print(response.best_known_for)
# > ['working on Bel', 'co-founding Viaweb', 'creating the programming language Arc']
print(response.extra_info)
# > "Paul Graham is a computer scientist, entrepreneur, and writer. He is best known      for ..."

从上面的示例可以看出,大模型的检索输出已经是一个自定义的 Biography 类对象。

更复杂的输出结构

大模型对于更复杂的嵌套模型也是能胜任的

from pydantic import BaseModel
from typing import Listfrom llama_index.core.program import LLMTextCompletionProgram
from dotenv import load_dotenv,find_dotenv
load_dotenv(find_dotenv())class Song(BaseModel):"""Data model for a song."""title: strlength_seconds: intclass Album(BaseModel):"""Data model for an album."""name: strartist: strsongs: List[Song]prompt_template_str = """\
从电影中获取一个唱片信息,需要包含作家名和歌曲列表. \
电影 {movie_name}:\
"""
program = LLMTextCompletionProgram.from_defaults(output_cls=Album,prompt_template_str=prompt_template_str,verbose=True,
)output = program(movie_name="功夫")print(output)

输出:

Album(name='Kung Fu Hustle Soundtrack', artist='Various Artists', songs=[Song(title='Kung Fu Fighting', length_seconds=180), Song(title='Zhi Yao Wei Ni Huo Yi Tian', length_seconds=210), Song(title='The Axe Gang', length_seconds=195), Song(title='Sing Sing Sing', length_seconds=240)])
自定义输出转换方式

LlamaIndex 也支持用户自己定义大模型的输出转换方式,由用户自己定义如何对结果进行输出转换,提供了更大的灵活性

# 自定义输出结果
from llama_index.core.output_parsers import ChainableOutputParserclass CustomAlbumOutputParser(ChainableOutputParser):def __init__(self, verbose:bool=False):self.verbose = verbosedef parse(self, output:str) -> Album:if self.verbose:print(f"> Raw output:{output}")lines = output.split('\n')name, artist= lines[0].split(",")songs = []for i in range(1, len(lines)):title, length_seconds = lines[i].split(",")songs.append(Song(title=title, length_seconds=length_seconds))return Album(name=name, artist=artist, songs=songs)prompt_template_str = """\
从电影 {movie_name} 中找出相关的唱片,需要有创作者和歌曲列表 返回的格式如下
第一行包括:
<唱片名>, <唱片作者>
接下来每一行代表一首歌
<歌名>, <歌曲时长(已秒计时)>
"""program = LLMTextCompletionProgram.from_defaults(output_parser=CustomAlbumOutputParser(verbose=True),output_cls=Album,prompt_template_str=prompt_template_str,verbose=True
)
output = program(movie_name="长江七号")print(output)

输出分两部分:

第一部分是我们打开了 verbose=True 时大模型的原始回复

> Raw output:长江七号原声带, 万籁鸣
大江东去, 240
梦想的船, 180
长江之歌, 210
夜色温柔, 195
追梦人, 220

第二部分才是我们的转换后的结果

Album(name='长江七号原声带', artist=' 万籁鸣', songs=[Song(title='大江东去', length_seconds=240), Song(title='梦想的船', length_seconds=180), Song(title='长江之歌', length_seconds=210), Song(title='夜色温柔', length_seconds=195), Song(title='追梦人', length_seconds=220)])
通过 Function Calling 方式

LlamaIndex 提供了 FunctionCallingProgram 来生成结构化的响应。当然使用这个类的前提是大模型需要支持 Function Calling,如果大模型不支持 Function Calling 那就使用 LLMTextCompletionProgram 来完成结构化的输出,两者的原理是不一样的。

当然两者的原理是不一样的,Function Calling 是通过将 Pydantic 对象结构描述作为 tool 来实现的,LLMTextCompletionProgram 则是通过提示词要求大模型返回结构化输出。

from pydantic import BaseModel
from typing import List
from llama_index.llms.openai import OpenAIfrom llama_index.core.program import FunctionCallingProgramclass Song(BaseModel):"""Data model for a song."""title: strlength_seconds: intclass Album(BaseModel):"""Data model for an album."""name: strartist: strsongs: List[Song]prompt_template_str = """\
Generate an example album, with an artist and a list of songs. \
Every song item has title and length_seconds.
Using the movie {movie_name} as inspiration.\
"""
llm = OpenAI(model="gpt-3.5-turbo")program = FunctionCallingProgram.from_defaults(output_cls=Album,prompt_template_str=prompt_template_str,verbose=True,llm=llm
)
output = program(movie_name="The Shining")
print(output)

输出第一部分:

=== Calling Function ===
Calling function: Album with args: {"name": "The Shining Soundtrack", "artist": "Various Artists", "songs": [{"title": "Main Title", "length_seconds": 180}, {"title": "The Overlook Hotel", "length_seconds": 240}, {"title": "Danny's Vision", "length_seconds": 200}, {"title": "Room 237", "length_seconds": 220}, {"title": "Redrum", "length_seconds": 190}, {"title": "The Maze", "length_seconds": 210}, {"title": "Here's Johnny", "length_seconds": 195}]}
=== Function Output ===
name='The Shining Soundtrack' artist='Various Artists' songs=[Song(title='Main Title', length_seconds=180), Song(title='The Overlook Hotel', length_seconds=240), Song(title="Danny's Vision", length_seconds=200), Song(title='Room 237', length_seconds=220), Song(title='Redrum', length_seconds=190), Song(title='The Maze', length_seconds=210), Song(title="Here's Johnny", length_seconds=195)]

输出第二部分:

Album(name='The Shining Soundtrack', artist='Various Artists', songs=[Song(title='Main Title', length_seconds=180), Song(title='The Overlook Hotel', length_seconds=240), Song(title="Danny's Vision", length_seconds=200), Song(title='Room 237', length_seconds=220), Song(title='Redrum', length_seconds=190), Song(title='The Maze', length_seconds=210), Song(title="Here's Johnny", length_seconds=195)])
Function Call 支持批量处理
prompt_template_str = """\
Generate example albums, with an artist and a list of songs, each song has title and length_seconds fields.
Using each movie below as inspiration. \Here are the movies:
{movie_names}
"""
llm = OpenAI(model="gpt-3.5-turbo")program = FunctionCallingProgram.from_defaults(output_cls=Album,prompt_template_str=prompt_template_str,verbose=True,allow_parallel_tool_calls=True,
)
output = program(movie_names="The Shining, The Blair Witch Project, Saw")print(output)

输出第一部分:

=== Calling Function ===
Calling function: Album with args: {"name": "The Shining", "artist": "Wendy Carlos", "songs": [{"title": "Main Title", "length_seconds": 180}, {"title": "Rocky Mountains", "length_seconds": 240}, {"title": "Lontano", "length_seconds": 200}]}
=== Function Output ===
name='The Shining' artist='Wendy Carlos' songs=[Song(title='Main Title', length_seconds=180), Song(title='Rocky Mountains', length_seconds=240), Song(title='Lontano', length_seconds=200)]
=== Calling Function ===
Calling function: Album with args: {"name": "The Blair Witch Project", "artist": "Tony Cora", "songs": [{"title": "The Rustin Parr House", "length_seconds": 150}, {"title": "The Blair Witch Project", "length_seconds": 210}, {"title": "The House in the Woods", "length_seconds": 180}]}
=== Function Output ===
name='The Blair Witch Project' artist='Tony Cora' songs=[Song(title='The Rustin Parr House', length_seconds=150), Song(title='The Blair Witch Project', length_seconds=210), Song(title='The House in the Woods', length_seconds=180)]
=== Calling Function ===
Calling function: Album with args: {"name": "Saw", "artist": "Charlie Clouser", "songs": [{"title": "Hello Zepp", "length_seconds": 220}, {"title": "Bite the Hand That Bleeds", "length_seconds": 190}, {"title": "X Marks the Spot", "length_seconds": 205}]}
=== Function Output ===
name='Saw' artist='Charlie Clouser' songs=[Song(title='Hello Zepp', length_seconds=220), Song(title='Bite the Hand That Bleeds', length_seconds=190), Song(title='X Marks the Spot', length_seconds=205)]

可以看到调了多次 Function Calling

总结:

1.结构化的输出可以通过定义一个 Pydantic 对象

2.可以在 index.as_query_engine 时作为 output_cls 参数输入

3.可以使用 LLMTextCompletionProgram时作为 output_cls 参数输入

4.在使用 LLMTextCompletionProgram 时自定义转化方式

5.在支持 Function Calling 的函数中使用 FunctionCallingProgram

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java实战项目-学生管理系统(附带全套源代码)--《基础篇》

一、前言 第一个java小型学生管理系统&#xff0c;思路和其他语言都一样&#xff0c;因为有C语言的基础&#xff0c;写这个并不是太难&#xff0c;不过&#xff0c;进阶篇的就难太多了。明天晚上更新进阶篇&#xff0c;因为目前代码还没有完善&#xff0c;保守估计需要500行代…

网络请求优化:如何让你的API飞起来

网络请求优化&#xff1a;如何让你的API飞起来 亲爱的开发者朋友们&#xff0c;你是否曾经遇到过这样的场景:用户疯狂点击刷新按钮,你的服务器却像老年人散步一样慢吞吞地响应。或者,你的应用像个贪吃蛇,疯狂吞噬用户的流量包。如果你对这些情况再熟悉不过,那么恭喜你,你正需要…

Unity ColorSpace 之 【颜色空间】相关说明,以及【Linear】颜色校正 【Gamma】的简单整理

Unity ColorSpace 之 【颜色空间】相关说明&#xff0c;以及【Linear】颜色校正 【Gamma】的简单整理 目录 Unity ColorSpace 之 【颜色空间】相关说明&#xff0c;以及【Linear】颜色校正 【Gamma】的简单整理 一、简单介绍 二、在Unity中设置颜色空间 三、Unity中的Gamma…

部队物资仓库出入库管理系统|实现物资有效的战备保障

随着科技的不断发展&#xff0c;智慧营区已成为现代军事管理的重要方向。后勤物资管控作为营区管理的重要组成部分&#xff0c;对于保障营区正常运转和提高部队战斗力具有重要意义。智慧营区后勤物资管控平台作为数字化后勤建设的重要组成部分&#xff0c;能够实现营区物资的智…

Ubuntu下载安装chrome浏览器

方法一&#xff1a;wget下载并安装 1、创建文件夹存安装包 cd /root/Downloads mkdir chrome 2、下载安装包到文件夹内 wget -c https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -P /root/Downloads/chrome 3、安装 cd chrome sudo dpkg -i go…

药品类别功能助力智慧校园医务管理向前迈进

在智慧校园的医务管理框架下&#xff0c;药品类别管理模块发挥着举足轻重的作用&#xff0c;它以智能化的方式优化药品的存储、分配流程&#xff0c;确保每一步都符合安全与效率的标准。这一功能围绕着科学分类的核心理念&#xff0c;细致入微地组织药品信息&#xff0c;为校园…

力扣1963.使字符串平衡的最小交换次数

力扣1963.使字符串平衡的最小交换次数 把所有匹配的消了 剩下的一定是k个‘ [ ’和k个‘ ] ’的组合k为偶数 则res k / 2;k为奇数 则res (k-1)/2 1; class Solution {public:int minSwaps(string s) {int cnt0;for(char c:s){if(c ]){if(cnt > 0) cnt--;}elsecnt;}co…

TCP传输控制协议二

TCP 是 TCP/IP 模型中的传输层一个最核心的协议&#xff0c;不仅如此&#xff0c;在整个 4 层模型中&#xff0c;它都是核心的协议&#xff0c;要不然模型怎么会叫做 TCP/IP 模型呢。 它向下使用网络层的 IP 协议&#xff0c;向上为 FTP、SMTP、POP3、SSH、Telnet、HTTP 等应用…

威纶通触摸屏连接MySQL数据库步骤

目录 概要威纶通支持数据库的触摸屏类型测试Step 1 选择触摸屏型号Step 2 新增数据库服务器Step 3 添加SQL数据库查询功能Step 4 仿真测试 概要 通过使用威纶通带数据库类型的触摸屏&#xff0c;实现连接本地/远程MySQL数据库&#xff0c;并实现数据查询功能 威纶通支持数据库…

Datawhale AI 夏令营_基于术语词典干预的机器翻译挑战赛 .md

基于术语词典干预的机器翻译 在baseline的基础上添加了soft attention&#xff0c;当N2000时&#xff0c;没有问题&#xff0c;但是一旦增加数据量就会爆显存&#xff0c;还需要找一下问题 完整代码如下 from typing import Listimport torch import torch.nn as nn import …

使用harbor作为chart仓库实现内网部署

使用harbor作为chart仓库实现内网部署 制作好的chart包可以传到chart仓库进行共享&#xff0c;chart仓库可以是公有仓库或者使用Harbor搭建的私有仓库。 本文使用的环境信息&#xff1a; rootmaster1:~# kubectl get node NAME STATUS ROLES AGE VERSION…

react antd table拖拽

下载node包 npm install react-resizable -D npm install types/react-resizable --save-dev 定义一个公用组建 ResizableTable.tsx import { useEffect, useState } from "react"; import { Resizable } from "react-resizable"; import "./resize.s…

使用Python + Scrapy + Django构建企业级爬虫平台

引言 在大数据时代&#xff0c;信息就是力量。对于企业而言&#xff0c;掌握行业动态、竞品分析、市场趋势等关键数据&#xff0c;是决策制定的重要依据。然而&#xff0c;手动收集这些信息既费时又低效。因此&#xff0c;自动化数据采集变得至关重要。本文将向你展示如何使用…

专业条码二维码扫描设备和手机二维码扫描软件的区别?

条码二维码技术已广泛应用于我们的日常生活中&#xff0c;从超市结账到公交出行&#xff0c;再到各类活动的入场验证&#xff0c;条码二维码的便捷性不言而喻&#xff0c;而在条码二维码的扫描识别读取过程中&#xff0c;专业扫描读取设备和手机二维码扫描软件成为了两大主要工…

- vuex路由:

vuex vue的状态管理工具(状态就是数据的管理仓库 话语中级语法modules是vuex的高级用法。 react---redux(状态管理工具) vue2--vuex vue3--pinia(小菠萝) 核心概念(是有五个): 1.state:--存放数据 2.getters:计算属性的&#xff0c;通过筛选数组中大于2的&#xff0c;需要…

MySQL表操作(增删改查)

添加字段 ALTER TABLE 表名 ADD 字段名字 类型&#xff08;长度&#xff09;[COMMENT 注释] [自己给当前字段注释命名];修改字段 &#xff08;1&#xff09;仅仅修改指定字段的一些属性&#xff0c;不能重命名 ALTER TABLE 表名 字段名 新数据类型&#xff08;长度);&#x…

ssh升级

文章目录 ssh升级一、解包ssh、ssl二、更新安装ssl三、手动更新手动复制库文件四、创建符号链接五、更新库路径六、验证库文件七、设置库路径环境变量八、配置、编译、安装OpenSSH&#xff1a;意外&#xff1a;缺少 zlib 的开发库解决方法&#xff1a; 九、刷新ssh服务、查看ss…

力扣第九题

回文数 提示&#xff1a; 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 代码展示&#…

用GPT 4o提高效率

**GPT-4o可以通过提高编程效率、优化工作流程、增强文档管理和知识分享等多方面帮助用户提升工作效率**。具体如下&#xff1a; 1. **代码生成与优化** - **快速原型开发**&#xff1a;程序员可以通过向GPT-4o描述需求或功能来生成初步的代码框架或关键函数&#xff0c;从而节省…

TCP流量控制是怎么实现的?

流量控制就是让发送方发送速率不要过快&#xff0c;让接收方来得及接收。利用滑动窗口机制就可以实施流量控制&#xff0c;主要方法就是动态调整发送方和接收方之间数据传输速率。 发送方维护一个窗口&#xff0c;表示可以发送但尚未被确认的数据量。接收方同样维护一个窗口&a…