当前位置: 首页 > news >正文

从零开始的Agent学习(二)-增加文档输出功能

背景

        继上次完成一个简单的聊天机器人之后,小H就在想该如何增加功能或者是环节,看到平常常用的cursor和kiro,能够修改代码的功能真的好厉害吧,不过一时间应该还没法完成这么高难度的东西,但是修改代码本质来看就是编辑文件嘛,所以打算试着从将LLM返回的结果输出到一个文件中来下手。

整体架构

        增加一个Doc类,用来完成工具类的具体实现;

        给出方法函数,利用Langchain工具包装

        修改提示词,提示大模型可以进行调用改工具

        同时对上次的项目结构进行修正,将工具类放到同一个地方去。

project
├── tools         # 工具类
│   ├── __init__.py     # 模块初始化
│   ├── document_exporter.py        # 文档输出工具类
│   └── MessageManager.py # 上下文整理类
├── .venv   # 虚拟环境
└── langgraph_chat.py      # 主要运行类

DocumentExporter

依赖

import os
import re
from datetime import datetime
from typing import Optional, Dict, Any
from langchain.tools import Tool

初始化

        对于工具类,我们希望他初始化的时候只要设定自己的输出路径就可以了,然后后面我们用函数再增加传入的内容。

def __init__(self, output_dir: str = "exports"):self.output_dir = output_dirself._ensure_output_dir()  # 确保目录存在
def _ensure_output_dir(self):"""确保输出目录存在"""if not os.path.exists(self.output_dir):os.makedirs(self.output_dir)

MD内容搭建

        这里提供了一份MD输出的格式输出,实际上只要稍微改动一些根据其他文件的输出方式就可以输出成其他文件,只依赖文件路径输入其实不会有影响的,只要修改本次内容中对应的文件名修饰的部分就可以了。

