本文主要是寻求解决把预先准备的文字需求转换为代码的方法
主要思路: 把某一类文字需求储存到本地知识库,使得用户输入需求目标,然后程序自动从知识库抽取相关需求,然后转发给在线的大模型形成代码。
工具:
本地在库用的向量持久化工具: ES 7.9
本地库提取所需的预训练模型: 抱脸虫HuggingFaceEmbeddings的paraphrase-multilingual-MiniLM-L12-v2
在线大模型还是选qwen-max
本地知识库的建设,不再赘述,参考之前的文章: 备忘,LangChain建立本地知识库的几个要点
包括参考资料 LangChain结合通义千问的自建知识库
由于需要用到流式输出(streaming=true),需要解决langchain整合qwen大模型关于流式输出的bug,可以参考 通义千问自己的例子
以及相关链接: https://github.com/langchain-ai/langchain/pull/16605
我选的解决方案:
本地库的设计:
参考akshare库的股票数据文档 AKShare股票数据
选了4个接口: stock_sse_summary,stock_individual_info_em , stock_zh_a_spot_em, stock_zh_a_hist 补充简单逻辑、入参和出参,完成本地知识库的akshareKnowledge.txt文件
获得上海证券交易所股票数据总貌,包括项目、股票、科创版、主板,可以使用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...
(行分隔符)
代码分为两部分
1 建本地库
import ...
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import ElasticVectorSearch
# 自定义切分
class Document:
def __init__(self, text):
self.page_content = text
self.metadata = {'source': 'Own'}
time_list = []
t = time.time()
base_file = '/home/cfets/AI/textwarefare/akshareKnowledge.txt'
# base_file = '/home/cfets/AI/textwarefare/cff.txt'
my_index = "es_akshare-api-new"
with open(base_file, 'r', encoding='utf-8') as file:
lines = file.readlines()
split_docs = [Document(line.strip()) for line in lines]
model_name = r"/home/cfets/AI/model/paraphrase-multilingual-MiniLM-L12-v2"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': False}
embeddings = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs)
# 使用ES
db = ElasticVectorSearch.from_documents(
split_docs,
embeddings,
elasticsearch_url="http://localhost:9200",
index_name=my_index
)
print(db.client.info())
注意这里是按行切分
ES本地库的索引如下
应用本地库的部分
from langchain_community.llms import Tongyi
import os
import dashscope
from langchain.prompts import PromptTemplate
from langchain_community.vectorstores import ElasticVectorSearch
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings
dashscope.api_key = xxx...
CONTEXT_QA_TMPL = """
下面的信息({summary_prompt})是否有这个问题({message})有关,
如果你觉得无关请告诉我无法根据提供的上下文回答'{message}'这个问题,简要回答即可,
否则请根据{summary_prompt}对{message}的问题进行回答
"""
CONTEXT_QA_PROMPT = PromptTemplate(
input_variables=["summary_prompt", "message"],
template=CONTEXT_QA_TMPL,
)
if __name__ == '__main__':
os.environ["DASHSCOPE_API_KEY"] = dashscope.api_key
llm = Tongyi(model_name="qwen-max", streaming=True, temperature=0)
# 引入模型
model_name = r"/home/cfets/AI/model/paraphrase-multilingual-MiniLM-L12-v2"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': False}
embeddings = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
# 使用elastic search
my_index = "es_akshare-api-new"
# 本地库
db = ElasticVectorSearch(
embedding=embeddings,
elasticsearch_url="http://localhost:9200",
index_name=my_index,
)
while True:
try:
user_input = input("请输入您的问题:")
similarDocs = db.similarity_search(user_input, k=2)
summary_prompt = "".join([doc.page_content for doc in similarDocs]) # 找到最接近的描述doc
# print('summary_prompt:: %s' % summary_prompt)
prompt = CONTEXT_QA_PROMPT.format(summary_prompt=summary_prompt, message=user_input)
print('prompt::', prompt)
print('\n')
print('answer::', llm(prompt))
print('\n')
except KeyboardInterrupt:
break
需要说明的是,之前的文章中利用了向量相似度的做法判断本地知识库是否准确,但是相似度的值很难把握,这里换了个做法,利用大模型本身的比较成熟判断,直接询问大模型,已经找到的本地知识(本文因为知识库较小,要求最相似的2条知识即可)和需要解决的问题是否相关,如果相关,则按本地知识库给出解释,如果不相关则由大模型给出回答,相关问题模板,参考CONTEXT_QA_TMPL和CONTEXT_QA_PROMPT
我们看运行结果:
问题1: 给出获取A股股票最新市场价的代码
请输入您的问题:给出获取A股股票最新市场价的代码
prompt::
下面的信息(获取股票最新价格、最新成交量、最新涨跌幅、最新换手率,可以使用akshare库的stock_zh_a_spot_em接口获取全市场行情,无入参,再按股票名称或者股票代码过滤获得信息,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```获得股票历史行情,包括指定交易日的最高价、最低价、开盘价、收盘价、成交量、涨跌幅、换手率,可以使用akshare库,按stock_zh_a_hist接口按股票代码,获取指定日线数据,startdate和enddate,以及指定前复权,获得日线数据,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```)是否有这个问题(给出获取A股股票最新市场价的代码)有关,
如果你觉得无关请告诉我无法根据提供的上下文回答'给出获取A股股票最新市场价的代码'这个问题,简要回答即可,
否则请根据获取股票最新价格、最新成交量、最新涨跌幅、最新换手率,可以使用akshare库的stock_zh_a_spot_em接口获取全市场行情,无入参,再按股票名称或者股票代码过滤获得信息,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```获得股票历史行情,包括指定交易日的最高价、最低价、开盘价、收盘价、成交量、涨跌幅、换手率,可以使用akshare库,按stock_zh_a_hist接口按股票代码,获取指定日线数据,startdate和enddate,以及指定前复权,获得日线数据,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```对给出获取A股股票最新市场价的代码的问题进行回答
/home/cfets/.local/lib/python3.10/site-packages/langchain_core/_api/deprecation.py:117: LangChainDeprecationWarning: The function `__call__` was deprecated in LangChain 0.1.7 and will be removed in 0.2.0. Use invoke instead.
warn_deprecated(
answer:: 有关。根据提供的上下文,我可以给出获取A股股票最新市场价的代码示例:
```python
import akshare as ak
# 获取全市场A股实时行情
stock_spot_df = ak.stock_zh_a_spot_em()
# 假设我们要查询股票代码为"600519"(贵州茅台)的最新市场价
stock_code = "600519"
stock_info = stock_spot_df[stock_spot_df["股票代码"] == stock_code]
# 打印股票名称和最新市场价
if not stock_info.empty:
print(f"{stock_info['股票名称'].values[0]}的最新市场价为:{stock_info['最新价'].values[0]}元")
else:
print("未找到该股票信息")
这段代码首先使用akshare
库的stock_zh_a_spot_em
接口获取了全市场的A股实时行情,然后通过股票代码筛选出特定股票的信息,并打印出该股票的最新市场价。
解释一下过程,我在代码中把提示模板prompt打印出来,可以看到代码获取了本地库的两个最接近的接口 stock_zh_a_spot_em 和 stock_zh_a_hist 以及相关逻辑,然后判断stock_zh_a_spot_em相关的逻辑与问题有关 再用stock_zh_a_spot_em相关逻辑 生成代码,这个代码还是相对靠谱
问题2 获得上海证交所最新股票数据的代码
请输入您的问题:获得上海证交所最新股票数据的代码
prompt::
下面的信息(获得上海证券交易所股票数据总貌,包括项目、股票、科创版、主板,可以使用akshare库的stock_sse_summary接口,无入参,返回最近交易日的股票数据总貌,包括流通股本、总市值、平均市盈率、上市公司、上市股票、流通市值、报告时间、总股本,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```获得股票个股信息,包括总市值、流通市值、行业、上市时间、股票代码、股票简称、总股本、流通股,可以使用akshare库的stock_individual_info_em接口按股票代码查询,获得相关股票个股信息,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```)是否有这个问题(获得上海证交所最新股票数据的代码)有关,
如果你觉得无关请告诉我无法根据提供的上下文回答'获得上海证交所最新股票数据的代码'这个问题,简要回答即可,
否则请根据获得上海证券交易所股票数据总貌,包括项目、股票、科创版、主板,可以使用akshare库的stock_sse_summary接口,无入参,返回最近交易日的股票数据总貌,包括流通股本、总市值、平均市盈率、上市公司、上市股票、流通市值、报告时间、总股本,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```获得股票个股信息,包括总市值、流通市值、行业、上市时间、股票代码、股票简称、总股本、流通股,可以使用akshare库的stock_individual_info_em接口按股票代码查询,获得相关股票个股信息,返回字段使用中文,最后用print方法打印行情,代码格式为```python...```对获得上海证交所最新股票数据的代码的问题进行回答
answer:: 有关。根据提供的上下文,可以构建获取上海证券交易所最新股票数据的代码示例。这里分为两部分:第一部分是获取股票数据总貌,第二部分是获取股票个股信息。以下是相应的Python代码示例:
### 获取上海证券交易所股票数据总貌
```python
import akshare as ak
# 使用stock_sse_summary接口获取上交所股票数据总貌
stock_summary_df = ak.stock_sse_summary()
print("上海证券交易所股票数据总貌:")
print(stock_summary_df)
获取股票个股信息
# 假设我们查询股票代码为"600000"的股票信息
stock_code = "600000"
# 使用stock_individual_info_em接口按股票代码查询
individual_stock_info_df = ak.stock_individual_info_em(stock_code)
print(f"{stock_code} 的股票个股信息:")
print(individual_stock_info_df)
这段代码首先导入了akshare
库,并使用了stock_sse_summary
接口来获取上海证券交易所的股票数据总貌,然后展示了包含流通股本、总市值等信息的数据框。接着,通过指定一个股票代码(例如"600000"),利用stock_individual_info_em
接口获取该股票的详细信息,包括总市值、流通市值等行业相关数据,并打印出来。这正好满足了提出的需求。
生成的代码第一段ak.stock_sse_summary() 比较靠谱,后一段稍微超出了预期,可以修正参数后使用,也可以选择不使用
基本达到了依赖本地库辅助AI生成代码的目标