Jelajahi Sumber

调整-备份

zhengkun 6 bulan lalu
induk
melakukan
59dd6187a7
14 mengubah file dengan 555 tambahan dan 45 penghapusan
  1. 247 0
      ai/ai_deekseek.go
  2. 20 4
      clean/c_all.go
  3. 26 1
      clean/c_money.go
  4. 3 3
      config.json
  5. 6 6
      extract/extract.go
  6. 1 2
      extract/test.go
  7. 167 1
      main.go
  8. 8 2
      prompt/prompt_buyer.go
  9. 12 2
      prompt/prompt_class.go
  10. 34 10
      prompt/prompt_field.go
  11. 18 5
      prompt/prompt_package.go
  12. 8 8
      tool.json
  13. 1 0
      ul/attr.go
  14. 4 1
      ul/init.go

+ 247 - 0
ai/ai_deekseek.go

@@ -0,0 +1,247 @@
+package ai
+
+import (
+	"bytes"
+	"data_ai/ul"
+	"encoding/json"
+	log "github.com/donnie4w/go-logger/logger"
+	"io/ioutil"
+	qu "jygit.jydev.jianyu360.cn/data_processing/common_utils"
+	"net/http"
+	"strings"
+	"time"
+)
+
+var req_retry_deepseek = 1
+
+// 通用外围
+func PostDeepSeekAI(content string) map[string]interface{} {
+	// API的URL
+	apiURL := "https://api.deepseek.com/chat/completions"
+	// 构造请求数据
+	messages := []map[string]interface{}{}
+	messages = append(messages, map[string]interface{}{
+		"role":    "user",
+		"content": content,
+	})
+	//glm-4-air	glm-4-0520  glm-4-flash
+	requestData := map[string]interface{}{
+		"model":    "deepseek-chat",
+		"messages": messages,
+	}
+	jsonData, _ := json.Marshal(requestData)
+	// 创建HTTP请求
+	req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
+	if err != nil {
+		log.Debug("Error: %s", err)
+		return map[string]interface{}{}
+	}
+	// 设置请求头
+	req.Header.Add("Content-Type", "application/json")
+	req.Header.Add("Accept", "application/json")
+	req.Header.Add("Authorization", "Bearer sk-832c259e371743a0bb7b280cb86ad806")
+
+	client := &http.Client{}
+	client.Timeout = 120 * time.Second
+	resp, err := client.Do(req)
+	if err != nil {
+		return map[string]interface{}{}
+	}
+	defer resp.Body.Close()
+
+	// 解析响应
+	body, _ := ioutil.ReadAll(resp.Body)
+	res := make(map[string]interface{})
+	json.Unmarshal(body, &res)
+	if res != nil {
+		if choices := ul.IsMarkInterfaceMap(res["choices"]); len(choices) > 0 {
+			if message := qu.ObjToMap(choices[0]["message"]); message != nil {
+				result := qu.ObjToString((*message)["content"])
+				result = ul.Escape.ReplaceAllString(result, "")
+				if new_result := ul.SaveResultReg.FindString(result); new_result != "" {
+					result = new_result
+				}
+				dict := make(map[string]interface{})
+				json.Unmarshal([]byte(result), &dict)
+				return dict
+			}
+		}
+	}
+	return map[string]interface{}{}
+}
+
+// 分类字段
+func PostClassDeepSeekAI(content string) map[string]interface{} {
+	// API的URL
+	apiURL := "https://api.deepseek.com/chat/completions"
+	// 构造请求数据
+	messages := []map[string]interface{}{}
+	messages = append(messages, map[string]interface{}{
+		"role":    "user",
+		"content": content,
+	})
+	//glm-4-air	glm-4-0520  glm-4-flash
+	requestData := map[string]interface{}{
+		"model":    "deepseek-chat",
+		"messages": messages,
+	}
+	jsonData, _ := json.Marshal(requestData)
+	// 创建HTTP请求
+	req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
+	if err != nil {
+		log.Debug("Error: %s", err)
+		return map[string]interface{}{}
+	}
+	// 设置请求头
+	req.Header.Add("Content-Type", "application/json")
+	req.Header.Add("Accept", "application/json")
+	req.Header.Add("Authorization", "Bearer sk-832c259e371743a0bb7b280cb86ad806")
+
+	client := &http.Client{}
+	client.Timeout = 120 * time.Second
+	resp, err := client.Do(req)
+	if err != nil {
+		return map[string]interface{}{}
+	}
+	defer resp.Body.Close()
+
+	// 解析响应
+	body, _ := ioutil.ReadAll(resp.Body)
+	res := make(map[string]interface{})
+	json.Unmarshal(body, &res)
+	if res != nil {
+		if choices := ul.IsMarkInterfaceMap(res["choices"]); len(choices) > 0 {
+			if message := qu.ObjToMap(choices[0]["message"]); message != nil {
+				result := qu.ObjToString((*message)["content"])
+				result = ul.Escape.ReplaceAllString(result, "")
+				if new_result := ul.SaveResultReg.FindString(result); new_result != "" {
+					result = new_result
+				}
+				dict := make(map[string]interface{})
+				json.Unmarshal([]byte(result), &dict)
+				return dict
+			}
+		}
+	}
+	return map[string]interface{}{}
+}
+
+// 分包字段
+func PostPackageDeepSeekAI(content string) map[string]interface{} {
+	// API的URL
+	apiURL := "https://api.deepseek.com/chat/completions"
+	// 构造请求数据
+	messages := []map[string]interface{}{}
+	messages = append(messages, map[string]interface{}{
+		"role":    "system",
+		"content": "你是一名’招标工程师’,拥有写标书及阅读理解公告的能力,根据要求抽取所需的内容,抽取内容要实事求是,不会无中生有。",
+	})
+	messages = append(messages, map[string]interface{}{
+		"role":    "user",
+		"content": content,
+	})
+	//glm-4-air	glm-4-0520  glm-4-flash
+	requestData := map[string]interface{}{
+		"model":    "deepseek-chat",
+		"messages": messages,
+	}
+	jsonData, _ := json.Marshal(requestData)
+	// 创建HTTP请求
+	req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
+	if err != nil {
+		log.Debug("Error: %s", err)
+		return map[string]interface{}{}
+	}
+	// 设置请求头
+	req.Header.Add("Content-Type", "application/json")
+	req.Header.Add("Accept", "application/json")
+	req.Header.Add("Authorization", "Bearer sk-832c259e371743a0bb7b280cb86ad806")
+
+	client := &http.Client{}
+	client.Timeout = 180 * time.Second
+	resp, err := client.Do(req)
+	if err != nil {
+		return map[string]interface{}{}
+	}
+	defer resp.Body.Close()
+
+	// 解析响应
+	body, _ := ioutil.ReadAll(resp.Body)
+	res := make(map[string]interface{})
+	json.Unmarshal(body, &res)
+	if res != nil {
+		if choices := ul.IsMarkInterfaceMap(res["choices"]); len(choices) > 0 {
+			if message := qu.ObjToMap(choices[0]["message"]); message != nil {
+				result := qu.ObjToString((*message)["content"])
+				//最终正确的结果
+				arr := strings.Split(result, "最终正确的结果")
+				if len(arr) > 1 {
+					result = arr[1]
+				}
+				result = ul.Escape.ReplaceAllString(result, "")
+				if new_result := ul.SaveResultReg.FindString(result); new_result != "" {
+					result = new_result
+				}
+				dict := make(map[string]interface{})
+				json.Unmarshal([]byte(result), &dict)
+				return dict
+			}
+		}
+	}
+	return map[string]interface{}{}
+}
+
+/*****************************
+******************************
+******************************
+******************************
+******************************
+******************************/
+// 请求数据外围字段···重试1次···
+func PostDeepSeekInfo(content string) map[string]interface{} {
+	zp, ok := map[string]interface{}{}, 0
+	for {
+		ok++
+		if zp = PostDeepSeekAI(content); len(zp) > 0 {
+			break
+		}
+		if ok >= req_retry {
+			break
+		}
+	}
+	return zp
+}
+
+// 请求多包字段...
+func PostDeepSeekPackageInfo(content string) map[string]interface{} {
+	zp, ok := map[string]interface{}{}, 0
+	for {
+		ok++
+		if zp = PostPackageDeepSeekAI(content); len(zp) > 0 {
+			break
+		}
+		if ok >= req_retry_deepseek {
+			break
+		}
+	}
+	return zp
+}
+
+// 请求质谱数据-分类字段
+func PostDeepSeekClassInfo(content string) (map[string]interface{}, bool) {
+	zp := map[string]interface{}{}
+	times := 0
+	ok := false
+	for {
+		times++
+		zp = PostClassDeepSeekAI(content)
+		if len(zp) > 0 {
+			ok = true
+			break
+		}
+		if times >= req_retry_deepseek {
+			break
+		}
+	}
+	return zp, ok
+}