def _build_markdown_content(self, content: str, title: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> str:"""构建 Markdown 内容"""lines = []# 标题if title:lines.append(f"# {title}")lines.append("")# 元数据if metadata:lines.append("## 文档信息")lines.append("")for key, value in metadata.items():lines.append(f"- **{key}**: {value}")lines.append("")# 生成信息lines.append("## 生成信息")lines.append("")lines.append(f"- **生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")lines.append(f"- **生成工具**: LangGraph 聊天机器人")lines.append("")# 主要内容lines.append("## 内容")lines.append("")lines.append(content)return "\n".join(lines)

        主要就是依据固定格式进行添加内容,配合下面的导出方法,如果有没看到的辅助方法,文章结尾全部代码里面可以找到的。

   def export_to_markdown(self, content: str, title: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> str:"""导出内容到 Markdown 文件Args:content: 要导出的内容title: 文档标题(可选)metadata: 元数据信息(可选)Returns:str: 生成的文件路径"""filename = self._generate_filename(title)filepath = os.path.join(self.output_dir, filename)# 构建 Markdown 内容md_content = self._build_markdown_content(content, title, metadata)# 写入文件try:with open(filepath, 'w', encoding='utf-8') as f:f.write(md_content)return f"✅ 文档已成功导出到: {filepath}"except Exception as e:return f"❌ 文档导出失败: {str(e)}"

        为了能够让LLM使用,我们需要提供一个函数接口,这里使用的是LangChain的Tool来做工具集成,Tool是LangChain框架提供的一个类,用于封装可执行的工具函数。那么里面应该包括一个实例化的对象,同时还要有对应的方法去调用我们刚才说到的导出文档的方法。

        Tool中含有三个核心参数,name代表的是工具的唯一标识符、AI 在决定使用哪个工具时会看到这个名称;description就是描述这个工具的作用、输入输出等内容,更有利于大模型判断是否使用;func参数,就是实际调用的参数。

def create_document_export_tool() -> Tool:"""创建文档导出工具"""exporter = DocumentExporter()def export_document(input_str: str) -> str:"""导出文档工具函数输入格式: "标题|内容" 或者直接是内容"""try:# 解析输入if "|" in input_str:parts = input_str.split("|", 1)title = parts[0].strip()content = parts[1].strip()else:title = Nonecontent = input_str.strip()# 添加一些元数据metadata = {"内容长度": f"{len(content)} 字符","内容类型": "AI 生成内容"}return exporter.export_to_markdown(content, title, metadata)except Exception as e:return f"❌ 文档导出工具执行失败: {str(e)}"return Tool(name="export_document",description="""将内容导出为 Markdown 文档。使用场景:当用户要求将信息保存到文档、整理到文件、导出报告等时使用。输入格式:1. 只有内容:"这是要导出的内容"2. 标题和内容:"文档标题|这是要导出的内容"示例:- "明天天气预报|明天北京天气晴朗,温度15-25度"- "市场调研报告|根据搜索结果,当前市场趋势..."""",func=export_document)

        实际使用的话,我们只要在这里的tools加上这个create···tool返回的结果, 然后在一开始的提示词中添加对应的工具内容,后面就可以交给大模型自主判断了。

结果

代码

"""
文档导出工具
用于将对话内容和搜索结果导出为 Markdown 格式文档
"""import os
import re
from datetime import datetime
from typing import Optional, Dict, Any
from langchain.tools import Toolclass DocumentExporter:"""文档导出器类"""def __init__(self, output_dir: str = "exports"):"""初始化文档导出器Args:output_dir: 输出目录,默认为 'exports'"""self.output_dir = output_dirself._ensure_output_dir()def _ensure_output_dir(self):"""确保输出目录存在"""if not os.path.exists(self.output_dir):os.makedirs(self.output_dir)def _sanitize_filename(self, filename: str) -> str:"""清理文件名,移除不合法字符"""# 移除或替换不合法字符filename = re.sub(r'[<>:"/\\|?*]', '_', filename)# 限制长度if len(filename) > 100:filename = filename[:100]return filenamedef _generate_filename(self, title: Optional[str] = None) -> str:"""生成文件名"""timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")if title:clean_title = self._sanitize_filename(title)return f"{timestamp}_{clean_title}.md"else:return f"document_{timestamp}.md"def export_to_markdown(self, content: str, title: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> str:"""导出内容到 Markdown 文件Args:content: 要导出的内容title: 文档标题(可选)metadata: 元数据信息(可选)Returns:str: 生成的文件路径"""filename = self._generate_filename(title)filepath = os.path.join(self.output_dir, filename)# 构建 Markdown 内容md_content = self._build_markdown_content(content, title, metadata)# 写入文件try:with open(filepath, 'w', encoding='utf-8') as f:f.write(md_content)return f"✅ 文档已成功导出到: {filepath}"except Exception as e:return f"❌ 文档导出失败: {str(e)}"def _build_markdown_content(self, content: str, title: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None) -> str:"""构建 Markdown 内容"""lines = []# 添加标题if title:lines.append(f"# {title}")lines.append("")# 添加元数据if metadata:lines.append("## 文档信息")lines.append("")for key, value in metadata.items():lines.append(f"- **{key}**: {value}")lines.append("")# 添加生成时间lines.append("## 生成信息")lines.append("")lines.append(f"- **生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")lines.append(f"- **生成工具**: LangGraph 聊天机器人")lines.append("")# 添加主要内容lines.append("## 内容")lines.append("")lines.append(content)return "\n".join(lines)def create_document_export_tool() -> Tool:"""创建文档导出工具"""exporter = DocumentExporter()def export_document(input_str: str) -> str:"""导出文档工具函数输入格式: "标题|内容" 或者直接是内容"""try:# 解析输入if "|" in input_str:parts = input_str.split("|", 1)title = parts[0].strip()content = parts[1].strip()else:title = Nonecontent = input_str.strip()# 添加一些元数据metadata = {"内容长度": f"{len(content)} 字符","内容类型": "AI 生成内容"}return exporter.export_to_markdown(content, title, metadata)except Exception as e:return f"❌ 文档导出工具执行失败: {str(e)}"return Tool(name="export_document",description="""将内容导出为 Markdown 文档。使用场景:当用户要求将信息保存到文档、整理到文件、导出报告等时使用。输入格式:1. 只有内容:"这是要导出的内容"2. 标题和内容:"文档标题|这是要导出的内容"示例:- "明天天气预报|明天北京天气晴朗,温度15-25度"- "市场调研报告|根据搜索结果,当前市场趋势..."""",func=export_document)# 为了方便直接使用
def export_to_markdown(content: str, title: Optional[str] = None) -> str:"""便捷函数:直接导出内容到 Markdown"""exporter = DocumentExporter()return exporter.export_to_markdown(content, title)if __name__ == "__main__":# 测试代码print("测试文档导出工具...")# 创建工具tool = create_document_export_tool()# 测试1: 只有内容result1 = tool.func("这是一个测试文档的内容,包含了一些重要信息。")print(f"测试1结果: {result1}")# 测试2: 标题和内容result2 = tool.func("天气预报|明天北京天气晴朗,气温15-25摄氏度,适合外出活动。")print(f"测试2结果: {result2}")print("测试完成!")

结语

        小H的agent已经可以输出文件了,那么查看文件等功能也应该跟上了,或者还有什么东西可以加上呢?

http://www.dtcms.com/a/342949.html

相关文章:

  • 医疗信创新征程:常德二院全栈国产化项目引领行业变革
  • 审美积累 | 界面设计拆分 | Redesign Health - Services 医疗页面设计
  • 8.21网络编程——词典(未完成,有问题)
  • kotlin协程笔记-朱凯
  • C# 基本数据类型
  • 生信分析自学攻略 | R语言数据筛选和修改
  • 前端:文件直接在浏览器里下载
  • VMware ESXi 服务器暴露高危漏洞,中国1700余台面临勒索软件威胁
  • UE 虚幻引擎, unreal engine(1)概略介绍,安装本引擎,创建账户,打开 UE,创建项目,项目导入内容,尝试运行的添加第一人称游戏,
  • Vibe Coding v.s Prompt Engineering
  • 【Docker】在Ubuntu22.04上安装Docker
  • 漫谈《数字图像处理》之平滑
  • 智能编码工具:GitHub Copilot 的深度应用与集成
  • 用OpencvSharp编写视频录制工具
  • HTTP/2 性能提升的核心原因
  • Vue2 ElementUI Upload组件http-request用法
  • (二十一)深入了解AVFoundation-编辑:导出视频与格式转换的全流程
  • 全文 part1 - DGEMM Using Tensor Cores, and Its Accurate and Reproducible Versions
  • DeepSeek-V3.1 发布,迈向 Agent 时代的第一步
  • 0821 sqlite3_get_table函数(数据库函数的补充)
  • Nacos-9--认识Nacos中的Distro协议(Nacos高可用的实现原理)
  • visual studio编译的软件查找所依赖的运行库方法
  • 基于单片机智能路灯控制
  • 学习嵌入式第三十四天
  • 杂记 07
  • BGP高级特性
  • AI论文速读 | 多模态能否助力时间序列预测?时序预测中融合文本的边界与条件
  • Oracle CLOB类型转换
  • 数据分析三剑客
  • 如何解读京东按图搜索(拍立淘)API(jd.item_search_img)的返回值