ai_scheduler/internal/tools/public/coze_company.go

266 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package public
import (
"ai_scheduler/internal/config"
"ai_scheduler/internal/entitys"
"ai_scheduler/internal/pkg/utils_ollama"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/ollama/ollama/api"
"github.com/coze-dev/coze-go"
)
type CozeCompany struct {
cozeApi coze.CozeAPI
config config.ToolConfig
llm *utils_ollama.Client
}
// NewCoze 创建 Coze 实例
func NewCozeCompany(config config.ToolConfig, llm *utils_ollama.Client) *CozeCompany {
return &CozeCompany{
cozeApi: newCozeApi(config),
config: config,
llm: llm,
}
}
// newCozeClient 创建 Coze 客户端
func newCozeApi(config config.ToolConfig) coze.CozeAPI {
authCli := coze.NewTokenAuth(config.APISecret)
cozeApi := coze.NewCozeAPI(authCli, coze.WithBaseURL(config.BaseURL), coze.WithHttpClient(&http.Client{
Timeout: time.Second * 120,
}))
return cozeApi
}
// Name 返回工具名称
func (c *CozeCompany) Name() string {
return "coze_company"
}
// Description 返回工具描述
func (c *CozeCompany) Description() string {
return "查询企业信息"
}
// Definition 返回工具定义
func (c *CozeCompany) Definition() entitys.ToolDefinition {
return entitys.ToolDefinition{
Type: "function",
Function: entitys.FunctionDef{
Name: c.Name(),
Description: c.Description(),
Parameters: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"company_name": map[string]interface{}{
"type": "string",
"description": "企业名称",
},
},
"required": []string{"company_name"},
},
},
}
}
// Execute 执行查询
func (c *CozeCompany) Execute(ctx context.Context, requireData *entitys.Recognize) error {
var req map[string]interface{}
if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil {
return fmt.Errorf("invalid express request: %w", err)
}
if req["company_name"] == "" {
return fmt.Errorf("company_name is required")
}
// 调用 Coze 工作流
rsp, err := c.callWorkflow(ctx, req)
if err != nil {
return fmt.Errorf("failed to get real weather: %w", err)
}
companyInfo := CompanyInfo{}
err = json.Unmarshal([]byte(rsp.Data), &companyInfo)
if err != nil {
return fmt.Errorf("failed to unmarshal company info: %w", err)
}
// 调用 LLM 模型
err = c.llm.ChatStream(ctx, requireData.Ch, []api.Message{
{
Role: "system",
Content: `# Role: 企业信息分析与经营诊断专家:
请基于以下12项指定数据字段无需补充未提供的信息完成目标企业的全维度分析总结要求每部分结论必须100%锚定对应数据,拒绝主观推测,突出“风险可见性”与“关键信息关联性”:
一、输入数据清单(需逐一对应分析)
行政处罚:公司是否有行政处罚(含处罚事由、处罚机关、处罚日期、处罚文号)
清算信息:公司的清算信息(含清算原因、清算组构成、清算进展状态)
变更记录:公司的变更记录(含变更事项:注册资本/股东/法定代表人/经营范围、变更时间、变更前后内容)
主要成员:公司名搜索公司的主要成员(含姓名、职位、任职时间、核心履历关键词)
企业详情:公司名称,搜索公司详细信息(含成立时间、注册资本、经营范围、行业分类、注册地址)
经营异常:公司是否有经营异常(含列入原因、列入日期、移出状态)
破产重组:公司破产重组的信息(含申请法院、受理时间、重组方案核心内容)
严重违法:是否有严重违法信息(含违法事由、认定机关、公示期限)
司法信息:司法信息(含案件类型、原被告身份、判决结果/进展)
被执行信息:公司的被执行信息(含执行法院、执行标的、未履行金额、失信状态)
企业手机号:公司名称查询企业手机号(需标注是否为公开备案号)
股东信息:公司对应的股东(含股东名称、出资额、出资比例、股东类型:自然人/企业/机构)
二、分析总结框架(严格对应数据)
1. 企业基础画像(锚定公司名称,搜索公司详细信息)
核心属性:成立时间、注册资本(实缴/认缴、行业分类如“批发和零售业”“软件和信息技术服务业”、主营业务从经营范围中提炼1-2个核心赛道如“专注于智能仓储设备研发与销售”
注册地址:是否与主要经营地一致(若公司名称,搜索公司详细信息有披露)。
2. 股权结构与股东特征(锚定公司对应的股东)
股权集中度前三大股东出资占比之和如“第一大股东持股60%,为绝对控股股东”);
股东类型分布自然人股东、企业股东、机构股东的占比如“70%为企业股东含1家行业头部企业”
关键股东亮点:若有知名企业/机构股东需明确标注如“股东含XX产业投资基金具备产业链资源协同潜力”
3. 经营稳定性与合规风险(锚定公司是否有行政处罚/公司是否有经营异常/是否有严重违法信息/公司的清算信息/公司破产重组的信息)
行政处罚风险:是否存在行政处罚?
若有列清「处罚事由如“虚假宣传”“税务逾期申报”、处罚机关、处罚日期」并判断“是否属于高频违规”如1年内≥2次同类处罚→高风险
若无:标注“无公开行政处罚记录”。
经营异常风险:是否存在经营异常?
若有:说明「列入原因(如“通过登记的住所无法联系”“未公示年度报告”)、是否已移出」,并评估对业务的影响(如“地址失联可能导致客户信任下降”);
若无:标注“无经营异常记录”。
严重违法红线:是否存在严重违法?
若有:明确「违法事由(如“拒不履行生效法律文书”“欺诈消费者”)、认定机关、公示期限」,并标注“触及监管红线,需重点核查整改情况”;
若无:标注“无严重违法记录”。
极端状态预警:是否存在清算或破产重组?
若有清算:说明「清算原因(如“股东会决议解散”“营业期限届满”)、清算进展(如“清算组已完成资产清查”)」;
若有破产重组说明「申请法院、受理时间、重组方案核心内容如“拟引入战略投资者注资5000万”
若无:标注“无清算或破产重组记录”。
4. 司法与执行风险(锚定司法信息/公司的被执行信息)
涉诉情况司法案件的核心特征如“80%为买卖合同纠纷20%为劳动争议仲裁”“作为被告的案件占比75%”“判决胜诉率约60%”);
被执行压力:是否存在被执行信息?
若有列清「执行法院、执行标的金额、未履行金额、是否纳入失信被执行人名单」并计算“未履行金额占注册资本的比例”如“未履行800万占注册资本的20%”);
若无:标注“无公开被执行记录”。
5. 管理团队与联系信息(锚定公司名搜索公司的主要成员/公司名称查询企业手机号)
核心团队稳定性主要成员的任职时间分布如“CEO任职4年CFO任职2年核心团队平均任职3年”是否有频繁变动如“1年内2位高管离职”→需提示“管理稳定性风险”
关键岗位资质核心成员如法定代表人、CEO、CFO的过往履历亮点如“CEO曾任职XX上市公司主导过亿元级项目落地”
联系信息可信度:企业手机号是否为公开备案(如“与工商登记预留电话一致→可信度高”;“为非备案号→需提示‘联系信息真实性存疑’”)。
6. 综合结论与行动建议(整合所有数据)
整体风险评级:基于数据密度,给出“低风险/中风险/高风险”定性示例“无行政处罚、无被执行、仅1条普通合同纠纷→低风险”“有失信被执行+严重违法→高风险”);
Top3核心风险按“严重违法被执行破产重组行政处罚经营异常司法纠纷”排序列出最需关注的3个问题如“1. 未履行金额占注册资本20%存在债务违约风险2. 1年内2次地址异常经营稳定性弱3. 自然人股东占比过高,决策易受个人因素影响”);
actionable 建议:针对每个核心风险,给出可执行的核查/应对动作如“核查未履行金额对应的案件进展评估企业偿债能力要求企业提供近1年的地址证明确认经营场所稳定性穿透核查自然人股东的资产状况降低决策风险”
三、输出规则(强制遵守)
数据溯源每句结论必须标注对应数据字段如“根据公司是否有行政处罚企业2023年因税务逾期申报被区税务局处罚”
量化优先拒绝模糊表述如不说“很多案件”要说“近1年涉及5起买卖合同纠纷”
风险分级:用“★”标注风险等级(★越多越严重,如“严重违法★★★”“被执行★★”“经营异常★”);
语言风格:专业简洁,避免冗余,适合风控/投资/合作前的快速决策阅读。
【示例输出片段】
3. 经营稳定性与合规风险
行政处罚根据公司是否有行政处罚企业2022年11月因“发布虚假广告”被区市场监管局处以3万元罚款文号X市监罚字2022456号无后续同类处罚→风险等级★
经营异常根据公司是否有经营异常企业2023年6月因“通过登记的住所无法联系”被列入异常名录2023年12月已移出→风险等级★
严重违法:根据是否有严重违法信息,无公开严重违法记录→风险等级无;
极端状态:根据公司的清算信息/公司破产重组的信息,无清算或破产重组记录→风险等级无。
6. 综合结论与行动建议
整体评级低风险仅1次轻微行政处罚无重大合规瑕疵
Top3核心风险1. 根据司法信息近1年作为被告的合同纠纷占比75%需警惕应收账款回收风险★★2. 根据公司名搜索公司的主要成员1年内2位销售总监离职管理稳定性弱★3. 根据公司名称查询企业手机号,企业手机号为非备案号,联系信息真实性存疑★;
建议:核查合同纠纷案件的原告身份及回款情况,评估坏账概率;要求企业提供离职人员的交接说明,确认业务连续性;索要企业备案的联系方式,验证沟通有效性。
`,
},
{
Role: "assistant",
Content: fmt.Sprintf(`请分析企业:%s
公司是否有行政处罚:%v
公司的清算信息:%v
公司的变更记录:%v
公司名搜索公司的主要成员:%v
公司名称,搜索公司详细信息:%v
公司是否有经营异常:%v
公司破产重组的信息:%v
是否有严重违法信息:%v
司法信息:%v
公司的被执行信息:%v
公司名称查询企业手机号:%v
公司对应的股东:%v`, req["company_name"], companyInfo.Xzcf, companyInfo.Clears, companyInfo.Changes, companyInfo.Employees, companyInfo.Searchdata, companyInfo.Operations, companyInfo.BankruptcyPublicList, companyInfo.Illegals, companyInfo.JudicialList, companyInfo.Executes, companyInfo.Phone, companyInfo.Partners),
},
{
Role: "user",
Content: requireData.UserContent.Text,
},
},
c.Name(), "")
if err != nil {
return fmt.Errorf("failed to get express info: %w", err)
}
//entitys.ResText(requireData.Ch, "", rsp.Data)
return nil
}
// CallWorkflow 调用 Coze 工作流
// 参数:
// - ctx: 上下文,用于控制超时和取消
// - workflowId: 工作流 ID
// - params: 工作流参数
// 返回:
// - interface{}: 工作流执行结果
// - error: 错误信息
func (c *CozeCompany) callWorkflow(ctx context.Context, params map[string]interface{}) (*coze.RunWorkflowsResp, error) {
// 准备工作流请求参数
workflowReq := &coze.RunWorkflowsReq{
WorkflowID: c.config.APIKey,
Parameters: params,
}
// 调用工作流
resp, err := c.cozeApi.Workflows.Runs.Create(ctx, workflowReq)
if err != nil {
return nil, fmt.Errorf("工作流调用失败: %w", err)
}
// 处理工作流响应
if resp == nil {
return nil, fmt.Errorf("工作流响应为空")
}
// 返回工作流执行结果
return resp, nil
}
type CompanyInfo struct {
BankruptcyPublicList interface{} `json:"bankruptcy_public_list"` // 破产公示列表
Changes interface{} `json:"changes"` // 变更记录
Clears interface{} `json:"clears"` // 清算记录
Employees interface{} `json:"employees"` // 员工列表
Executes interface{} `json:"executes"` // 执行记录
Illegals interface{} `json:"illegals"` // 违法记录
JudicialList interface{} `json:"judicial_list"` // 司法记录
Operations interface{} `json:"operations"` // 经营记录
Partners interface{} `json:"partners"` // 合伙人列表
Phone string `json:"phone"` // 联系电话
// 搜索数据
Searchdata struct {
Authority interface{} `json:"authority"`
BusinessScope interface{} `json:"business_scope"`
Capital interface{} `json:"capital"`
CompanyAddress interface{} `json:"company_address"`
CompanyName string `json:"company_name"`
CompanyStatus interface{} `json:"company_status"`
CompanyType interface{} `json:"company_type"`
CreditNo interface{} `json:"credit_no"`
EstablishDate interface{} `json:"establish_date"`
Industry interface{} `json:"industry"`
LegalPerson interface{} `json:"legal_person"`
Province interface{} `json:"province"`
} `json:"searchdata"`
Xzcf interface{} `json:"xzcf"` // 行政处罚
}