+ 20 - 4
clean/c_all.go

@@ -37,11 +37,27 @@ func CleanFieldInfo(zhipu map[string]interface{}, fns []string, isTable bool) ma
 	if s_contractcode := CleanOtherCode(qu.ObjToString(zhipu["合同编号"])); s_contractcode != "" {
 		data["s_contractcode"] = s_contractcode
 	}
-	if s_budget := CleanMoney([]interface{}{zhipu["预算金额"], ""}); s_budget > 0.0 && s_budget < 1000000000.0 {
-		data["s_budget"] = s_budget
+	if s_budget, s_budget_unit := CleanMoney([]interface{}{zhipu["预算金额"], ""}); s_budget > 0.0 && s_budget < 1000000000.0 {
+		if !s_budget_unit {
+			if n_s_budget := ConvertMoney(s_budget, qu.ObjToString(zhipu["预算金额单位"])); n_s_budget > 0.0 && n_s_budget < 1000000000.0 {
+				data["s_budget"] = n_s_budget
+			} else {
+				data["s_budget"] = s_budget
+			}
+		} else {
+			data["s_budget"] = s_budget
+		}
 	}
-	if s_bidamount := CleanMoney([]interface{}{zhipu["中标金额"], ""}); s_bidamount > 0.0 && s_bidamount < 1000000000.0 {
-		data["s_bidamount"] = s_bidamount
+	if s_bidamount, s_bidamount_unit := CleanMoney([]interface{}{zhipu["中标金额"], ""}); s_bidamount > 0.0 && s_bidamount < 1000000000.0 {
+		if !s_bidamount_unit {
+			if n_s_bidamount := ConvertMoney(s_bidamount, qu.ObjToString(zhipu["中标金额单位"])); n_s_bidamount > 0.0 && n_s_bidamount < 1000000000.0 {
+				data["s_bidamount"] = n_s_bidamount
+			} else {
+				data["s_bidamount"] = s_bidamount
+			}
+		} else {
+			data["s_bidamount"] = s_bidamount
+		}
 	}
 	if s_agency := CleanAgency(qu.ObjToString(zhipu["代理机构"])); s_agency != "" {
 		data["s_agency"] = s_agency

+ 26 - 1
clean/c_money.go

@@ -2,6 +2,7 @@ package clean
 
 import (
 	"fmt"
+	"github.com/shopspring/decimal"
 	util "jygit.jydev.jianyu360.cn/data_processing/common_utils"
 	"math"
 	"regexp"
@@ -76,6 +77,31 @@ func init() {
 	regPercentMoney, _ = regexp.Compile(`[0-9.]+[((]?[%|%][))]?`)
 }
 
+// 转换金额
+func ConvertMoney(money float64, unit string) float64 {
+	if strings.Contains(unit, "万") && money > 0.0 {
+		//倍率
+		num1 := decimal.NewFromFloat(money)
+		num2 := decimal.NewFromFloat(10000)
+		decimalValue := num1.Mul(num2)
+		res, _ := decimalValue.Float64()
+		if res < 1000000000.0 {
+			return res
+		}
+	}
+	if strings.Contains(unit, "亿") && money > 0.0 {
+		//倍率
+		num1 := decimal.NewFromFloat(money)
+		num2 := decimal.NewFromFloat(100000000)
+		decimalValue := num1.Mul(num2)
+		res, _ := decimalValue.Float64()
+		if res < 1000000000.0 {
+			return res
+		}
+	}
+	return money
+}
+
 // 金额转换
 func CleanMoney(data []interface{}) (float64, bool) {
 	isFindUnit := false
@@ -161,7 +187,6 @@ func CleanMoney(data []interface{}) (float64, bool) {
 	if strings.Contains(fmt.Sprint(data[0]), "万") || strings.Contains(fmt.Sprint(data[0]), "亿") {
 		isFindUnit = true
 	}
-
 	ret := capitalMoney(data)[0]
 	if ret.(float64) < float64(10000) || ret.(float64) > float64(50000000000) {
 		ret2, _ := numMoney(data)

+ 3 - 3
config.json

@@ -11,7 +11,7 @@
   "s_mgo": {
     "local": true,
     "l_addr": "127.0.0.1:12005",
-    "addr": "172.17.189.140:27080,172.17.189.141:27081",
+    "addr": "172.31.31.202:27081,172.20.45.128:27080",
     "dbname" : "qfw",
     "username": "zhengkun",
     "password": "zk@123123"
@@ -19,7 +19,7 @@
   "b_mgo": {
     "local": true,
     "l_addr": "127.0.0.1:12005",
-    "addr": "172.17.189.140:27080,172.17.189.141:27081",
+    "addr": "172.31.31.202:27081,172.20.45.128:27080",
     "dbname" : "qfw",
     "username": "zhengkun",
     "password": "zk@123123"
@@ -27,7 +27,7 @@
   "qy_mgo": {
     "local": true,
     "l_addr": "127.0.0.1:12005",
-    "addr": "172.17.189.140:27080,172.17.189.141:27081",
+    "addr": "172.31.31.202:27081,172.20.45.128:27080",
     "dbname" : "mixdata",
     "username": "zhengkun",
     "password": "zk@123123"

+ 6 - 6
extract/extract.go

@@ -73,13 +73,13 @@ func ResolveInfo(v map[string]interface{}) map[string]interface{} {
 	tmpid := ul.BsonTOStringId(v["_id"])
 	title := qu.ObjToString(v["title"])
 	old_detail := getDetailText(v, tmpid) //获取正文文本
-
-	isTable := false //是否表格
+	//是否表格
+	isTable := false
 	if strings.Contains(old_detail, "<table>") {
-		isTable = true
+		isTable = false //可以屏蔽表格的识别内容
 	}
-
-	if NotInProgressInfo(title, old_detail, v) { //过滤信息
+	//过滤信息
+	if NotInProgressInfo(title, old_detail, v) {
 		return map[string]interface{}{}
 	}
 	//识别结构,短文本结构
@@ -113,7 +113,7 @@ func ResolveInfo(v map[string]interface{}) map[string]interface{} {
 		f_info["s_subtype"] = s_subtype
 
 		//调用标的物识别
-		if !ul.IsTool {
+		if !ul.IsTool && !ul.IsLocal {
 			if s_purchasinglist := getPurList(v, old_detail, f_info); len(s_purchasinglist) > 0 {
 				f_info["s_purchasinglist"] = s_purchasinglist
 			}

+ 1 - 2
extract/test.go

@@ -24,7 +24,7 @@ func TestSingleFieldInfo(name string, tmpid string) {
 	data := ResolveInfo(tmp)
 	//最终结果...
 	if data != nil {
-		log.Debug(data["s_area"], "~", data["s_city"])
+		log.Debug(data["s_budget"], "~", data["s_bidamount"])
 	}
 	log.Debug("耗时···", time.Now().Unix()-now)
 }
@@ -45,7 +45,6 @@ func TestSinglePurchasingInfo(name string, tmpid string) {
 	for k, v := range p_list {
 		log.Debug(k, "~", v)
 	}
-
 	log.Debug("耗时···", time.Now().Unix()-now)
 }
 

+ 167 - 1
main.go

@@ -4,8 +4,10 @@ import (
 	"data_ai/tool"
 	"data_ai/udp"
 	"data_ai/ul"
+	"fmt"
 	log "github.com/donnie4w/go-logger/logger"
 	"github.com/gogf/gf/v2/util/gconv"
+	qu "jygit.jydev.jianyu360.cn/data_processing/common_utils"
 	"strings"
 	"sync"
 	"unicode/utf8"
@@ -37,11 +39,175 @@ func main() {
 		tool.StartToolInfo()
 		return
 	}
-	//extract.TestSingleFieldInfo("bidding", "67763c6b3309c0998ba25811")
+	//extract.TestSingleFieldInfo("bidding", "677cf41c3309c0998bb6ddda")
 	lock := make(chan bool)
 	<-lock
 }
 
+// 对比程序
+func compare1() {
+	fields := map[string]string{
+		"toptype":     "string",
+		"subtype":     "string",
+		"area":        "string",
+		"city":        "string",
+		"projectname": "string",
+		"projectcode": "string",
+		"buyer":       "string",
+		"s_winner":    "string",
+		"budget":      "float",
+		"bidamount":   "float",
+	}
+	dataArr, _ := ul.BidMgo.Find("zktest_sample_data", map[string]interface{}{}, nil, map[string]interface{}{})
+	dataArr1, _ := ul.BidMgo.Find("zktest_sample_data_source_1", map[string]interface{}{}, nil, map[string]interface{}{})
+	dataArr2, _ := ul.BidMgo.Find("zktest_sample_data_source_2", map[string]interface{}{}, nil, map[string]interface{}{})
+	dataArr3, _ := ul.BidMgo.Find("zktest_sample_data_source_3", map[string]interface{}{}, nil, map[string]interface{}{})
+
+	biaozhu := creat(dataArr, false) //标注数据···
+	source1 := creat(dataArr1, true)
+	source2 := creat(dataArr2, true)
+	source3 := creat(dataArr3, true)
+
+	log.Debug("数据源:", len(biaozhu))
+	log.Debug("对比源:", len(source1))
+	log.Debug("对比源:", len(source2))
+	log.Debug("对比源:", len(source3))
+	dataArr = nil
+	dataArr1 = nil
+	dataArr2 = nil
+	dataArr3 = nil
+	//计数
+	tj1 := duibi(fields, biaozhu, source1)
+	tj2 := duibi(fields, biaozhu, source2)
+	tj3 := duibi(fields, biaozhu, source3)
+
+	log.Debug("...................")
+	arr := []string{"toptype", "subtype", "area", "city", "projectname", "projectcode", "buyer", "budget", "s_winner", "bidamount"}
+	for _, v := range arr {
+		t1, s1 := tj1[v]["total"], tj1[v]["same"]
+		t2, s2 := tj2[v]["total"], tj2[v]["same"]
+		t3, s3 := tj3[v]["total"], tj3[v]["same"]
+		f1 := fmt.Sprintf("模型flash~字段:%s 总计:%d 一致:%d 一致率:%.2f%s", v, t1, s1, (float64(s1)/float64(t1))*100.0, "%")
+		f2 := fmt.Sprintf("模型air~字段:%s 总计:%d 一致:%d 一致率:%.2f%s", v, t2, s2, (float64(s2)/float64(t2))*100.0, "%")
+		f3 := fmt.Sprintf("模型deepseek~字段:%s 总计:%d 一致:%d 一致率:%.2f%s", v, t3, s3, (float64(s3)/float64(t3))*100.0, "%")
+		log.Debug(f1)
+		log.Debug(f2)
+		log.Debug(f3)
+	}
+}
+
+// 构建数据
+func creat(dataArr []map[string]interface{}, is_zhipu bool) map[string]map[string]interface{} {
+	dict := map[string]map[string]interface{}{}
+	for _, biaozhu := range dataArr {
+		if is_zhipu {
+			ai_zhipu := *qu.ObjToMap(biaozhu["ai_zhipu"])
+			if len(ai_zhipu) > 0 {
+
+			} else {
+				continue
+			}
+		}
+		tmpid := ul.BsonTOStringId(biaozhu["_id"])
+		toptype := qu.ObjToString(biaozhu["toptype"])
+		subtype := qu.ObjToString(biaozhu["subtype"])
+		area := qu.ObjToString(biaozhu["area"])
+		city := qu.ObjToString(biaozhu["city"])
+		projectname := qu.ObjToString(biaozhu["projectname"])
+		projectcode := qu.ObjToString(biaozhu["projectcode"])
+		budget := qu.Float64All(biaozhu["budget"])
+		bidamount := qu.Float64All(biaozhu["bidamount"])
+		buyer := qu.ObjToString(biaozhu["buyer"])
+		s_winner := qu.ObjToString(biaozhu["s_winner"])
+
+		info := map[string]interface{}{}
+		info["toptype"] = toptype
+		info["subtype"] = subtype
+		info["area"] = area
+		info["city"] = city
+		info["projectname"] = projectname
+		info["projectcode"] = projectcode
+		info["budget"] = budget
+		info["bidamount"] = bidamount
+		info["buyer"] = buyer
+		info["s_winner"] = s_winner
+		dict[tmpid] = info
+	}
+	return dict
+}
+
+func duibi(fields map[string]string, biaozhu map[string]map[string]interface{}, source map[string]map[string]interface{}) map[string]map[string]int {
+	//计数
+	tj := map[string]map[string]int{}
+	for tmpid, tmp := range source {
+		bz := biaozhu[tmpid]
+		for filed, typeof := range fields {
+			nums := tj[filed]
+			if nums == nil {
+				nums = map[string]int{}
+			}
+			if typeof == "string" {
+				b_value := qu.ObjToString(bz[filed])
+				s_value := qu.ObjToString(tmp[filed])
+				if b_value == "" && s_value == "" {
+
+				} else {
+					nums["total"] = qu.IntAll(nums["total"]) + 1
+					if b_value == s_value {
+						nums["same"] = qu.IntAll(nums["same"]) + 1
+					}
+				}
+			} else if typeof == "float" {
+				b_value := qu.Float64All(bz[filed])
+				s_value := qu.Float64All(tmp[filed])
+				if b_value == 0.0 && s_value == 0.0 {
+
+				} else {
+					nums["total"] = qu.IntAll(nums["total"]) + 1
+					if b_value == s_value {
+						nums["same"] = qu.IntAll(nums["same"]) + 1
+					} else {
+						//if filed == "budget" {
+						//	if b_value == 0.0 {
+						//		log.Debug(tmpid)
+						//	}
+						//}
+					}
+				}
+			} else {
+
+			}
+			tj[filed] = nums
+		}
+	}
+	return tj
+}
+
+func export1() {
+	dataArr, _ := ul.BidMgo.Find("zktest_sample_data", map[string]interface{}{}, nil, map[string]interface{}{"_id": 1})
+	pool_mgo := make(chan bool, 1)
+	wg_mgo := &sync.WaitGroup{}
+	for _, v := range dataArr {
+		pool_mgo <- true
+		wg_mgo.Add(1)
+		go func(tmp map[string]interface{}) {
+			defer func() {
+				<-pool_mgo
+				wg_mgo.Done()
+			}()
+			tmpid := ul.BsonTOStringId(v["_id"])
+			data := ul.BidMgo.FindById("bidding", tmpid)
+			if len(data) == 0 || data == nil {
+				log.Debug("异常")
+			}
+			ul.BidMgo.Save("zktest_sample_data_source_3", data)
+			//ul.BidMgo.Save("zktest_sample_data_source_2", data)
+		}(v)
+	}
+	wg_mgo.Wait()
+	log.Debug("is over ...")
+}
+
 // 测试调试数据
 func test1() {
 	q, total := map[string]interface{}{

+ 8 - 2
prompt/prompt_buyer.go

@@ -2,13 +2,19 @@ package prompt
 
 import (
 	"data_ai/ai"
+	"data_ai/ul"
 )
 
 // 获取外围抽取字段
 func AcquireBuyerInfo(detail string) map[string]interface{} {
 	content := PromptBuyerText(detail)
-	zp := ai.PostZhiPuInfo(content)
-	return zp
+	res := map[string]interface{}{}
+	if ul.ModelType == "DeepSeek" {
+		res = ai.PostDeepSeekInfo(content)
+	} else {
+		res = ai.PostZhiPuInfo(content)
+	}
+	return res
 }
 
 // 提示词优选 - 提问词补偿不需要限制

+ 12 - 2
prompt/prompt_class.go

@@ -41,7 +41,13 @@ func AcquireClassInfo(detail string, title string, top string) (string, string)
 
 	}
 	top_content := PromptToptypeFieldText(detail, title)
-	top_zp, ok := ai.PostZhiPuClassInfo(top_content)
+	top_zp, ok := map[string]interface{}{}, false
+	if ul.ModelType == "DeepSeek" {
+		top_zp, ok = ai.PostDeepSeekClassInfo(top_content)
+	} else {
+		top_zp, ok = ai.PostZhiPuClassInfo(top_content)
+	}
+
 	if !ok {
 		return "", ""
 	}
@@ -70,7 +76,11 @@ func AcquireClassInfo(detail string, title string, top string) (string, string)
 	sub_zp := map[string]interface{}{}
 	if subtype == "" {
 		sub_content := PromptSubtypeFieldText(detail, title, toptype, tpInfo)
-		sub_zp, ok = ai.PostZhiPuClassInfo(sub_content)
+		if ul.ModelType == "DeepSeek" {
+			sub_zp, ok = ai.PostDeepSeekClassInfo(sub_content)
+		} else {
+			sub_zp, ok = ai.PostZhiPuClassInfo(sub_content)
+		}
 		if !ok {
 			return "", ""
 		}

+ 34 - 10
prompt/prompt_field.go

@@ -26,8 +26,8 @@ var pmt_field1 = `
 请根据我提供的正文做以下工作;
 首先,根据正文进行"项目所在地的省份"、"项目所在地的城市"、"采购单位"、"项目的中标单位"、"代理机构"、"采购单位联系人"、"采购单位联系电话"、"中标单位联系人"、"中标单位联系电话"、"代理机构联系人"、"代理机构联系电话"  进行实体抽取;
 
-你在识别"项目所在地的省份"的时候,如果找不到,请去找项目信息的省份、采购单位的省份,如果还找不到,请根据上下文思考,给出你认为的最佳匹配的省份;
-你在识别"项目所在地的城市"的时候,如果找不到,请去找项目信息的城市、采购单位所在的城市,如果匹配到三级区县信息,请推导出具体城市。如果还找不到,请根据上下文思考,给出你认为的最佳匹配的城市;
+你在识别"项目所在地的省份"的时候,如果找不到,请去找项目信息的省份、采购单位所在的省份,优先使用项目信息和采购方所在地的省份。如果还找不到,请根据上下文思考,给出你认为的最佳匹配的项目省份;
+你在识别"项目所在地的城市"的时候,如果找不到,请去找项目信息的城市、采购单位所在的城市,优先使用项目信息和采购方所在地的城市。如果匹配到三级区县信息,请推导出具体城市。如果还找不到,请根据上下文思考,给出你认为的最佳匹配的项目城市;
 你在识别"采购单位"的时候,请根据上下文思考,输出最佳匹配结果;包括但不限于采购人,采购方,甲方,委托人,负责采购的单位名称等;不要使用:代理机构与中标单位;
 你在识别"项目的中标单位"的时候,中标单位包括但不限于成交供应商(注:当入围供应商/中标人存在多个,选择第一位为中标单位)、中标人、中标方、承包方、受让单位、中选单位、服务商、第一名中标候选人、第1名中标人(忽略其他中标候选人),如果正文明确指定了中标单位,请优先选正文的中标单位。联合体投标时,请列出所有单位名称使用","分割)。如果不能准确识别出"项目的中标单位",请填写"无";注:不要采购单位,不要代理机构;
 你在识别"代理机构"的时候,输出代理采购事务的机构名称,不能使用采购单位和中标单位;
@@ -64,6 +64,8 @@ var pmt_field2 = `
 
 你在识别"项目的预算金额"的时候,一定不要识别业绩相关的内容。(合同内容如果没有明确指出甲方的预算金额,请不要识别)如果有多个预算金额存在,优先取预算金额含税总价。如果识别出的预算金额含有单位比如万元等,请务必提取完整。如果不能准确识别出"项目的预算金额,"请填写"无";
 你在识别"项目的中标金额"的时候,一定不要识别业绩相关的内容。优先使用合同的金额,合同的总价当做"项目的中标金额"。如果有多个中标金额存在,优先取中标金额的含税总价。如果原文没有明确的中标金额,可以选取第一名中标候选人的投标报价(金额单位请提取完整)。如果识别出项目的中标金额含有单位比如万元等,请务必提取完整。如果不能准确识别出"项目的中标金额",请填写"无";
+你在识别"项目的中标金额单位":对应项目的中标金额单位,如果不存在输出“无”",
+你在识别"项目的预算金额单位":"对应项目的预算金额的单位,如果不存在输出“无”",
 你在识别"开标日期"时,输出开标的具体时间,输出格式为:YYYY-MM-DD HH:MM:SS,如果格式不对,请转化为:YYYY-MM-DD HH:MM:SS;
 你在识别"投标截止时间"时,输出投标⽂件提交的最后期限,输出格式为:YYYY-MM-DD HH:MM:SS,如果格式不对,请转化为:YYYY-MM-DD HH:MM:SS;
 你在识别"开标地点"时,输出开标的具体地址;
@@ -75,6 +77,8 @@ var pmt_field2 = `
 {
 "预算金额":"项目的预算金额",
 "中标金额":"项目的中标金额",
+"中标金额单位":"项目的中标金额单位",
+"预算金额单位":"项目的预算金额单位",
 "开标日期":"开标日期",
 "投标截止时间":"投标截止时间",
 "开标地点":"开标地点",
@@ -115,29 +119,49 @@ var pmt_field3 = `
 // 判断短文本
 func AcquireJudgeShortInfo(detail string) map[string]interface{} {
 	content := PromptFieldText(detail, pmt_field_prefix)
-	zp := ai.PostZhiPuInfo(content)
-	return zp
+	res := map[string]interface{}{}
+	if ul.ModelType == "DeepSeek" {
+		res = ai.PostDeepSeekInfo(content)
+	} else {
+		res = ai.PostZhiPuInfo(content)
+	}
+	return res
 }
 
 // 获取抽取字段第一次
 func AcquireExtractFieldInfoFirst(detail string) map[string]interface{} {
 	content := PromptFieldText(detail, pmt_field1)
-	zp := ai.PostZhiPuInfo(content)
-	return zp
+	res := map[string]interface{}{}
+	if ul.ModelType == "DeepSeek" {
+		res = ai.PostDeepSeekInfo(content)
+	} else {
+		res = ai.PostZhiPuInfo(content)
+	}
+	return res
 }
 
 // 获取抽取字段第二次
 func AcquireExtractFieldInfoSecond(detail string) map[string]interface{} {
 	content := PromptFieldText(detail, pmt_field2)
-	zp := ai.PostZhiPuInfo(content)
-	return zp
+	res := map[string]interface{}{}
+	if ul.ModelType == "DeepSeek" {
+		res = ai.PostDeepSeekInfo(content)
+	} else {
+		res = ai.PostZhiPuInfo(content)
+	}
+	return res
 }
 
 // 获取抽取字段第三次
 func AcquireExtractFieldInfoThird(detail string) map[string]interface{} {
 	content := PromptFieldText(detail, pmt_field3)
-	zp := ai.PostZhiPuInfo(content)
-	return zp
+	res := map[string]interface{}{}
+	if ul.ModelType == "DeepSeek" {
+		res = ai.PostDeepSeekInfo(content)
+	} else {
+		res = ai.PostZhiPuInfo(content)
+	}
+	return res
 }
 
 // 提示语构建

+ 18 - 5
prompt/prompt_package.go

@@ -154,18 +154,31 @@ func PromptMultiplePackageText(detail string) string {
 // 新结构分包信息提取
 func AcquireNewMultiplePackageInfo(detail string, isTable bool) map[string]interface{} {
 	content := PromptMultiplePackageText(detail)
-	zp := ai.PostZhiPuPackageInfo(content)
+	res := map[string]interface{}{}
+	if ul.ModelType == "DeepSeek" {
+		res = ai.PostDeepSeekPackageInfo(content)
+	} else {
+		res = ai.PostZhiPuPackageInfo(content)
+	}
 	//转格式...
 	ai_pkg := map[string]interface{}{}
 	s_winner, s_bidamount, s_budget, com_package := "", 0.0, 0.0, []map[string]interface{}{}
 	win_arr, win_temp := []string{}, map[string]string{}
-	pkginfo := ul.IsMarkInterfaceMap(zp["分包信息"])
-	for _, v := range pkginfo { //
+	pkginfo := ul.IsMarkInterfaceMap(res["分包信息"])
+	for _, v := range pkginfo {
 		name := qu.ObjToString(v["标段名称"])
 		code := qu.ObjToString(v["标段/包号"])
 		winner := clean.CleanWinner(qu.ObjToString(v["中标单位"]))
-		bidamount := clean.CleanMoney([]interface{}{v["中标金额"], ""})
-		budget := clean.CleanMoney([]interface{}{v["预算金额"], ""})
+		bidamount, bidamount_unit := clean.CleanMoney([]interface{}{v["中标金额"], ""})
+		budget, budget_unit := clean.CleanMoney([]interface{}{v["预算金额"], ""})
+
+		if !bidamount_unit {
+			bidamount = clean.ConvertMoney(bidamount, qu.ObjToString(v["中标金额单位"]))
+		}
+		if !budget_unit {
+			budget = clean.ConvertMoney(budget, qu.ObjToString(v["预算金额单位"]))
+		}
+
 		if bidamount > 1000000000.0 {
 			bidamount = 0.0
 		}

+ 8 - 8
tool.json

@@ -1,27 +1,27 @@
 {
   "reading": 500,
-  "ext_name": "zktest_liantong_bidding",
+  "ext_name": "zxl_liantong_0115",
   "s_mgo": {
-    "local": false,
-    "l_addr": "172.31.31.202:27081,172.20.45.128:27080",
+    "local": true,
+    "l_addr": "127.0.0.1:12005",
     "addr": "172.31.31.202:27081,172.20.45.128:27080",
     "dbname" : "qfw",
     "username": "zhengkun",
     "password": "zk@123123"
   },
   "b_mgo": {
-    "local": false,
-    "l_addr": "172.31.31.202:27081,172.20.45.128:27080",
+    "local": true,
+    "l_addr": "127.0.0.1:12005",
     "addr": "172.31.31.202:27081,172.20.45.128:27080",
     "dbname" : "qfw",
     "username": "zhengkun",
     "password": "zk@123123"
   },
   "qy_mgo": {
-    "local": false,
-    "l_addr": "172.31.31.202:27081,172.20.45.128:27080",
+    "local": true,
+    "l_addr": "127.0.0.1:12005",
     "addr": "172.31.31.202:27081,172.20.45.128:27080",
-    "dbname" : "mixdata",
+    "dbname" : "qfw",
     "username": "zhengkun",
     "password": "zk@123123"
   }

+ 1 - 0
ul/attr.go

@@ -21,6 +21,7 @@ var (
 	FlashModel              string
 	SpecialTextReg          = regexp.MustCompile("(原网页|见附件|下载附件|(查看|访问)(源网|原网)|详情请下载附件!|详情请访问原网页!)")
 	Escape                  = regexp.MustCompile("(json|`|\n|\\\\)")
+	ModelType               string
 )
 
 type ExtReg struct {

+ 4 - 1
ul/init.go

@@ -30,7 +30,10 @@ func InitToolVar() {
 
 // 其它属性
 func initOther() {
-	FlashModel = "glm-4-flash"
+	//glm-4-air glm-4-flash
+	FlashModel = "glm-4-air"
+	//ModelType = "DeepSeek"
+	ModelType = "Flash"
 	MaxUdp = qu.IntAllDef(SysConfig["udp_max"], 10000)
 }