我们以上一篇为基础《备忘: 使用langchain结合千问大模型,用本地知识库辅助AI生成代码》 ,建立一个完整的AI应用,具备按用户输入的问题,匹配本地数据库预设需求,然后转发给AI(千问)生成代码,然后提取代码进行自动测试,如果测试成功,则根据代码再使用AI(千问)生成文件名,保存代码到预设仓库,其流程如下(典型的Rag流程):
主要工具:
本地库用的向量持久化工具: ES 7.9
本地库匹配使用的embedding: 抱脸虫HuggingFaceEmbeddings的paraphrase-multilingual-MiniLM-L12-v2
LLM 还是选qwen-max
本地库内容还是4个akshare接口
- 获得上海证券交易所股票数据总貌,包括项目、股票、科创版、主板,可以使用akshare库的stock_sse_summary接口,无入参,返回最近交易日的股票数据总貌,包括流通股本、总市值、平均市盈率、上市公司、上市股票、流通市值、报告时间、总股本,返回字段使用中文,最后用print方法打印行情,代码格式为python…
- 获得股票个股信息,包括总市值、流通市值、行业、上市时间、股票代码、股票简称、总股本、流通股,可以使用akshare库的stock_individual_info_em接口按股票代码查询,获得相关股票个股信息,返回字段使用中文,最后用print方法打印行情,代码格式为python…
- 获取股票最新价格、最新成交量、最新涨跌幅、最新换手率,可以使用akshare库的stock_zh_a_spot_em接口获取全市场行情,无入参,再按股票名称或者股票代码过滤获得信息,返回字段使用中文,最后用print方法打印行情,代码格式为python…
- 获得股票历史行情,包括指定交易日的最高价、最低价、开盘价、收盘价、成交量、涨跌幅、换手率,可以使用akshare库,按stock_zh_a_hist接口按股票代码,获取指定日线数据,startdate和enddate,以及指定前复权,获得日线数据,返回字段使用中文,最后用print方法打印行情,代码格式为python… (行分隔符)
建本地库和依赖本地匹配需求,参考上一篇 《备忘: 使用langchain结合千问大模型,用本地知识库辅助AI生成代码》
我们把依赖于LM生成代码,根据代码自动获取文件名,以及自动测试,保存文件统一到一个工具类Assistant类
import ...
dashscope.api_key
CONTEXT_QA_TMPL = """
下面的信息({summary_prompt})是否有这个问题({message})有关,
如果你觉得无关请告诉我无法根据提供的上下文回答'{message}'这个问题,简要回答即可,
否则请根据{summary_prompt}对{message}的问题进行回答
"""
CONTEXT_QA_PROMPT = PromptTemplate(
input_variables=["summary_prompt", "message"],
template=CONTEXT_QA_TMPL,
)
# 新增LLM助手
class Assistant:
def __init__(self, llm: BaseLLM):
self.llm = llm # LLM
self.used_code = ""
self.python_path = "/home/cfets/gitea/pyWebTest1/pythonRepository/"
CONTEXT_QA_TMPL = """
下面的信息({summary_prompt})是否有这个问题({message})有关,
如果你觉得无关请告诉我无法根据提供的上下文回答'{message}'这个问题,简要回答即可,
否则请根据{summary_prompt}对{message}的问题进行回答
"""
self.CONTEXT_QA_PROMPT = PromptTemplate(
input_variables=["summary_prompt", "message"],
template=CONTEXT_QA_TMPL,
)
# 生成代码
def genCode(self, message: str, summary_prompt: str):
prompt = CONTEXT_QA_PROMPT.format(summary_prompt=summary_prompt, message=message)
print('prompt::', prompt)
print('\n')
raw_code = llm(prompt)
print('raw_code::', raw_code)
print('\n')
return raw_code
# 提取并执行代码列表
def py_repl_tool_list(self, code: str):
py_repl = PythonREPL()
result = {
}
realcode_list = re.findall(r'```python(.*?)```', code, re.DOTALL)
for i in range(len(realcode_list)):
# 执行
res = py_repl.run(realcode_list[i])
# 判断执行结果,如果成功,则保存代码,如果不成功,不保存
result[i] = py_repl.run(realcode_list[i])
if "Error" not in result[i]:
print('执行成功')
self.saveCode(realcode_list[i])
else:
print('执行失败 错误信息:', result[i])
return result
# 自动保存
def saveCode(self, code: str):
file_name = self.python_path + self.getFileName(code)
try:
if not os.path.exists(file_name):
with open(file_name, 'w') as f:
f.write(code)
print('文件保存成功')
else:
print('文件已存在')
version = random.randint(1, 100)
file_name = file_name.split(".py")[0] + str(version) + ".py"
with open(file_name, 'w')