
参数提取器可以很方便的从“非结构的自然语言”中,提取出结构化的结果。

下面来看看langchain4j如何实现类似功能:
public static final String TEST_DATA = """金庸(1924年3月10日—2018年10月30日),本名查良镛,浙江省海宁市人,祖籍江西省婺源县浙源乡凤山村 [10] [146-147],1948年移居香港。当代武侠小说作家、新闻学家、企业家、政治评论家、社会活动家,被誉为“香港四大才子”之一,与古龙、梁羽生、温瑞安并称为“中国武侠小说四大宗师”。 [1-4]1944年,考入重庆中央政治大学外交系。1946年秋,进入上海《大公报》任国际电讯翻译。1948年,毕业于上海东吴大学法学院,并被调往《大公报》香港分社 [5]。1952年调入《新晚报》编辑副刊,并写出《绝代佳人》《兰花花》等电影剧本。1959年,金庸等人于香港创办《明报》 [6]。1985年起,历任香港特别行政区基本法起草委员会委员、政治体制小组负责人之一,基本法咨询委员会执行委员会委员,以及香港特别行政区筹备委员会委员。1994年,受聘北京大学名誉教授 [7]。2000年,获得大紫荆勋章。2007年,出任香港中文大学文学院荣誉教授 [5]。2009年9月,被聘为中国作协第七届全国委员会名誉副主席 [8];同年荣获2008影响世界华人终身成就奖 [9]。2010年,获得剑桥大学哲学博士学位 [2]。"2018年10月30日,在香港逝世,享年94岁。""";@GetMapping(value = "/extract", produces = MediaType.APPLICATION_JSON_VALUE)public ResponseEntity<String> extract() {try {Prompt prompt = PromptTemplate.from("请从以下生平介绍中,提取出该人物的基本信息,以json格式输出,参考格式:{{json_output_sample}} \n{{test_data}}").apply(Map.of("json_output_sample", "{\"name\":\"张三\",\"age\":10,\"birthDay\":\"2000-01-01\",\"isAlive\":false,\"deathDate\":\"2040-02-01\",\"degree\":\"本科\"}","test_data", TEST_DATA));String text = ollamaChatModel.chat(prompt.toUserMessage()).aiMessage().text();return ResponseEntity.ok(text);} catch (Exception e) {log.error("extract", e);return ResponseEntity.ok("{\"error\":\"extract error: " + e.getMessage() + "\"}");}}
代码很简单,直接在prompt提示词里,告诉LLM怎么做就行,输出结果:

不过,这个输出结果是个string,还不能算是结构化的输出,可以再改进一下:
/*** Person 记录类,用于表示一个人的基本信息* 使用 Java record 类型实现,自动生成构造函数、getter 方法、equals()、hashCode() 和 toString() 方法** @param name 人的姓名* @param age 人的年龄* @param birthDay 人的出生日期* @param isAlive 人是否仍然活着* @param deathDate 人的死亡日期(如果已故)* @param degree 人的学位*/record Person(String name, int age, Date birthDay, boolean isAlive, Date deathDate, String degree) {// 这是一个记录类声明,包含了表示个人基本信息的数据字段// 所有字段都是 final 的,且自动生成对应的访问器方法}/*** 人员信息提取接口* 该接口定义了一个从生平介绍中提取人员信息的方法*/interface PersonExtractor {/*** 从生平介绍中提取人员主要信息** @param biography 人员的生平介绍文本* @return 包含提取信息的Person对象*/@SystemMessage("""你的任务是从生平介绍中,提取出该人的主要信息:name[姓名],age[年龄], birthDay[出生日期], isAlive[是否健在], deathDate[死亡日期(如果已逝世)], degree[最高学历]""")Person extractPerson(String biography);}/*** 处理GET请求,提取人员信息并以JSON格式返回** @return 返回包含提取的人员信息的ResponseEntity对象*/@GetMapping(value = "/extract2", produces = MediaType.APPLICATION_JSON_VALUE)public ResponseEntity<Person> extract2() {try {// 创建PersonExtractor实例,使用AiServices和ollamaChatModelPersonExtractor personExtractor = AiServices.create(PersonExtractor.class, ollamaChatModel);// 使用TEST_DATA调用extractPerson方法提取人员信息Person person = personExtractor.extractPerson(TEST_DATA);// 返回成功响应,包含提取的人员信息return ResponseEntity.ok(person);} catch (Exception e) {// 捕获异常并记录错误日志log.error("extract2", e);// 发生异常时返回默认的Person对象return ResponseEntity.ok(new Person("", -1, null, false, null, ""));}}
这里我们用抽象级别更高的AiService来创建指定的抽取器,一步到位的输出了对象实例

本文示例完整代码:GitHub - yjmyzz/langchain4j-study at day06