当前位置:   article > 正文

备忘: 使用langchain结合千问大模型,用本地知识库辅助AI生成代码_langchain tongyi qwen-max

langchain tongyi qwen-max

本文主要是寻求解决把预先准备的文字需求转换为代码的方法
主要思路: 把某一类文字需求储存到本地知识库,使得用户输入需求目标,然后程序自动从知识库抽取相关需求,然后转发给在线的大模型形成代码。
工具:
本地在库用的向量持久化工具: 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())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

注意这里是按行切分

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

需要说明的是,之前的文章中利用了向量相似度的做法判断本地知识库是否准确,但是相似度的值很难把握,这里换了个做法,利用大模型本身的比较成熟判断,直接询问大模型,已经找到的本地知识(本文因为知识库较小,要求最相似的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("未找到该股票信息")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

这段代码首先使用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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

获取股票个股信息

# 假设我们查询股票代码为"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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这段代码首先导入了akshare库,并使用了stock_sse_summary接口来获取上海证券交易所的股票数据总貌,然后展示了包含流通股本、总市值等信息的数据框。接着,通过指定一个股票代码(例如"600000"),利用stock_individual_info_em接口获取该股票的详细信息,包括总市值、流通市值等行业相关数据,并打印出来。这正好满足了提出的需求。



生成的代码第一段ak.stock_sse_summary() 比较靠谱,后一段稍微超出了预期,可以修正参数后使用,也可以选择不使用


基本达到了依赖本地库辅助AI生成代码的目标
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号